在使用GitHub Actions和kubeconform工具自动检查Kubernetes清单文件的语法
这篇文章是2023年Kubernetes Advent Calendar的第2天文章。
梗概
kubeconform是一个用于验证Kubernetes清单文件的工具。
您可以将其集成到CI中,或在本地使用它来验证Kubernetes的配置。
-
- install方法
-
- https://github.com/yannh/kubeconform#installation
-
- 以下からダウンロードも可能
- https://github.com/yannh/kubeconform/releases
运用方式
例として以下のmanifestを使用します。
$ cat nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
resources:
requests:
memory: 100M
cpu: 100m
ephemeral-storage: 100M
limits:
memory: 200M
cpu: 200m
ephemeral-storage: 100M
对于上述的manifest执行kubeconform
- 正常パターン
$ ~/kubeconform -summary -output json nginx-deployment.yaml
{
"resources": [],
"summary": {
"valid": 1,
"invalid": 0,
"errors": 0,
"skipped": 0
}
}
-
- エラーパターン
- port番号を文字列で定義すると、誤りを検出してくれます。
$ ~/kubeconform -summary -output json nginx-deployment.yaml
{
"resources": [
{
"filename": "nginx-deployment.yaml",
"kind": "Deployment",
"name": "nginx-deployment",
"version": "apps/v1",
"status": "statusInvalid",
"msg": "problem validating schema. Check JSON formatting: jsonschema: '/spec/template/spec/containers/0/ports/0/containerPort' does not validate with https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/master-standalone/deployment-apps-v1.json#/properties/spec/properties/template/properties/spec/properties/containers/items/properties/ports/items/properties/containerPort/type: expected integer, but got string",
"validationErrors": [
{
"path": "/spec/template/spec/containers/0/ports/0/containerPort",
"msg": "expected integer, but got string"
}
]
}
],
"summary": {
"valid": 0,
"invalid": 1,
"errors": 0,
"skipped": 0
}
}
如果正在使用kustomize
- フォルダ構成
.
├── base
│ ├── kustomization.yaml
│ └── nginx.yaml
└── overlay
├── dev
│ ├── kustomization.yaml
│ └── patch.yaml
:
:
- 実行コマンド
$ kustomize build overlay/dev/ | kubeconform -summary -output json
{
"resources": [],
"summary": {
"valid": 1,
"invalid": 0,
"errors": 0,
"skipped": 0
}
}
カスタムリソースを扱う場合
- schemaについて
カスタムリソースを扱う場合は、schemaファイルを用意する必要があります。
以下記載の通り、-schema-locationというオプションがあり、指定しない場合はdefaultのschemaが使用されます。defaultの場合、カスタムリソースに対応していません。
https://github.com/yannh/kubeconform/tree/master#usage
例えば、カスタムリソースであるtargetgroupbindingを例にdefaultのschemaでkubeconformを実行すると以下のようにエラーになります。
$ ~/kubeconform -summary -output json targegroup.yaml
{
"resources": [
{
"filename": "targegroup.yaml",
"kind": "TargetGroupBinding",
"name": "nginx-tg",
"version": "elbv2.k8s.aws/v1beta1",
"status": "statusError",
"msg": "could not find schema for TargetGroupBinding"
}
],
"summary": {
"valid": 0,
"invalid": 0,
"errors": 1,
"skipped": 0
}
}
- schemaファイルの作成方法
通过执行以下脚本,可以创建schema文件。
- 作成手順
首先,获取目标资源的crd信息。
$ kubectl get crd targetgroupbindings.elbv2.k8s.aws -o yaml > targetgroup_crd.yaml
为了执行openapi2jsonschema.py,克隆存储库。
$ git clone https://github.com/yannh/kubeconform.git
schemaファイルのフォーマットを定義
(ソースを見るとkind,group,fullgroup,versionが指定できそう)
$ export FILENAME_FORMAT={kind}_{version}
使用获取的crd信息,执行openapi2jsonschema.py并指定。
$ python kubeconform/scripts/openapi2jsonschema.py targetgroup_crd.yaml
JSON schema written to targetgroupbinding_v1alpha1.json
JSON schema written to targetgroupbinding_v1beta1.json
- kubeconform実行
取得したjsonファイルは適当にschemaフォルダに格納し、以下のように-schema-locationでschemaファイルを指定して実行すればカスタムリソースも扱うことができるようになります。
$ ~/kubeconform -summary -output json -schema-location "schemas/{{ .ResourceKind }}_{{ .ResourceAPIVersion }}.json" targegroup.yaml
{
"resources": [],
"summary": {
"valid": 1,
"invalid": 0,
"errors": 0,
"skipped": 0
}
}
また、-schema-locationは複数指定できるので、defaultのschemaも使用したい場合は以下のように記載することができます。
$ kubeconform -summary -output json -schema-location default -schema-location "schemas/{{ .ResourceKind }}_{{ .ResourceAPIVersion }}.json" xxx.yaml
以下のように指定することで、schemaファイルが複数あってもファイル名が指定したフォーマットに準拠していればすべて適用してくれます。
“schemas/{{ .ResourceKind }}_{{ .ResourceAPIVersion }}.json”
从GitHub Actions的工作流程中执行
以下链接中提供了一个例子,展示了workflow的使用方式。
https://github.com/yannh/kubeconform#github-workflow
然而,我个人建议使用以下选项。
原因是,run命令可执行命令,因此具有相当高的自由度。
https://github.com/yokawasa/action-setup-kube-tools
- workflow例
运行kubeconform来对以下以该结构进行管理的manifest进行验证。
.
├── schemas
│ ├── rollout_v1alpha1.json
: : :
│ └── targetgroupbinding_v1beta1.json
└── template
└── kustomize
├── base
│ ├── kustomization.yaml
│ └── nginx.yaml
└── overlay
├── dev
│ ├── kustomization.yaml
│ └── patch.yaml
├── prod
│ ├── kustomization.yaml
│ └── patch.yaml
└── stg
├── kustomization.yaml
└── patch.yaml
通过使用action-setup-kube-tools工具,您可以按照以下方式创建工作流,以便在创建PR时一次性检查多个清单。
name: Check manifest
on:
pull_request:
jobs:
kubeconform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: yokawasa/action-setup-kube-tools@v0.9.2
with:
setup-tools: |
kubeconform
kustomize
kubeconform: '0.5.0'
kustomize: '5.0.0'
- run: |
for ENV_NAME in dev stg prod
do
kustomize build template/kustomize/overlay/$ENV_NAME |
kubeconform -summary \
-schema-location default \
-schema-location "schemas/{{ .ResourceKind }}_{{ .ResourceAPIVersion }}.json" \
-output json
done
使用action-setup-kube-tools工具可以避免在执行环境中安装kustomize和kubeconform,也能消除对执行环境的依赖,这是一个优点。
通过将CI集成到其中,我们可以在PullRequest阶段确保能够准确地检测出语法等错误,这非常不错。