[kubernetes] Aqua + Tilt + Kind
概要
普段から Kubernetes 上で動作するアプリケーションを開発する際には、 Kind を利用して、ローカル環境に K8s の環境を用意しています。
Docker Desktop でも K8s の環境を用意することはできますが、 Kind を利用するとアプリケーションごとにノードを用意することができ、ローカル環境がしっちゃかめっちゃかになることが無いなどの利点があります。
一方で、これは Kind に起因する訳ではないですが、開発手順が冗長でスピーディに開発ができていませんでした。
そこで Aqua と Tilt を利用して、ローカルの K8s の開発環境を改善してみました。
これまでの手順
Kind に自身の作成したアプリケーションの変更を適用する時に、これまでは下記のような手順を踏んでいました。
-
docker build
でイメージを更新 -
kind load
でイメージを Kind にアップロード -
kustomize edit
でマニフェストのイメージタグを更新 -
kubectl apply
で最新のイメージをデプロイ
これらの手順は Makefile で管理することで make xxx
で実行可能とはなりますが、できればホットリロードみたく、ファイルの変更を保存したら勝手に反映されて欲しいものです。
KAIZEN後
冒頭にある通り、 Aqua と Tilt を利用しました。
今回は簡単に job (go/cmd/job/main.go)
と sample (go/cmd/sample/main.go)
という文字列を出力するプログラムを Go で作成して、それを継続的に Kind 上にデプロイ可能としてみました。
最終的には下記のようなディレクトリ構成となっています。
├── Tiltfile
├── aqua.yaml
├── cluster.yaml
├── go
│ ├── build
│ │ ├── job
│ │ │ └── Dockerfile
│ │ └── sample
│ │ └── Dockerfile
│ ├── cmd
│ │ ├── job
│ │ │ └── main.go
│ │ └── sample
│ │ └── main.go
│ └── go.mod
└── manifest
├── crd.yaml
├── job.yaml
├── kustomization.yaml
└── sample.yaml
aqua.yaml
Aqua は必須ではないですが、 CLI の管理が楽になるため利用しています。
実際に導入する際には下記にコマンドを利用します。aqua g
で対話形式で導入したい CLI を選択することができるため必要なものを選択するようにします。
aqua init
aqua g >> aqua.yaml
aqua i -l
今回は下記の内容となりました。
registries:
- type: standard
ref: v3.79.0 # renovate: depName=aquaproj/aqua-registry
packages:
- name: kubernetes-sigs/kind@v0.14.0
- name: kubernetes/kubectl
version: v1.22.15
- name: tilt-dev/ctlptl@v0.8.9
- name: tilt-dev/tilt@v0.30.9
cluster.yaml
Aqua でインストールした ctlptl を利用して、 Kind のクラスターの起動をするための設定ファイルです。
Kind で利用するイメージのリポジトリの作成の定義も行なっています。これにより kind load
の手間が省けます。
実行するコマンドは ctlptl apply -f cluster.yaml
となります。
apiVersion: ctlptl.dev/v1alpha1
kind: Registry
name: hello-registry
port: 5000
---
apiVersion: ctlptl.dev/v1alpha1
kind: Cluster
name: kind-hello
product: kind
kubernetesVersion: v1.22.0
registry: hello-registry
docker ps
で作成されたことが確認できます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
317f22b5d8c3 kindest/node:v1.22.9 "/usr/local/bin/entr…" 2 days ago Up 2 days 127.0.0.1:58121->6443/tcp hello-control-plane
92a56ac5e767 registry:2 "/entrypoint.sh /etc…" 2 days ago Up 2 days 127.0.0.1:5000->5000/tcp hello-registry
Tiltfile
Tiltfile を作成し、tilt up
で利用可能です。
起動後は指定されたアドレスにアクセスすることでブラウザ上で K8s の様子を見ることができます。
$ tilt up
Tilt started on http://localhost:10350/
v0.30.9, built 2022-10-08
(space) to open the browser
(s) to stream logs (--stream=true)
(t) to open legacy terminal mode (--legacy=true)
(ctrl-c) to exit
Job のデプロイ
下記の Job
リソースを Tilt を利用してデプロイしていきます。
apiVersion: batch/v1
kind: Job
metadata:
name: hello-job
spec:
completions: 1
backoffLimit: 1
template:
spec:
containers:
- name: hello-job
image: hello-job:latest
restartPolicy: Never
Tiltfile は下記のようになります。
ディレクトリ構造で紹介したとおり、Kustomize
の利用を想定しています。本来は overlays などの作成が一般的ですが、ローカルでの開発が主眼なため用意せず雰囲気を味わうためだけに、各マニフェストを読み込むだけの kustomization.yaml
を作成しました。
Tiltfileに k8s_yaml(kustomize('xxx'))
とするだけで、kustomize build
-> kubectl apply -f
をよしなに行ってくれます。
そして、docker_build
で指定したとおりに、go/cmd/job/main.go
に変更が加わったり、マニフェストに変更が加わった際には docker build
をして hello-job:xxxxx
の形式で hello-registry
にイメージをプッシュしてくれます。
またマニフェストにある hello-job:latest
のタグは自動で最新のタグに置換されます。
docker_build(
'hello-job:latest',
context='go/',
dockerfile='go/build/job/Dockerfile'
)
k8s_yaml(kustomize('./manifest'))
Custom Resource の場合
下記のような CustomResourceDefinition
を利用した sample は k8s_yaml(kustomize('./manifest'))
ではイメージの更新を行うことができませんが、k8s_kind()
を利用することでイメージの更新を自動で適用することができます。
## crd.yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: mines.myfirstcontroller.mshr.doc
spec:
group: myfirstcontroller.mshr.doc
names:
kind: Mine
plural: mines
singular: mine
shortNames:
- mine
scope: Namespaced
versions:
- name: v1alpha1
(後略)
## sample.yaml
apiVersion: "myfirstcontroller.mshr.doc/v1alpha1"
kind: Mine
metadata:
name: sample
spec:
image: hello-sample:latest
k8s_kind()
を利用して Custom Resource のイメージ更新にも適用した Tiltfile。
docker_build(
'hello-job:latest',
context='go/',
dockerfile='go/build/job/Dockerfile'
)
docker_build(
'hello-sample:latest',
context='go/',
dockerfile='go/build/sample/Dockerfile'
)
k8s_yaml(kustomize('./manifest'))
k8s_kind('Mine', image_json_path='{.spec.image}')
ホットリロードの確認
試しに go/cmd/job/main.go
で出力する文字列を Hello, Job!
から Hello, Aqua and Tilt!
に変更してみると Tilt の UI 上でイメージが更新されて、ログに出力される文字列が変更されていることが分かります。
出力が多く、一連の流れをうまいことスクショできませんが、メッセージが意図した通りに変更されていることが確認できるはずです。
34s 程度で完了したようでした。
まとめ
これまでも Makefile やシェルスクリプトを利用して、なるべくローカルでの K8s 環境を快適にしようと努めてはきましたが、それでもわざわざエディターから Terminal に移動してコマンドを実行したり、アプリケーションが増えた際のスクリプトのメンテナンスなどはやはり手間でした。
今回の Aqua
+ Tilt
+ Kind
の組み合わせを導入することで、それらの手間が省ける上開発もスピーディに行うことが可能となるため、是非とも興味がある方は導入してみてください。
Discussion