kindでローカルでKubernetesを用いてFastAPIサーバを立ち上げる
今回はDockerを利用してローカルでKubernetes環境を構築できるkindを用いて、FastAPIサーバを実装してみました。
kindとは?
公式ページによると、
kind is a tool for running local Kubernetes clusters using Docker container “nodes”.
kind was primarily designed for testing Kubernetes itself, but may be used for local development or CI.
ということで、DockerコンテナをノードとしてローカルでKubernetes環境を作ることができるツールになります。今まではGoogle Cloud上のGKEをよく利用していましたが、今回はローカルでも検証してみたく試してみました。
やってみる!
それでは環境を構築してみようと思います。実装するにあたり、基本的に構成は以下の記事と同様のものを利用します。
また、Kubernetes環境のダッシュボードには以下で紹介しだkdash
を利用します。
kindのインストール
kindのインストール方法は公式ページにインストール方法が乗っております。私はmacbookを使っていますので以下の方法でインストールしました。
brew install kind
kindクラスターの作成
まずはクラスタを作成するために設定ファイルを作成します。今回は以下のように実装しました。設定内容は以下です。
kind create cluster --name=fastapi-cluster
これを実行すると、最終的にdockerコンテナが起動します。
docker ps
# 結果
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a3267226e5eb kindest/node:v1.33.1 "/usr/local/bin/entr…" 4 minutes ago Up 4 minutes 127.0.0.1:53601->6443/tcp fastapi-cluster-control-plane
この状況でkdash
を実行すると、ノードが作成されていることが確認できます。
Dockerイメージのビルドと読み込み
PythonコードとDockerfileはそれぞれ記事の内容を利用します。
from fastapi import FastAPI
app = FastAPI()
@app.get("/hello")
def hello():
return {"message": "hello"}
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim
WORKDIR /app
COPY . /app
EXPOSE 80
RUN uv sync
CMD ["uv", "run", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
ファイルを用意したら以下のようにしてビルドを実行します。
docker build -t fastapi-kind:latest .
ビルドをした後、以下のようにすることでkind
に対して先ほど作成したDockerイメージを読み込ませることができます。なお、このコマンドではデプロイはまだされません。
kind load docker-image fastapi-kind:latest --name fastapi-cluster
デプロイ
それではkubectl
を利用してデプロイするための準備をします。まずは今回利用するDeploymentやサービスを以下のよううにまとめました。実装内容は以下になります。なお、Ingress周りはまだキャッチアップが十分ではなかったのでclaude codeにお手伝いいただきました。
- Deployment
- レプリカ数:2
- fastapi-appというラベルをアプリケーションに付与
- イメージは先ほど
kind
にロードしたfastapi-kind:latest
を指定
- ClusterIPサービスにて通信プロトコルとポートの設定
- Ingressサービス
- ホスト名を
fastapi.local
と設定 - パスやパスタイプ、ポートの設定
- ホスト名を
apiVersion: apps/v1
kind: Deployment
metadata:
name: fastapi-app
labels:
app: fastapi-app
spec:
replicas: 2
selector:
matchLabels:
app: fastapi-app
template:
metadata:
labels:
app: fastapi-app
spec:
containers:
- name: fastapi-app
image: fastapi-kind:latest
imagePullPolicy: Never
ports:
- containerPort: 8000
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "100m"
---
apiVersion: v1
kind: Service
metadata:
name: fastapi-service
spec:
selector:
app: fastapi-app
ports:
- protocol: TCP
port: 80
targetPort: 8000
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: fastapi-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: fastapi.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: fastapi-service
port:
number: 80
ファイルを用意したら次はデプロイします。
kubectl apply -f k8s-deployment.yaml
実行して少し待つと、kdash
上でfastapi-app
がPodとしてデプロイされ、fastapi-service
としてClusterIPが作成されていることが確認できます。
接続してみる
FastAPIサーバに接続するには、ポートフォワーディングを設定する必要があります。以下のコマンドを実行した状態でlocalhost:8080/docs
にアクセスするとSwagger UIにアクセスできます。
kubectl port-forward service/fastapi-service 8080:80
クラスターの削除
利用が終了したら以下のコマンドでクラスタを削除できます。
kind delete cluster --name=fastapi-cluster
実行後にDockerコンテナを見ると、コンテナが削除されていることを確認できました。
docker ps
# 結果
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
まとめ
今回はローカルでKubernetesクラスタを作成できるkind
を紹介しました。個人開発でパパッと作ってみたりローカルでとりあえずテストしてみたい時とかにぜひ使ってみてください!
Discussion