🐳

uv + FastAPI + Hypercorn なアプリを K8S にデプロイする

2025/02/26に公開

tl;dr

  • uv を使う限りでは、uv の公式イメージが既にあるので Dockerfile を作るのはすごい楽ちん
  • コンテナレジストリにイメージをアップロード出来れば、後は kubectl apply すれば良い

前文

やりたいこと

K8S の練習で、自前の Dockerfile を使ったサービスを K8S にデプロイしてみたい。
そのためしてみる。

前提

  • Ubuntu 24.04 + microk8s 環境
  • uv が入っていること

デプロイへの道

依存パッケージのインストール

uv init
uv add fastapi hypercorn pydantic

FastAPI アプリの作成

https://github.com/ARGI-BERRI/fastapi-k8s/blob/main/app/main.py

ローカルで起動確認する分には uv run hypercorn app/main:app することで http://127.0.0.1:8000 からアプリアクセスできる。

Dockerfile の作成

なんと、Astral は既に uv 用の Docker イメージを公開している(参考)。ここはありがたく公式イメージを拝借し Dockerfile を作ることにする。

FROM ghcr.io/astral-sh/uv:debian-slim

ADD . /app
WORKDIR /app

RUN uv sync --frozen

CMD ["uv",  "run", "hypercorn", "app/main:app"]

Docker イメージのアップロード

K8S からイメージをプルするために、イメージをどこからのレジストリにアップロードしなければらない。今回はコンテナレジストリとして GHCR を使う。<token> は GitHub の Personal Access Token を指定する。ちなみにトークンはここから作れるwrite:packagesread:packages があれば十分。

docker build ./ -t fastapi-k8s
docker tag fastapi-k8s:latest ghcr.io/argi-berri/fastapi-k8s/fastapi-k8s:latest

echo <token> | docker login ghcr.io -u argi-berri --password-stdin
docker push ghcr.io/argi-berri/fastapi-k8s/fastapi-k8s:latest

デプロイメントを書く

image: ghcr.io/argi-berri/fastapi-k8s/fastapi-k8s:latest の部分は適量読み替えてほしい。今回は最終的にポートフォワーディングするつもりなので、DeploymentService まで書いて終わりにする。

https://github.com/ARGI-BERRI/fastapi-k8s/blob/main/k8s/manifest.yaml

K8S にデプロイする

microk8s kubectl apply -f k8s/manifest.yaml

microk8s kubectl get all して ImagePullBackOff などが起きていないかをチェックしておく。

microk8s kubectl get all
NAME                               READY   STATUS    RESTARTS   AGE
pod/fastapi-app-58b684d75b-lvm8f   1/1     Running   0          19m
pod/fastapi-app-58b684d75b-wtn92   1/1     Running   0          19m

NAME                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/fastapi-service   NodePort    10.152.183.42   <none>        80:32075/TCP   17m
service/kubernetes        ClusterIP   10.152.183.1    <none>        443/TCP        40m

NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/fastapi-app   2/2     2            2           19m

NAME                                     DESIRED   CURRENT   READY   AGE
replicaset.apps/fastapi-app-58b684d75b   2         2         2       19m

サービスにアクセスする

今回は安直にポートフォワーディングします。

# ポートフォワーディングする
microk8s kubectl port-forward service/fastapi-service 8080:80

# curl する
curl localhost:8080

以下のようなレスポンスを受け取ったら大成功。パチパチ。

{"message":"Kaixo, mundua"}

終わりに

似たような記事ならいくらでもあるのだろうが、こういうのは自分で書くのが良いだろう。似たような記事と言えど数年前の記事はちょっと賞味期限切れで参考にならないこともある。

Discussion