LoginSignup
5
6

More than 3 years have passed since last update.

Skaffold + IKS を使った 簡単・軽量・高速のCI/CD環境

Posted at

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

次の部分のリポジトリ名を、ご自分のリポジトリ名に変更します。

k8s-webserver.yaml
    spec:
      containers:
      - name: webserver
        image: <YOUR REG ID>/skaffold-example
        ports:
        - containerPort: 8080

もう一箇所も修正します。

skaffold.YAML
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 <CLUSTER NAME>`でパブリック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 コマンドで自動生成されます。

skaffold.yaml
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/

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6