はじめに
KuberentesのLinterツールはいくつかありますが、今回はKubeLinterについてご紹介していきたいと思います。
元々はStackRoxという企業が開発していたツールですが、昨年RedHatに買収されており現在はRedHatのメンバー中心に開発が進んでいるものかと思われます。
現時点において開発の初期段階にあるため、今後大きく仕様が変更される可能性があります。
個人的に初期段階のツールに触れた経験があまりないため、この機会に触れてみることで今後のアップデートを実感できるようになれれば良いと思いました。
KubeLinterとは
Kubernetesのマニフェスト(YAMLファイル)とHelmチャートに対して、構成とセキュリティの2つ観点で検証するLinterです。
デフォルトで検証するためのチェックが既にあるので、基本的にはそれだけである程度の検証が可能です。また、組織によってポリシーが違ったりすると思いますが、必要に応じてカスタムチェックの設定を追加して使用することが可能です。
公式ドキュメント等は以下になります。
■ 概要
https://www.redhat.com/ja/topics/containers/what-is-kubelinter
■ GitHub Repository
https://github.com/stackrox/kube-linter
■ 公式ドキュメント
https://docs.kubelinter.io/#/
使い方その1
KubeLinterでは48個のチェックが組み込まれており、デフォルトではそのうちの23個が有効化されています。
以下のマニフェストに対してkube-lintコマンドを実行すればデフォルトのチェックによって検証されます。
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: test-deploy
name: test-deploy
spec:
replicas: 1
selector:
matchLabels:
app: test-deploy
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: test-deploy
spec:
containers:
- image: nginx
name: nginx
resources: {}
status: {}
$ kube-linter lint deploy.yaml
KubeLinter 0.5.0
deploy.yaml: (object: <no namespace>/test-deploy apps/v1, Kind=Deployment) The container "nginx" is using an invalid container image, "nginx". Please use images that are not blocked by the `BlockList` criteria : [".*:(latest)$" "^[^:]*$" "(.*/[^:]+)$"] (check: latest-tag, remediation: Use a container image with a specific tag other than latest.)
deploy.yaml: (object: <no namespace>/test-deploy apps/v1, Kind=Deployment) container "nginx" does not have a read-only root file system (check: no-read-only-root-fs, remediation: Set readOnlyRootFilesystem to true in the container securityContext.)
deploy.yaml: (object: <no namespace>/test-deploy apps/v1, Kind=Deployment) no label matching "company.io/release=<any>" found (check: required-label-release, remediation: )
deploy.yaml: (object: <no namespace>/test-deploy apps/v1, Kind=Deployment) container "nginx" is not set to runAsNonRoot (check: run-as-non-root, remediation: Set runAsUser to a non-zero number and runAsNonRoot to true in your pod or container securityContext. Refer to https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ for details.)
deploy.yaml: (object: <no namespace>/test-deploy apps/v1, Kind=Deployment) container "nginx" has cpu request 0 (check: unset-cpu-requirements, remediation: Set CPU requests and limits for your container based on its requirements. Refer to https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits for details.)
deploy.yaml: (object: <no namespace>/test-deploy apps/v1, Kind=Deployment) container "nginx" has cpu limit 0 (check: unset-cpu-requirements, remediation: Set CPU requests and limits for your container based on its requirements. Refer to https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits for details.)
deploy.yaml: (object: <no namespace>/test-deploy apps/v1, Kind=Deployment) container "nginx" has memory request 0 (check: unset-memory-requirements, remediation: Set memory requests and limits for your container based on its requirements. Refer to https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits for details.)
deploy.yaml: (object: <no namespace>/test-deploy apps/v1, Kind=Deployment) container "nginx" has memory limit 0 (check: unset-memory-requirements, remediation: Set memory requests and limits for your container based on its requirements. Refer to https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits for details.)
Error: found 8 lint errors
使い方その2
組み込まれている48個のチェックにおいて、どのチェックを有効化するか、どのAPIオブジェクトに対して適用するかといったことが構成ファイルを使うことで設定可能です。
以下のように構成ファイル.kube-linter.yaml
を作成すると、デフォルトチェックを全て無効化し、指定したlatest-tag
チェックのみを有効化することができます。
checks:
doNotAutoAddDefaults: true
include:
- "latest-tag"
$ kube-linter lint deploy.yaml
KubeLinter 0.5.0
deploy.yaml: (object: <no namespace>/test-deploy apps/v1, Kind=Deployment) The container "nginx" is using an invalid container image, "nginx". Please use images that are not blocked by the `BlockList` criteria : [".*:(latest)$" "^[^:]*$" "(.*/[^:]+)$"] (check: latest-tag, remediation: Use a container image with a specific tag other than latest.)
Error: found 1 lint errors
特定のAPIオブジェクトにアノテーションを付与することでチェックを無視することができます。
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: test-deploy
name: test-deploy
annotations: # 追加
kube-linter.io/ignore-all: "" # 追加
spec:
replicas: 1
selector:
matchLabels:
app: test-deploy
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: test-deploy
spec:
containers:
- image: nginx
name: nginx
resources: {}
status: {}
$ kube-linter lint deploy.yaml
KubeLinter 0.5.0
No lint errors found!
使い方その3
既存チェックの使い回しだけではなく、チェックする内容自体をカスタマイズすることが可能です。
KubeLinterではテンプレートが用意されており、このテンプレートで使用するパラメータの値を変更することでカスタムチェックを行うことができます。
checks:
doNotAutoAddDefaults: true
include:
- "custom-check-label"
customChecks:
- name: "custom-check-label"
template: "required-label"
params:
key: "app"
value: "hoge"
※ 使い方その2
でdeploy.yaml
に付与したアノテーションは削除して以下実行します。
$ kube-linter lint deploy.yaml
KubeLinter 0.5.0
deploy.yaml: (object: <no namespace>/test-deploy apps/v1, Kind=Deployment) no label matching "app=hoge" found (check: custom-check-label, remediation: )
Error: found 1 lint errors
テンプレートで必要なパラメータは公式ドキュメントか、以下コマンドで確認することができます。
$ kube-linter templates list
(省略)
Name: Required Label
Key: required-label
Description: Flag objects not carrying at least one label matching the provided patterns
Supported Objects: [Any]
Parameters:
key:
Description: Key of the required label.
Required: true
value:
Description: Value of the required label.
Required: false
(省略)
他にも適用するAPIオブジェクトのタイプを指定することや、カスタムチェックがfailしたときのメッセージを変更することなどが可能です。
今回説明した内容について、詳しくは以下ご参照ください。
https://docs.kubelinter.io/#/configuring-kubelinter
おわりに
KubeLinterを調べる前は、Ansible LintのPythonで作成するカスタムルールのように、KubeLinterでもGoでユーザ独自のチェックを作成するのかなと思っていました。しかし、現在のKubeLinterでは用意されたテンプレートのパラメータを変更してユーザー独自のチェックを作成するようで、調べてみる前の自分の想像と違う使い方をするツールでした。Goで実装するとなると結構大変そうなイメージだったので使いやすいとは思う反面、どこまで柔軟に対応できるのかが重要なポイントだと感じました。