🗂

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をよく利用していましたが、今回はローカルでも検証してみたく試してみました。

https://kind.sigs.k8s.io/

やってみる!

それでは環境を構築してみようと思います。実装するにあたり、基本的に構成は以下の記事と同様のものを利用します。

https://zenn.dev/akasan/articles/6618da4fe05367

また、Kubernetes環境のダッシュボードには以下で紹介しだkdashを利用します。

https://zenn.dev/akasan/articles/b520532e647f6d

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はそれぞれ記事の内容を利用します。

main.py
from fastapi import FastAPI

app = FastAPI()


@app.get("/hello")
def hello():
    return {"message": "hello"}
Dockerfile
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と設定
    • パスやパスタイプ、ポートの設定
k8s-deployment.yaml
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