到目前为止,我使用 docker 和 docker-compose 在本地开发 Python 应用程序。现在,我想更改我的开发工作流程,skaffold
以docker
用作构建器、kubectl
用作部署器以及minikube
用于管理本地 kubernetes 集群。
假设我有这个用于 FastAPI 的基于 docker 的 hello world:
项目结构:
app/app.py
Dockerfile
应用程序/应用程序.py
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
Dockerfile:
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
COPY ./app /app
如果我运行docker build -t hello-fastapi .
并且docker run -p 80:80 hello-fastapi
我可以通过0.0.0.0
或访问该服务localhost
。我跳过docker-compose
这里的东西,因为脚手架设置无关紧要。
要使用skaffold
我有完全相同的项目结构和内容,但我添加了 skaffold + kubectl 特定的东西(skaffold.yaml
,deployment.yaml
):
项目结构:
app/app.py
k8s/deployment.yaml
Dockerfile
skaffold.yaml
k8s/deployment.yaml
apiVersion: v1
kind: Service
metadata:
name: fastapi-service
labels:
app: fastapi-service
spec:
clusterIP: None
ports:
- port: 80
name: fastapi-service
selector:
app: fastapi-service
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: fastapi-service
labels:
app: fastapi-service
spec:
replicas: 1
selector:
matchLabels:
app: fastapi-service
template:
metadata:
labels:
app: fastapi-service
spec:
containers:
- name: fastapi-service
image: fastapi-service
ports:
- containerPort: 80
脚手架.yaml
apiVersion: skaffold/v2beta10
kind: Config
build:
artifacts:
- image: fastapi-image
deploy:
kubectl:
manifests:
- k8s/*
如果我运行skaffold dev
一切似乎都很好:
Listing files to watch...
- fastapi-service
Generating tags...
- fastapi-service -> fastapi-service:latest
Some taggers failed. Rerun with -vdebug for errors.
Checking cache...
- fastapi-service: Found Locally
Tags used in deployment:
- fastapi-service -> fastapi-service:17659a877904d862184d7cc5966596d46b0765f1995f7abc958db4b3f98b8a35
Starting deploy...
- service/fastapi-service created
- deployment.apps/fastapi-service created
Waiting for deployments to stabilize...
- deployment/fastapi-service is ready.
Deployments stabilized in 2.165700782s
Press Ctrl+C to exit
Watching for changes...
[fastapi-service] Checking for script in /app/prestart.sh
[fastapi-service] Running script /app/prestart.sh
[fastapi-service] Running inside /app/prestart.sh, you could add migrations to this file, e.g.:
[fastapi-service]
[fastapi-service] #! /usr/bin/env bash
[fastapi-service]
[fastapi-service] # Let the DB start
[fastapi-service] sleep 10;
[fastapi-service] # Run migrations
[fastapi-service] alembic upgrade head
[fastapi-service]
[fastapi-service] [2020-12-15 19:02:57 +0000] [1] [INFO] Starting gunicorn 20.0.4
[fastapi-service] [2020-12-15 19:02:57 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
[fastapi-service] [2020-12-15 19:02:57 +0000] [1] [INFO] Using worker: uvicorn.workers.UvicornWorker
[fastapi-service] [2020-12-15 19:02:57 +0000] [8] [INFO] Booting worker with pid: 8
...
但是我无法通过我的网络浏览器访问该服务。如何通过网络浏览器从本地机器访问服务?
编辑:
根据minikube service list
服务fastapi-service
存在:
|----------------------|---------------------------|--------------|-----|
| NAMESPACE | NAME | TARGET PORT | URL |
|----------------------|---------------------------|--------------|-----|
| default | fastapi-service | No node port |
| default | kubernetes | No node port |
| kube-system | kube-dns | No node port |
| kubernetes-dashboard | dashboard-metrics-scraper | No node port |
| kubernetes-dashboard | kubernetes-dashboard | No node port |
|----------------------|---------------------------|--------------|-----|
但我无法通过以下方式访问它curl $(minikube service fastapi-service --url)
:
curl: (3) Failed to convert to ACE; string contains a disallowed character
curl: (6) Could not resolve host: service
curl: (6) Could not resolve host: default
curl: (6) Could not resolve host: has
curl: (6) Could not resolve host: no
curl: (6) Could not resolve host: node
curl: (6) Could not resolve host: port
可能这与Unable to get ClusterIP service url from minikube 有关。如果我deployment.yaml
改为
apiVersion: v1
kind: Service
metadata:
name: fastapi-service
labels:
app: fastapi-service
spec:
type: NodePort
ports:
- targetPort: 80
port: 80
selector:
app: fastapi-service
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: fastapi-service
labels:
app: fastapi-service
spec:
replicas: 1
selector:
matchLabels:
app: fastapi-service
template:
metadata:
labels:
app: fastapi-service
spec:
containers:
- name: fastapi-service
image: fastapi-service
ports:
- containerPort: 80
访问服务curl $(minikube service fastapi-service --url)
成功:
{"message":"Hello world! From FastAPI running on Uvicorn with Gunicorn. Using Python 3.7"}
但是我无法通过网络浏览器访问该服务。