背景
とある先日。
kubernetesマニフェストを用意してCIも通ったしマージ!あとはデプロイを待つだけ!と思って待っている時にデプロイパイプラインの中でマニフェストに不備があるよ的なエラーを吐いて止まっている...
マニフェストのバリデーションチェックをしていなかったので、デプロイするときになって初めてapplyできないマニフェストであることに気づくことがしばしば。時間返して...と悲しい気持ちになるので、PullRequestを作ったときに自動でそこまでチェックできるようにしたい。
やりたいこと
- kustomizeを使っているので、kustomize buildの結果に対してバリデーションチェックをしたい
- 最近はGithubActionsを使うことが多いので、GitHubActionで実装したい
バリデーションチェックツールは何を使うか
kubevalは聞いたことがあったのですが、21/3以降あまり動きが見受けられず。
調べているとkubeconformというのがあり、こちらはスキーマも最新の1.23まで対応していそうだったのでkubeconformを使ってみることにしました。
まずは手元で実験する
homebrewでインストール可能です。詳細はREADMEを参照ください。
実験に使うサンプルのマニフェストは以下のように準備しています。
$ tree
.
├── README.md
└── kubernetes
├── base
│ ├── busybox-deployment.yml
│ ├── kustomization.yml
│ └── nginx-deployment.yml
└── overlays
└── test
├── busybox-deployment.yml
├── kustomization.yml
└── nginx-deployment.yml
Q.エラーになった時対象はわかるのか
kustomize buildを実行すると結果は以下のように1つのファイルで出力されます。
$ kustomize build kubernetes/overlays/test/
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: busybox
name: busybox-deployment
spec:
replicas: 3
selector:
matchLabels:
app: busybox
template:
metadata:
labels:
app: busybox
spec:
containers:
- env:
- name: COLLOR
value: YELLOW
image: busybox:latest
name: busybox
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- env:
- name: COLLOR
value: GREEN
image: nginx:latest
name: nginx
ports:
- containerPort: 80
そのため、不備があるのはどのマニフェストなのか?が判別できる情報がないと実行しても修正箇所を見つけるのが大変...となってしまいそうです。
意図的にspec.template.spec.containersのnameをいじってkubeconformを実行すると、kind: Deployment
とDeploymentのname情報が出力されていました。
$ kustomize build kubernetes/overlays/test/ | kubeconform -summary
stdin - Deployment nginx-deployment is invalid: For field spec.template.spec.containers.0: name is required
Summary: 2 resources found parsing stdin - Valid: 1, Invalid: 1, Errors: 0, Skipped: 0
Q.スペルミスでスキーマに存在しない記述があった場合に検知されるのか
spec.template.spec.containersで指定するimageをmageに変えてバリデーションを実行してみます。なお、この状態で生成されるマニフェストはkubectl applyしようとすると失敗する内容です。
$ kustomize build kubernetes/overlays/test/ | kubectl apply -f meerged-manifest.yml
deployment.apps/busybox-deployment unchanged
error: error validating "meerged-manifest.yml": error validating data: ValidationError(Deployment.spec.template.spec.containers[0]): unknown field "mage" in io.k8s.api.core.v1.Container; if you choose to ignore these errors, turn validation off with --validate=false
そのまま実行すると全てValidになっていました。
$ kustomize build kubernetes/overlays/test/ | kubeconform -summary
Summary: 2 resources found parsing stdin - Valid: 2, Invalid: 0, Errors: 0, Skipped: 0
よくよくkubeconform -hでhelpを見ると、-strict
というオプションが。
-strict
disallow additional properties not in schema
-strict
オプションを付けて実行してみると無事Invalidになっていました。
$ kustomize build kubernetes/overlays/test/ | kubeconform -summary -strict
stdin - Deployment nginx-deployment is invalid: For field spec.template.spec.containers.0: Additional property mage is not allowed
Summary: 2 resources found parsing stdin - Valid: 1, Invalid: 1, Errors: 0, Skipped: 0
Github Actionsにする
kustomize buildした結果に対してバリデーションを実行したいので、まずはkustomizeのアクションで結果の出力を指定します。
kustomizeのアクションはこちらを利用しています。
https://github.com/karancode/kustomize-github-action
name: validate-kubernetes-manifest
on:
pull_request:
types: [opened, synchronize]
push:
branches:
- "main"
jobs:
cluster:
name: Validate Kubernetes Manifest
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: 'Kustomize Build'
uses: karancode/kustomize-github-action@master
with:
kustomize_build_dir: 'kubernetes/overlays/test'
kustomize_comment: true
kustomize_output_file: "merged-manifest.yml" #ここを指定
kustomize_build_options: ""
enable_alpha_plugins: false
env:
GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_ACCESS_TOKEN }}
ここに続けてkubeconformのステップを追加していきます。
- name: login to Github Packages
run: echo "${{ github.token }}" | docker login https://ghcr.io -u ${GITHUB_ACTOR} --password-stdin
- uses: docker://ghcr.io/yannh/kubeconform:master
with:
entrypoint: '/kubeconform'
args: "-summary -strict merged-manifest.yml"
実行されたアクションの結果を見ると、以下のようにちゃんと結果が出力されていました。
Summary: 2 resources found in 1 file - Valid: 2, Invalid: 0, Errors: 0, Skipped: 0
終わりに
まだ手探り状態なので、使いながら少しずつベストな形に改良していきたいと思います!
おまけ
kubeconformとは別にdatreeというツールも気になっていたのですが、こちらはkindやnameといった情報が表示されず、エラー箇所がわかりませんでした。
$ datree test meerged-manifest.yml
>> File: /Users/akane.saigo/go/src/github.com/akanenone/practice-kubernetes/meerged-manifest.yml
[V] YAML validation
[X] Kubernetes schema validation
❌ k8s schema validation error: For field spec.template.spec.containers.0: Additional property mage is not allowed
[?] Policy check didn't run for this file
(Summary)
- Passing YAML validation: 1/1
- Passing Kubernetes (1.18.0) schema validation: 0/1
- Passing policy check: 0/1
+-------------------------------------+----------------------------------------------------------+
| Enabled rules in policy “Default” | 8 |
| Configs tested against policy | 0 |
| Total rules evaluated | 0 |
| Total rules failed | 0 |
| Total rules passed | 0 |
| See all rules in policy | https://datreeのURLリンク |
とはいえ、cpuやメモリがちゃんと設定されているかをチェックしたりとできることは多く有用そうではあるので、また時間がある時に再度試してみたいと思います。