これまでは、docker と docker-compose を使用してローカルで Python アプリケーションを開発していました。ここで、開発ワークフローを変更して、ビルダーとして、デプロイヤーとして、およびローカル kubernetes クラスターを管理するために使用skaffold
したいと考えています。docker
kubectl
minikube
FastAPI 用のこの docker ベースの hello world があるとします。
プロジェクト構造:
app/app.py
Dockerfile
アプリ/app.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
...
ただし、Web ブラウザからサービスにアクセスできません。Web ブラウザなどを介してローカル マシンからサービスにアクセスするにはどうすればよいですか?
編集:
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"}
ただし、Web ブラウザー経由でサービスにアクセスできません。