前提とゴール
- Kubernetesでのデプロイはなんとなくわかる
DeploymentとServiceのyaml用意して、kubectl applyすればいいんでしょ?
くらいで大丈夫です - Github-Flowをしたい
masterがマージされたら、production(staging)に即デプロイしたい - yaml内にあるdocker imageのtagをスマートに書き換えたい
置換用の文字を埋め込んでsedしたくない - (ついでに) production, staging, development, localのyamlの差異をスマートに管理したい
localだけ完全に別yaml、とか辞めたい
kustomizeを使う理由です
(Kubernetes) kustomizeについて
概要
(細かくは触れないのでググっていただくとして)
Kubernetesのyamlをいい感じにマージできます
超簡単に、基本的な設定と、共通の設定、環境ごとの設定を、コマンドでマージしてapplyできます
ほかの選択肢としてHelmがありますが、
kustomizeのほうが、Helmよりも気軽に使える、という認識です
(2019/07) 2つあるので、超注意すること
- 元々開発されていた、単体のコマンドとして
kustomize ...
で動くkustomize
いろいろできる - kubectlコマンドに統合された
kubectl kustomize ...
のkustomize
kustomize build ...
相当のことしかできないので、 今回は使わない
設定に関しては同じ項目が設定できる、はず(細かくは見切れていない)
https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/#kustomize-feature-list
https://github.com/kubernetes-sigs/kustomize/blob/master/docs/fields.md
統合については、きちんと状態を追えていないので、よしなにご判断ください
ディレクトリ構成
botを作った時の構成なので、serviceは含んでいません
適宜読み替えてお願いします
/ops/k8s
├── manifest
│ └── .gitignore
├── base
│ ├── deployment.yaml
│ └── kustomization.yaml
└── overlays
├── local
│ ├── build.sh
│ └── kustomization.yaml
└── production
├── build.sh
├── deployment.yaml
└── kustomization.yaml
ディレクトリ構成はこちらを参考に
https://github.com/kubernetes-sigs/kustomize/blob/master/README.md
baseとoverlaysでわけ、overlays内に環境(production, staging, ...)を置くようです
manifestは、マージ後のyaml確認用フォルダとして置いているので、なくても大丈夫です
/ops/k8s/manifest
フォルダは管理対象にするが、フォルダ内のファイル管理は不要
*
!.gitignore
/ops/k8s/base
一見いろいろ足りてないですが、これで大丈夫です
最終的には、ほかの設定とマージしていい感じにします
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-name
spec:
replicas: 1
template:
spec:
containers:
- name: container-name
image: app-image:latest
commonLabels:
app: app-label
resources:
- deployment.yaml
/ops/k8s/overlays/production
yamlでは、docker imageもtagも 指定しません
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-name
spec:
template:
spec:
imagePullSecrets:
- name: secret-name
containers:
- name: container-name
imagePullPolicy: Always
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patchesStrategicMerge:
- deployment.yaml
images:
- name: app-image
/ops/k8s/overlays/production/build.shを実行すると、
新しいdocker imageとtagで、/ops/k8s/overlays/production/kustomization.yamlが更新されます
これを用いて、CircleCIにてdocker imageとtagをスマートに差し替えます
#!/bin/sh
cd `dirname $0`
IMAGE_NAME="$1"
kustomize edit set image app-image="${IMAGE_NAME}"
kustomize build . > ../../manifest/prd-k8s.yaml
/ops/k8s/overlays/local
詳細は割愛しますが、productionと似たような感じです
/.circleci/config.yml
抜粋して書いていきます
全てのブランチでビルドまでしますが、デプロイはmasterのみです
リリースタグを切った時だけ、特定の環境にデプロイ、などもここでトリガーを書きます
workflows:
version: 2
build_and_deploy:
jobs:
- build:
filters:
branches:
only: /.*/
- deploy:
requires:
- build
filters:
branches:
only: master
ビルドジョブの中で、gitのハッシュ値(CIRCLE_SHA1)でdocker tagを切り、
kubectl apply ...
で新しいmasterを参照しなおすようにします
version: 2
jobs:
(省略)
deploy:
(省略)
steps:
(省略)
- run:
name: docker build
command: docker build -t ${APP_NAME}:${CIRCLE_SHA1} ops/app
- run:
name: docker registry push
command: docker push ${APP_NAME}:${CIRCLE_SHA1}
- run:
name: k8s releasse
command: |
./ops/k8s/overlays/production/build.sh "${APP_NAME}:${CIRCLE_SHA1}"
kubectl apply -f ./ops/k8s/manifest/prd-k8s.yaml
残課題
docker registryに参照されないimageが大量に増える
あとで調べてやります
local、めんどくさい
kustomizeでは、どういう構成にするのがいいのか、については触れてませんが、
どうするのがいいのかというのは、いろいろ考えられます
- localのvolumeを、k8sでmountしてアプリを参照する
- docker imageはproductionに(近い)registryに置く
- docker imageはlocalでdocker buildしたimageを使う
それに、アプリのビルドをして、docker imageのビルドをして、k8sにapplyして、、、
という一連の作業もめんどくさいです
これについてはskaffoldで改善させる予定です
https://qiita.com/yakisuzu/items/caf5557ba059bb88f0fe