ローカル開発環境準備 - 自動化ツール(Skaffold)

| 5 min read
Author: noboru-kudo noboru-kudoの画像

前回は、minikubeを使ってローカル環境内でコンテナアプリケーションを実行する環境を整えました。

しかし、サンプルアプリのデプロイを通して、ソースコードに加えて、コンテナイメージのビルドやKubernetesマニフェストの反映等、手順が煩雑だと感じられた方も多かったのではないでしょうか?
コンテナ以前のアプリ開発だと、任意のIDEを利用してソースコードを記述し、IDEまたはコマンドからそのままローカル環境で実行・確認していた方が多いと思います。
Kubernetesに載せるためには、追加手順としてコンテナのビルドやマニフェスト反映が必要となり、これを手動でやっていては間違いなく開発効率が悪くなることでしょう。

今回はこれを解決するために、Google社で開発・運用しているKubernetes向けの自動化ツールのSkaffoldを導入し、この面倒な手順を自動化してしまいましょう。
なお、Skaffold自体はローカル環境の自動化だけを目的としてしているツールという訳ではありません。
今回はローカル環境の自動化を目的として利用していますが、CI/CDパイプラインで実行できるようにビルド、テスト、デプロイといった粒度の細かいコマンドも提供されていますので、興味がある方はそちらも試してみると良いかと思います。

Contents

事前準備

#

事前にローカル環境のKubernetesを準備しておきましょう。
ここでは、minikubeまたはDocker Desktopを前提とします。

minikube

#

minikubeについては前回を参考にminikubeのインストールとIngressアドオンのセットアップをしてください。

また、未実施の場合は実行するターミナルのDocker CLIがminikubeのDockerで実行されるようにしておきましょう。

eval $(minikube docker-env)

Docker Desktop

#

Docker Desktopの場合は、以下を参考にインストールしてください。インストール後はPreferences->KubernetesでKubernetesが有効になっていることを確認してください。

また、以下を参考にNGINX Ingress ControllerをDocker DesktopのKubernetes内に別途セットアップしてください。

既にセットアップ済みの場合は、kubectlがDocker DesktopのKubernetes(docker-desktopコンテキスト)を利用するように設定を切り替えておきましょう。

kubectl config use-context docker-desktop

Skaffoldセットアップ

#

利用する環境に応じて以下公式ドキュメントに従って、ローカル環境にSkaffoldインストールしてください。

インストール後は以下でskaffoldコマンドが利用できることを確認してください。

skaffold version

今回は現時点で最新バージョンのv1.35.1を利用しました。

Skaffold定義ファイルの作成

#

まずは、Skaffoldパイプラインが実行するビルドやデプロイステージの定義を作成する必要があります。

これの確認用のアプリケーションとして、前回minikubeで動作確認したGo言語のアプリをそのまま使用します。
未作成の場合はこちらを参考に作成してください。
以下のような構成となっているはずです。

.
├── Dockerfile
├── app.yaml
├── ingress.yaml
└── main.go

以下のコマンドで定義ファイルのテンプレートを作成しましょう。

skaffold init --force

ディレクトリ直下に、以下の内容でskaffold.yamlが作成されます。

apiVersion: skaffold/v2beta26
kind: Config
metadata:
name: sample
build:
artifacts:
- image: sample-app
docker:
dockerfile: Dockerfile
deploy:
kubectl:
manifests:
- app.yaml
- ingress.yaml

Skaffoldがディレクトリ内のファイルを解析して、ビルドステージ(build)にはDocker、デプロイステージ(deploy)にはkubectlで初期状態として作成してくれます[1]

今回はここから修正する必要はありませんので、定義ファイルの作成はこれで完了となります。実運用ではアプリの構成変更に応じて、この定義を修正していくことになります。
また、Skaffoldには特定の環境に応じて振る舞いを変えるプロファイル機能についてもサポートされていますので、そのようなケースではこちらの利用を検討してください。

動作確認

#

それではSkaffoldでイメージビルド -> Kubernetesへデプロイを実施してみましょう。
前回minikubeで既にアプリをデプロイ済みの場合は、以下を実行して削除しておきましょう。

kubectl delete -f ingress.yaml
kubectl delete -f app.yaml

あとは、skaffold.yamlが配置されたディレクトリで以下のコマンドを打つだけです。

skaffold dev

前回minikubeで手動で実施していた、イメージビルドやKubernetesマニフェストの反映が、Skaffoldによって実行されていることが分かります(Ingressアドオンのセットアップは除く)。
この状態で別ターミナルからcurl http://sample-app.minikube.local[2]を実行すると期待通りの結果(Hello minikube app!!!)が返ってくることが確認できるはずです。

また、Skaffoldではこの状態でソースコードやマニフェストファイルの変更を監視し、変更を検知すると自動で反映までしてくれます。
試しにアプリが返す固定レスポンスの内容を変更したり、app.yamlでレプリカ数を増やしてみてください。
ファイルの変更が検知されると、Skaffoldのパイプラインが実行され、新しいバージョンのアプリケーションやKubernetes設定をローカルのKubernetes環境に反映してくれることが分かると思います。

skaffold devは便利なコマンドですが、変更の都度ビルドやデプロイが実行されるとローカル環境に負荷がかかりすぎるという場合もあるかと思います。
そのような場合は、ソースコード変更監視を実施しない以下のコマンドを実行します。

# コンテナログを表示する場合は--tailオプションを追加してください
skkafold run

ソースコード変更を反映する場合は、上記コマンドを再度実行すれば新しいアプリケーションがデプロイされます。

クリーンアップ

#

skaffold devで起動した場合は、Ctr+Cでプロセスを終了することでアンデプロイされます。
一方で、skaffold runで起動した場合は、手動で以下を実行する必要があります。

skkafold delete

また、Skaffoldで変更を監視していると未使用のイメージが溜まりますので、定期的にDockerの不要なリソースは削除しておくとよいでしょう。

docker image prune -a
docker system prune --force

参照資料


  1. Skaffoldにはビルドとデプロイ以外にもコンテナのテストについてもサポートしています。詳細はこちらを参照してください。 ↩︎

  2. Docker Desktopで実施する場合は、minikubeのようにIngress DNSがないため、/etc/hosts等でlocalhostsample-app.minikube. localにマッピングを追加してください。
    Macの場合はecho "localhost sample-app.minikube.local" | sudo tee -a /etc/hostsを実行すれば追加できます。 ↩︎

豆蔵デベロッパーサイト - 先週のアクセスランキング
  1. 自然言語処理初心者が「GPT2-japanese」で遊んでみた (2022-07-08)
  2. Tauri でデスクトップアプリ開発を始める (2022-07-08)
  3. Deno による Slack プラットフォーム(オープンベータ) (2022-09-27)
  4. Jest再入門 - 関数・モジュールモック編 (2022-07-03)
  5. ORマッパーのTypeORMをTypeScriptで使う (2022-07-27)
  6. 第1回 OpenAPI Generator を使ったコード生成 (2022-06-04)
  7. 直感が理性に大反抗!「モンティ・ホール問題」 (2022-07-04)
  8. Rust によるデスクトップアプリケーションフレームワーク Tauri (2022-03-06)
  9. 箱ひげ図で外れ値を確認する (2022-05-18)
  10. Nuxt3入門(第1回) - Nuxtがサポートするレンダリングモードを理解する (2022-09-25)