Kubernetes の dev 環境 では skaffold + kustomize が超便利な話。〜 CI/CD を考えてみた 〜
Kubernetes の CD (継続的デリバリー)の話です。
Kubernetes って便利だなって思う反面、いちいちコンテナのイメージをビルドしたりプッシュしたり Kubetenetes へデプロイしたりするのが非常に面倒になってきました。みんなそうですよね。Dev 環境だけでも簡単にデプロイ環境作れないかなと思って色々試してみました。
ちなみに Kubernetes の基礎知識が足りてないな、知識ちゃんと保管したいな・・・って人は以下の参考書がオススメです。 かなり詳細にそして網羅されているので、これ一冊読んでおけば大丈夫です。電子書籍版もあります。
Kubernetes完全ガイド (impress top gear)
- 作者: 青山真也
- 出版社/メーカー: インプレス
- 発売日: 2018/09/21
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
skaffold について
Google が開発している Kubernetes 向けの CD ができるツールです。特にサーバとかいらないのでお手軽に環境が作れます。
上記の図の通り、build, push, deploy の一連の流れを組むことができます。
https://github.com/GoogleContainerTools/skaffold
今回は、Dev 環境で skaffold dev を主に使っているのですが、一連の流れをコマンド一発で実現できますし、ログを垂れ流してくれるのが嬉しいですね。
kustomize について
Dev 用の yaml と Prd 用の yaml を生成するためにつかっています。 base に対して環境ごとの overlay を適用するため、以下のようなディレクトリ構造にしています。
├── base │ ├── kustomization.yaml │ ├── cert-secret.yaml │ ├── deployment-app.yaml │ ├── env-map.yaml │ └── service.yaml ├── overlays │ ├── development │ │ └── kustomization.yaml │ └── production │ ├── kustomization.yaml │ ├── service.yaml
以下のようなコマンドで development の yaml を生成しています。
kustomize build overlays/development/ > dev-k8s.yaml
環境準備
まずは skaffold をインストールします。MAC OSX だと以下の通りです。 特にサーバコンポーネントを入れる必要などはありません。
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-darwin-amd64 && chmod +x skaffold && sudo mv skaffold /usr/local/bin
次に skaffold のレポジトリをクローンします。
git clone https://github.com/GoogleContainerTools/skaffold
以下に各種設定ファイルがあります。
cd examples/getting-started
skaffold.yaml を見てみます。
Docker file を元にイメージをビルドして gcr にあげて、kubernetes に k8s-pod.yaml を元にデプロイします。
次は以下のコマンドで実行してみます。
skaffold dev
docker build / docker push / kubectl apply が実行され、 Hello world!
が表示されます。
[getting-started] Hello world!
さて、このまま main.go を書き換えてみましょう。再度一連の流れが走り、以下の通り出力が変わります。
[getting-started] Hello jerry!
skaffold の簡単な使い方とインストールは大丈夫ですね。 次に kustomize をインストールします。
brew install kustomize
kubernetes のデプロイ環境構築
skaffold も踏まえて以下のディレクトリ構造にしました。kubesec で復号化したファイルを元に kustomize でマニュフェストを生成しています。そのため、非暗号化テキストが入るため、manifest 配下を .gitignore に入れるようにしています。
├── README.md ├── base │ ├── kustomization.yaml │ ├── cert-secret.yaml │ ├── deployment-app.yaml │ ├── env-map.yaml │ └── service.yaml ├── depoly_dev.sh ├── manifest │ ├── dev-k8s.yaml │ └── prd-k8s.yaml ├── overlays │ ├── development │ │ └── kustomization.yaml │ └── production │ ├── kustomization.yaml │ ├── service.yaml └── skaffold.yaml
Dev 環境のデプロイ
流れは以下の通りです。
- アプリケーションの更新 - skaffold dev を実行 -> Dockerfile(ないしは関連するファイル) の更新 -> 動作確認- > Dockerfile(ないしは関連するファイル) の更新 -> 動作確認 - kubernetes のマニュフェスト更新 - skaffold dev を実行 -> マニュフェストの更新 -> 動作確認 -> マニュフェストの更新 -> 動作確認
ちなみに、アプリケーションと kubernetes のマニュフェストは別のレポジトリで管理しています。そのため、github submodule を使ってマニュフェスト側に取り込んでいます。
マニュフェストの生成部分を説明していなkったので説明しておきます。kustomize では、 base ないしは overlay、kustomization.yaml を更新してマニュフェストを生成します。
kustomize build overlays/development/ > dev-k8s.yaml
overlays/production/kustomization.yaml を見て見ます。namespace やファイルの頭、label に dev を一括で入れてくれます。image tag は base 側では指定せずにこちらで上書きします。
namespace: dev bases: - ../../base namePrefix: dev- commonLabels: env: dev patches: - service.yaml imageTags: - name: <private registry>/test-app newTag: "0.3"
あとは skaffold dev 叩けば OK です。
depoly_dev.sh は Kustomize や submodule 周りの処理をまとめたものです。 depoly_dev.sh を実行して必要な操作をワンコマンドで実行します。
Prd 環境のデプロイ
Prd では別のデプロイ方法を利用しています。 Devで気がすむまでテストをしているので、作業は少ないです。ある程度手作業を入れながら慎重に実施する方針で考えています。
少し話が逸れますが、 Prd 環境では Kustomize を利用してサービスも上書きしています。イメージを掴むためにサンプルを書いておきます。
- base の yaml
apiVersion: v1 kind: Service metadata: name: test-lb spec: type: LoadBalancer ports: - name: "ldap-port" protocol: "TCP" port: 80 targetPort: 80 selector: app: test-subldap
- overlay の yaml
apiVersion: v1 kind: Service metadata: name: test-lb spec: type: LoadBalancer loadBalancerIP: 10.10.10.10
本題に戻ります。image の作成には CircleCI を使っています。 tag がつくと CircleCI が docker registry に push するようにしています。
シンプルすぎてこれといってないですが、 .circleci/config.yml は以下の通りです。 本当はブランチの名前ごとに処理を分岐して CircleCI 側でもう少し処理するのが良いですね。
version: 2 jobs: build: docker: - image: circleci/golang:1.9.3 working_directory: ~/app steps: - setup_remote_docker: docker_layer_caching: true - checkout - run: name: Build command: docker build -t ${IMAGE_NAME}:latest . - run: name: Tag to latest command: docker tag ${IMAGE_NAME}:latest ${OWNER}/${IMAGE_NAME}:$CIRCLE_TAG - run: name: Docker Login command: docker login -u ${DOCKER_USER} -p ${DOCKER_PASS} <private registry> - run: name: Push image to registory command: docker push ${OWNER}/${IMAGE_NAME} workflows: version: 2 build: jobs: - build: filters: branches: ignore: /.*/ tags: only: /.*/
このような .circleci/config.yml になっているので、以下のように tag を push するとビルドが走るようになっています。Dev でテストして満足いったら tag つけるだけという感じです。
git tag 0.3 git push origin --tags
Kustomize で Prd 用のマニュフェストを生成して(これも Dev で検証しているので、共通の base ファイルは更新されている前提です)、kubernetes 側に適用します。
kubectl apply -f prd-k8s.yaml
一連の流れは bot 化しても良いかなと思いましたが、こなれてくるまで一旦手動にしています。
まとめ
kubernetes の CD はなかなかこれというのが見つからず、skaffold は割とシンプルで手元で試せるので面白かったです。一つ難点があるとすれば、手元のクレデンシャルに従って kubernetes にデプロイされるため環境間違いが怖いなというところです。spinnaker もいいかなと思いましたが、今回の環境にはオーバースペックかなと思ったので、また改めて機会をみてトライしてみようかなと思います。
シェアして頂けると嬉しいです。
参考になったという方がいれば是非お願いしますm(_ _ )m
モチベーション維持の観点で非常に励みになります。
Kubernetes完全ガイド (impress top gear)
- 作者: 青山真也
- 出版社/メーカー: インプレス
- 発売日: 2018/09/21
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
- 作者: Kelsey Hightower,Brendan Burns,Joe Beda,松浦隼人
- 出版社/メーカー: オライリージャパン
- 発売日: 2018/03/22
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
- 作者: 山田明憲
- 出版社/メーカー: 技術評論社
- 発売日: 2018/08/25
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る