LoginSignup
17

More than 3 years have passed since last update.

Kubernetes+kustomizeでmasterをスマートにさっとデプロイする

Last updated at Posted at 2019-07-11

前提とゴール

  • 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つあるので、超注意すること

  1. 元々開発されていた、単体のコマンドとして kustomize ... で動くkustomize
    いろいろできる
  2. 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

フォルダは管理対象にするが、フォルダ内のファイル管理は不要

/ops/k8s/manifest/.gitignore
*
!.gitignore

/ops/k8s/base

一見いろいろ足りてないですが、これで大丈夫です
最終的には、ほかの設定とマージしていい感じにします

/ops/k8s/base/deployment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-name
spec:
  replicas: 1
  template:
    spec:
      containers:
        - name: container-name
          image: app-image:latest
/ops/k8s/base/kustomization.yaml
commonLabels:
  app: app-label
resources:
  - deployment.yaml

/ops/k8s/overlays/production

yamlでは、docker imageもtagも 指定しません

/ops/k8s/overlays/production/deployment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-name
spec:
  template:
    spec:
      imagePullSecrets:
        - name: secret-name
      containers:
        - name: container-name
          imagePullPolicy: Always
/ops/k8s/overlays/production/kustomization.yaml
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をスマートに差し替えます

/ops/k8s/overlays/production/build.sh
#!/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

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
17