k8sを使うとローカルでの開発がめんどくさくなりました。毎回ビルドしたりdeploymentを削除したりしないといけないからです。HotReload機能的なものは標準ではついていないそうです。 そこで、Tiltを使うと差分チェックして、最小限のビルド処理を自動で実行してくれて、ログとかもブラウザでいい感じに見られるようになるらしいので、使ってみたいと思います。
TiltをScoopでインストール
> scoop bucket add tilt-dev https://github.com/tilt-dev/scoop-bucket > scoop install tilt > tilt version v0.33.22, built 2025-01-03
FastAPIのプロジェクトを作る
ためしにFastAPIで簡易的なプロジェクトを作ります。
> mkdir tilt-1 > cd tilt-1 > poetry init > poetry add fastapi uvicorn > mkdir app > touch app/main.py
main.py
from fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return {"message": "Hello, Tilt + FastAPI!"} @app.get("/ping") def ping(): return {"pong": True}
Dockerfileを作成
> touch Dockerfile
Dockerfile
# ベースイメージ FROM python:3.12-slim # Poetryをインストールするために必要なパッケージ等を追加 RUN apt-get update && apt-get install -y curl git # Poetryのインストール (最新版の公式推奨スクリプト) # バージョンは必要に応じて固定しても良い RUN curl -sSL https://install.python-poetry.org | python3 - # Poetry がインストールされたパスを通す ENV PATH="/root/.local/bin:${PATH}" # 作業ディレクトリ作成 WORKDIR /app # ホスト側の pyproject.toml / poetry.lock をコピー COPY pyproject.toml poetry.lock /app/ # Poetryで依存関係をインストール (--no-root でプロジェクト本体はインストールしない) RUN poetry install --no-root # ソースコードをコピー COPY . /app # プロジェクト本体をインストール (必要に応じて) # RUN poetry install # FastAPIを起動するコマンド CMD ["poetry", "run", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
k8sのDeployment, Serviceのyamlファイルを作成
touch deployment.yaml touch service.yaml
deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: my-tilt-app spec: replicas: 1 selector: matchLabels: app: my-tilt-app template: metadata: labels: app: my-tilt-app spec: containers: - name: my-tilt-app image: my-tilt-app-image:latest ports: - containerPort: 8000
service.yaml
apiVersion: v1 kind: Service metadata: name: my-tilt-app-service spec: selector: app: my-tilt-app ports: - port: 80 targetPort: 8000 protocol: TCP type: NodePort
Tiltflieを作る
# Tiltfile # 1. Dockerイメージのビルド設定 docker_build( 'my-tilt-app-image', # イメージ名。deployment.yaml で参照 '.', dockerfile='Dockerfile', live_update=[ sync('.', '/app'), # ホストの現在ディレクトリをコンテナの /app に同期 run('poetry install --no-root', trigger=['pyproject.toml', 'poetry.lock']) ], ) # 2. k8s マニフェストの読み込み k8s_yaml('k8s/deployment.yaml') k8s_yaml('k8s/service.yaml') # 3. ポートフォワード設定(Service を利用しない場合や補助的に使う場合) # Service: NodePort でアクセス可能なら必須ではありませんが、補助的に設定する例 k8s_resource( 'my-tilt-app', port_forwards=8000 # 例:ローカルホストの 8000 番を Pod の 8000 番にフォワード ) # 4. 推奨: Tilt が実行されたら Minikube コンテキストを自動的に使用する # 事前に `kubectl config use-context minikube` しているなら省略可。 # 参考: https://docs.tilt.dev/api.html#tilt_set_team (最新版のAPIをご確認ください)
tilt upする
> tilt up Tilt started on http://localhost:10350/ v0.33.22, built 2025-01-03 (space) to open the browser (s) to stream logs (--stream=true) (t) to open legacy terminal mode (--legacy=true) (ctrl-c) to exit Opening browser: http://localhost:10350/
tiltのコンソールを開く
上記のhttp://localhost:10350を開くと下記のような画面になりました。
http://localhost:8000でFastAPIのエンドポイントにアクセスできました! しかも、main.pyを変更すると、即座に変更が反映されました!
感想
超便利。Tiltを使わない場合、docker buildしてもminikubeで使えなくてminikube loadしないといけなかったり、色々deployment側で設定を追加していないとminikubeのリポジトリを見てくれなかったりしました。また、修正したらビルドし直しで、差分チェックとかしない場合、再ビルドにものすごく時間がかかります。あと、Windows11の場合だけかもしれませんが、NodePortで30080とか指定しても、直接アクセスできず、minikube service xxxxみたいなやつを使わないとアクセス可能なurlが取得できませんでした。これを使うとportがランダムになったりしました。ということで、何しろ結構めんどくさかったです。Tiltを使うと、Tiltfileにビルド内容を書くだけで、tilt upでビルドしてくてれて、自動的にMinikubeのイメージに入りました。port_forwards設定をすると、minikube service xxxxとかやらずに、直接localhost:8000でアクセスできました。しかも、main.py修正すると一瞬でHot Reloadされます!まあ、Tiltを使わない場合でも、もっと便利なやり方はあるとは思いますが、Tiltを使うことで超便利になってよかったです。