Skaffold は、ソースコードを変更した後に、自動的にKubernetesクラスタへデプロイしてくれる手作業を自動化するツールです。具体的には、次の作業を自動化してくれるので、コードを修正して保存するだけで、変更結果を確認できるようになります。 そのため、Jenkinsを立てるのは面倒と感じている人には、とっても良いツールと思います。
- docker build でコンテナのイメージを作る
- docker tag でタグを付与
- docker push でリポジトリに登録
- kubectl apply -f マニフェスト で Kubernetesクラスタにデプロイ
- テストして、コードを修正して、上記を繰り返し
つまり、Skaffold は、Kubernetesアプリケーションの継続的開発環境のコマンドライン・ツールです。 ローカル環境で、ソースコードを変更すると、ローカルまたはクラウド上のKubernetesクラスタへ、自動的にデプロイします。 すなわち、Skaffold は、ビルド、レジストリへのプッシュ、アプリケーションのデプロイのワークフローを実行します。 そして、CI/CDの作業工程の進行と、カスタマイズを提供します。
このツールは、Googleが開発したツールで、とてもシンプルで便利なツールです。しかも、Minikube をはじめ、どのKubenetes 環境でも動作します。そこで、IBM Cloud Kubernetes Service で動かしたメモです。
特徴
高速なローカル環境での開発
- ソースをk8sへ反映に最適化: Slaffold は、アプリケーションのソースコードの変更を検知して、ビルド、プシュ、デプロイのパイプラインを進行させる。 これには、ポリシーベースのイメージのタグ付け、高度な最適化、高速でローカルでのワークフローを伴う。
- 継続的なフィードバック: Skaffoldは、ロギング や ポートフォワーディング の自動的に管理する。
Skaffold のプロジェクトは何処でも動作
- デベロッパー間での共有: gitクローンとskaffoldは、最も簡単にプロジェクトを世界と共有する手段である。
- コンテキストに対応: Skaffold の profiles を使うと、ユーザーレベルのコンフィグ、環境変数やフラグなど、環境の差異を記述できる。
- CI/CD工程の単位: skafffold run を最初から最後まで、または、一部の工程だけを実行できる。
skaffold.yaml は、プラグインで機能追加でき、宣言的な設定である。
- skaffold init はファイルを発見して、コンフィグファイルを作成する。
- 複数要素に対応: Skaffoldは複数コンポーネントから成るアプリに対応する・。
- 自己ツールを持ち込み可能: Skaffoldは、プラグイン可能なアーキテクチャなので、ステージで異なる実装が許容される。
ライトウェイト
- クライアントサイドのみ: クラスタ側にポッドなどが不要
- 最小のパイプライン: シンプルを維持して、最適化する
事前準備
skaffoldを利用するための前提条件は、以下になります。 Kubernetesクラスタ、リポジトリにアクセスできて、Dockerをビルドできることが必要です。
- ローカル環境にDockerがインストールされていること
- IKSクラスタが作られており、kubectl get node できること
- コンテナのレジストリにアカウントがあり、docker login できていること
ここでは、サンプルコードに、Go言語を利用しています。このコンパイル環境は、マルチステージ・ビルド形式の Dockerfile を利用することで、ローカルにコンパイル環境を作らずに対応できるようにします。
適用対象のプロジェクト
これはGo言語で書いたウェブサーバーをコンテナにビルドして、レジストリに登録、Kubernetesにデプロイする簡単なコードです。
Go言語のソースコードを変更する都度、Skaffoldが監視していて、Kubernetesへデプロイしてくれます。
このコードをローカルにクローンして、skaffold を実行するだけで、CI/CDの簡易環境が実現します。
$ git clone https://github.com/takara9/skaffold-test-1
次の部分のリポジトリ名を、ご自分のリポジトリ名に変更します。
spec:
containers:
- name: webserver
image: <YOUR REG ID>/skaffold-example
ports:
- containerPort: 8080
もう一箇所も修正します。
skaffold.yaml
apiVersion: skaffold/v1beta10
kind: Config
build:
artifacts:
- image: <YOUR REG ID>/skaffold-example
deploy:
kubectl:
manifests:
- k8s-webserver.yaml
これで準備は完了です。 dockerにログインして、リポジトリに登録できるようにしておき、skaffold を実行するだけです。
これで、ソースコードからコンパイル、コンテナのビルド、レジストリへのプッシュ、Kubernetesへのデプロイを完了して、アプリケーションへアクセスできます。
$ docker login
$ skaffold dev --default-repo <your reg account id>
以下のコマンドで、ウェブサーバーをアクセスして確認します。 ワーカーノードのIPアドレスが解らないときは、`ibmcloud ks workers ``でパブリックIPアドレスを取得してください。
$ curl http://<YOUR NODE IP>:31080/
プログラムを変更して、保存するごとに、ビルドからデプロイまでが自動実行されます。
テスト
コードの修正を保存するごとに、以下のように、ビルドとレジストリへの登録、Kubernetesクラスタへのデプロイが自動実行されます。実際に動かして、main.go や index.html を修正して、自動的にデプロイされるまでを確認していただきたいと思います。
Watching for changes every 1s...
Generating tags...
- maho/maho_skaffold-example -> WARN[0271] Unable to find git commit: Running [git describe --tags --always]: stdout , stderr: fatal: not a git repository (or any of the parent directories): .git
, err: exit status 128: exit status 128
maho/maho_skaffold-example:dirty
Tags generated in 8.038839ms
Starting build...
Building [maho/maho_skaffold-example]...
Sending build context to Docker daemon 4.096kB
Step 1/8 : FROM golang:1.10.1-alpine3.7 as builder
---> 52d894fca6d4
Step 2/8 : COPY main.go .
---> f9ae2c270440
Step 3/8 : RUN go build -o /app main.go
---> Running in faf21a1ae59f
Removing intermediate container faf21a1ae59f
---> e55f9a80fea4
Step 4/8 : FROM alpine:3.7
---> 6d1ef012b567
Step 5/8 : CMD ["./app"]
---> Using cache
---> c0a8d07256ed
Step 6/8 : COPY --from=builder /app .
---> c9ea340c10fb
Step 7/8 : RUN mkdir /html
---> Running in 30b975e6d86a
Removing intermediate container 30b975e6d86a
---> fe5fe1d2fae8
Step 8/8 : COPY index.html /html/index.html
---> 9437956da99a
Successfully built 9437956da99a
Successfully tagged maho/maho_skaffold-example:dirty
The push refers to repository [docker.io/maho/maho_skaffold-example]
a74066c0f706: Preparing
963ac60d4895: Preparing
ac1354bcd7fb: Preparing
3fc64803ca2d: Preparing
3fc64803ca2d: Layer already exists
a74066c0f706: Pushed
963ac60d4895: Pushed
ac1354bcd7fb: Pushed
dirty: digest: sha256:74e583a6ed2efb205c13b680fd2e863cbab355f2ef6b6985c30fc8249cb6d34e size: 1152
Build complete in 18.951475622s
Starting test...
Test complete in 5.473µs
Starting deploy...
kubectl client version: 1.14
deployment.apps/web-deployment configured
Deploy complete in 611.256771ms
Watching for changes every 1s...
skaffold.yamlの書き方
skaffold.yamlは、自身で書くこともできますが、skaffold init
コマンドで自動生成されます。
apiVersion: skaffold/v1beta10
kind: Config
build:
artifacts:
- image: maho/skaffold-example
deploy:
kubectl:
manifests:
- k8s-webserver.yaml
プロジェクトで利用する場合、KubernetesのYAMLやDockerfileが存在するディレクトリで、次のように簡単に skaffold.yaml を生成できます。あとは、必要に応じて、Skaffoldのドキュメント[3]を参考にしながら、YAMLを修正すれば良いでしょう。
imac:project maho$ skaffold init
apiVersion: skaffold/v1beta10
kind: Config
build:
artifacts:
- image: maho/skaffold-example
deploy:
kubectl:
manifests:
- k8s-webserver.yaml
Do you want to write this configuration to skaffold.yaml? [y/n]: y
Configuration skaffold.yaml was written
You can now run [skaffold build] to build the artifacts
or [skaffold run] to build and deploy
or [skaffold dev] to enter development mode, with auto-redeploy
参考資料
[1] Skaffold 入門, https://skaffold.dev/docs/getting-started/
[2] Docker マルチステージビルドの方法, https://docs.docker.com/develop/develop-images/multistage-build/
[3] Skaffoldの利用法、https://skaffold.dev/docs/how-tos/