k8s環境でのProd,Stg,Feature,DevなどへのデプロイにSkaffoldを利用しています。
おそらくJenkinsやCIツールなどからこいつを利用してデプロイするのが今のところのベストプラクティスかと思われるので、メモっておきます。
Skaffold: docker buildやkubectl apply を自動でやってくれる便利ツール、dockerのtag管理などもやってくれるのでとってもらくちん。
https://skaffold.dev/
https://github.com/GoogleContainerTools/skaffold
インストール
コマンドなのでPATHの通ったところに配置します。インストールは簡単。公式の通りにするだけ。
murata:~ $ skaffold
A tool that facilitates continuous development for Kubernetes applications.
Find more information at: https://skaffold.dev/docs/getting-started/
End-to-end pipelines:
run Run a pipeline
dev Run a pipeline in development mode
debug [beta] Run a pipeline in debug mode
Pipeline building blocks for CI/CD:
build Build the artifacts
deploy Deploy pre-built artifacts
delete Delete the deployed application
render [alpha] Perform all image builds, and output rendered Kubernetes manifests
Getting started with a new project:
init [alpha] Generate configuration for deploying an application
fix Update old configuration to newest schema version
Other Commands:
completion Output shell completion for the given shell (bash or zsh)
config Interact with the Skaffold configuration
credits Export third party notices to given path (./skaffold-credits by default)
diagnose Run a diagnostic on Skaffold
schema List and print json schemas used to validate skaffold.yaml configuration
version Print the version information
Usage:
skaffold [flags] [options]
Use "skaffold <command> --help" for more information about a given command.
Use "skaffold options" for a list of global command-line options (applies to all commands).
ファイル作成
こんな感じでk8sのマニフェスト(yaml), Dockerfile, Skaffoldファイルの3つを、各ステージ環境ごとに用意しています。
murata:~/workspace/tmp/ttt/back $ ll
total 12
-rw-rw-r-- 1 murata murata 0 Dec 23 12:52 Dockerfile.dev
-rw-rw-r-- 1 murata murata 0 Dec 23 12:52 Dockerfile.feature
-rw-rw-r-- 1 murata murata 0 Dec 23 12:52 Dockerfile.prod
-rw-rw-r-- 1 murata murata 200 Dec 23 12:52 go.mod
-rw-rw-r-- 1 murata murata 2925 Dec 23 12:52 go.sum
-rw-rw-r-- 1 murata murata 0 Dec 23 12:54 k8s.dev.yaml
-rw-rw-r-- 1 murata murata 0 Dec 23 12:54 k8s.prod.yaml
-rw-rw-r-- 1 murata murata 0 Dec 23 12:54 k8s.feature.yaml
-rw-rw-r-- 1 murata murata 228 Dec 23 12:51 main.go
-rw-rw-r-- 1 murata murata 0 Dec 23 12:52 skaffold.dev.yaml
-rw-rw-r-- 1 murata murata 0 Dec 23 12:52 skaffold.prod.yaml
-rw-rw-r-- 1 murata murata 0 Dec 23 12:52 skaffold.feature.yaml
Dockerfileは普通に作るだけ。k8sファイルもいつも通り作るだけ。
skaffold.dev.yamlではDockerfileとk8sファイルの場所を指定してあげる。Dockerのリポジトリがサーバと同居しているのであればlocal.pushはfalseでおk。その辺のオプションは公式を参照してください。
apiVersion: skaffold/v1
kind: Config
build:
artifacts:
- image: dev/xxxxx.dev
context: ./
docker:
dockerfile: ./Dockerfile.dev
local:
push: false
useBuildkit: true
deploy:
kubectl:
manifests:
- ./k8s.dev.yaml
コマンド
skaffold run -f ./skaffold.dev.yaml
するだけでkubectl apply までやってくれちゃう優れもの。
skaffold runで1回だけビルド、--tailを付けるとログの出力がされます。(kubectl logsがそのまま出てくる)
skaffold devで実行するとファイルに変更があった場合にビルドしなおしてくれます。
murata:~/workspace/tmp/ttt/back $ skaffold run -f ./skaffold.dev.yaml --tail
Generating tags...
- dev/ttt -> WARN[0000] Unable to find git commit: Running [git describe --tags --always]
- stdout:
- stderr: fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
: exit status 128
dev/ttt:dirty
Checking cache...
- dev/ttt: Not found. Building
Building [dev/ttt]...
[+] Building 6.6s (10/10) FINISHED
=> [internal] load build definition from Dockerfile.dev
=> => transferring dockerfile: 181B
=> [internal] load .dockerignore
=> => transferring context: 2B
=> [internal] load metadata for docker.io/library/golang:1.13.4
=> CACHED [1/5] FROM docker.io/library/golang:1.13.4
=> [internal] load build context
=> => transferring context: 550B
=> [2/5] WORKDIR /app
=> [3/5] ADD . /app
=> [4/5] RUN go mod download
=> [5/5] RUN go build
=> exporting to image
=> => exporting layers
=> => writing image sha256:6a87aa5a540a1910371f352abfbd4efa0045df9d34032fa183e75397b5e7e185
=> => naming to docker.io/dev/ttt:dirty
Tags used in deployment:
- dev/ttt -> dev/ttt:6a87aa5a540a1910371f352abfbd4efa0045df9d34032fa183e75397b5e7e185
local images can't be referenced by digest. They are tagged and referenced by a unique ID instead
Starting deploy...
- deployment.apps/ttt created
- service/ttt created
手元でがりがり開発している場合には、VolumeMountしてskaffold runのほうが早いです。(DockerのBuildがされないので)
こいつは本番やステージング環境でも使えるので手プロイしている人にとってはオペミスも減るのでとってもよろしいかと思います。