Tiltをセットアップしてサンプルを動かす

# はじめに

Kubernetes上でデプロイするコンテナイメージの開発に[Tilt](https://docs.tilt.dev/)が便利と聞き、とりあえずサンプルを動かしてみました。その記録です。

公式サイトからの言葉を借りると、「Tiltは、コード変更から新しいプロセスへの全てのステップ（ファイルの監視、コンテナイメージの構築、環境の最新化）を自動化する」ツールです。

# 事前準備

[Install](https://docs.tilt.dev/install.html)を参考にして記載します。macOS, Linux, Windowsで動作可能のようですが、筆者はmacOS, Linuxでセットアップできることを確認しました。


## 必要なツール

* Docker
    * Linuxの場合はroot以外のユーザでセットアップが必要
* kubectl
    * [kubectlのインストールおよびセットアップ](https://kubernetes.io/ja/docs/tasks/tools/install-kubectl/)等を参考にインストール
* ctlptl
    * Kind、k3d、Minikube等の「ローカルKubernetesクラスター」を作ってくれるツール
    * Tiltで使うコンテナレジストリを作ってくれる機能もあり
    * おそらくはLinuxを使う場合に必須で、macOSやWindowsでは必須ではない
* tilt
    * コンテナイメージのビルド、プッシュ、K8sリソースのデプロイを全てやってくれるツール

## ctlptlのインストール

**macOS, Windowsの場合はこの手順は（おそらく）不要です。**

[ctlptl Installation Appendix](https://github.com/tilt-dev/ctlptl/blob/main/INSTALL.md)を参考にインストールします。

いくつかのインストールのバリエーションが書かれていますが、おそらくは[Command-line](https://github.com/tilt-dev/ctlptl/blob/main/INSTALL.md#command-line)に記載の``curl``コマンドでインストールする方法が一番楽です。

※ 筆者は``go install``コマンドでGoのパッケージとしてインストールしてしまいました。この場合、環境によってはGoのセットアップが必要となり手数が増えます。

## Tiltで使うコンテナレジストリの作成

**macOS, Windowsの場合はこの手順は（おそらく）不要です。**

### ケース1 : ローカルで使えるKubernetesクラスターがない場合

次のコマンドでローカルマシン内にKubernetesクラスターを作成しつつ、Tilt用のコンテナレジストリを作成します。

```
ctlptl create cluster kind --registry=ctlptl-registry
```

上記は``kind``でローカルクラスターを作る例ですが、``k3d``や``minikube``も指定可能です。


### ケース2 : 既にローカルKubernetesクラスターがある場合

ローカルKubernetesクラスターがあってそれをそのまま使いたい場合は、以下のコマンドでTilt用のコンテナレジストリのみを作成します。

```
ctlptl create registry ctlptl-registry
```


ケース1またはケース2のコマンドが成功すれば、Tilt用のコンテナレジストリが以下のように作成されます。

```
$ docker ps -f name=ctlptl-registry
CONTAINER ID   IMAGE        COMMAND                   CREATED      STATUS      PORTS                       NAMES
f80cd832b671   registry:2   "/entrypoint.sh /etc…"   4 days ago   Up 4 days   127.0.0.1:45841->5000/tcp   ctlptl-registry
```

## Tiltのインストール

[Install](https://docs.tilt.dev/install.html)にしたがってTiltをインストールします。

```
curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash
```

ちなみにmacOSの場合は``brew``でもインストールできました。

```
brew install tilt
```

# サンプルを動作させる

## tilt-example-goのデプロイ

GitHubにある[Goのサンプル](https://github.com/tilt-dev/tilt-example-go)を動かしてみます。

```
$ git clone https://github.com/tilt-dev/tilt-example-go.git
$ cd tilt-example-go/0-base
```

ディレクトリの中身を見てみましょう。

```
$ tree .
.
├── Tiltfile
├── build.bat
├── deployments
│   ├── Dockerfile
│   └── kubernetes.yaml
├── go.mod
├── go.sum
├── main.go
└── web
    ├── index.html
    └── pets.png
```

Webアプリケーション、コンテナ、K8sリソースを作成するためのソースがall-in-oneで入っているのが何となくわかります。
これらのソースを使ってどのようにK8s上にリソースをデプロイするかは、``Tiltfile``に以下のように書かれています。

```Tiltfile:Tiltfile
# -*- mode: Python -*-

docker_build('example-go-image', '.', dockerfile='deployments/Dockerfile')
k8s_yaml('deployments/kubernetes.yaml')
k8s_resource('example-go', port_forwards=8000)
```

諸々確認できたので、``tilt up``コマンドを実行してみましょう。
```
$ tilt up
Tilt started on http://localhost:10350/
v0.33.11, built 2024-02-15

(space) to open the browser
(s) to stream logs (--stream=true)
(t) to open legacy terminal mode (--legacy=true)
(ctrl-c) to exit
```

コマンドを実行後、Webブラウザ上で http://localhost:10350/ にアクセスすると、以下のようにTiltのWebUIを見ることができます。

![screenshot 118.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370519/d3dbaf52-8806-fb3f-14e3-29c09b0b4cac.png)

上のリストで1行目の``(Tiltfile)``や2行目の``example-go``等をクリックすると実行ログが出てきて、Tiltfileの内容をもとに以下を一気通貫で実行していることがわかります。

* Goアプリケーションのコンテナイメージをビルド
* ビルドしたイメージをコンテナレジストリにプッシュ（※1）
* K8sのマニフェストにしたがって、ローカルK8sにリソースがデプロイされる（※2）

※1 Linuxの場合、事前に作成したctlptl-registryのコンテナレジストリにpushされます。macOSのDocker Desktop for Macだと、既にイメージをbuildした時点でローカルK8s環境からコンテナイメージをpullできる状態になっているようです。

※2 以下のように、ローカルK8s環境にGoアプリケーションのリソースが出来ているのを確認できます。

```
$ kubectl get deploy -n default
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
example-go       1/1     1            1           11m
$ kubectl get pod -n default
NAME                              READY   STATUS    RESTARTS   AGE
example-go-649479f666-7kwr8       1/1     Running   0          11m
```

example-goのWebアプリケーションには http://localhost:8000/ でアクセスでき、以下のような画像と文字が表示されます。

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370519/0343b294-d016-1703-9e29-2c4f41c95bba.png">


## ソースを編集してみる

ここで、``web/index.html``に記載された``Hello cats!``というテキストを、``Hello CATs!``に変更してみましょう。
Tiltが変更を検知し、変更を反映するために必要な作業（コンテナビルド、プッシュ、K8sへのデプロイ）を自動で実行してくれます。TiltのWebUIで見ると、下のようにexample-goのリソースがUpdatingの状態になることを確認できます。

![screenshot 121のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370519/2e2ffff6-604a-6c64-4b4e-b999daa4c135.png)

Update完了後に再び http://localhost:8000/ にアクセスすると、確かに文字列の変更が反映されています。素晴らしい！

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370519/15da6029-23aa-8c50-314c-e41adad42837.png">

この辺の動きは、以下の動画の2:50~3:40あたりを見ていただくとより理解できると思います。

https://www.youtube.com/watch?v=rtAQ6Gm6z_s

# おわりに

これまではアプリの変更内容をコンテナやK8sで確認するのに、手動でコンテナのビルドやプッシュ等の作業を行う必要がありましたが、それを自動化してくれるのがTiltであることを理解できたかと思います。
筆者はまだサンプルでしか試せていないので、これから自分で作っているコンテナやK8s環境にも適用していこうと思います。