kubelinter
kubelinterとは
Installation
まず、cliツールを使えるようにします。
# curl -LO https://github.com/stackrox/kube-linter/releases/download/0.1.3/kube-linter-linux.tar.gz # tar -xvf kube-linter-linux.tar.gz # mv kube-linter /usr/local/bin # kube-linter version 0.1.3
実践
では、以下のmanifestを確認していきます。
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-lint-test namespace: default labels: app: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 protocol: TCP livenessProbe: httpGet: path: / port: 80 readinessProbe: httpGet: path: / port: 80
kube-linter lint
コマンドで確認ができます。
# kube-linter lint nginx.yaml nginx.yaml: (object: default/nginx-lint-test 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 your container's securityContext.) nginx.yaml: (object: default/nginx-lint-test 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. See https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ for more details.) nginx.yaml: (object: default/nginx-lint-test apps/v1, Kind=Deployment) container "nginx" has cpu request 0 (check: unset-cpu-requirements, remediation: Set your container's CPU requests and limits depending on its requirements. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits for more details.) nginx.yaml: (object: default/nginx-lint-test apps/v1, Kind=Deployment) container "nginx" has cpu limit 0 (check: unset-cpu-requirements, remediation: Set your container's CPU requests and limits depending on its requirements. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits for more details.) nginx.yaml: (object: default/nginx-lint-test apps/v1, Kind=Deployment) container "nginx" has memory request 0 (check: unset-memory-requirements, remediation: Set your container's memory requests and limits depending on its requirements. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits for more details.) nginx.yaml: (object: default/nginx-lint-test apps/v1, Kind=Deployment) container "nginx" has memory limit 0 (check: unset-memory-requirements, remediation: Set your container's memory requests and limits depending on its requirements. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits for more details.) Error: found 6 lint errors
今回のmanifestにおいて、以下のことを注意されています。
- readOnlyRootFilesystemの設定がない
- runAsNonRootが設定されていない
- cpu request/limit が設定されていない
- memory request/limit が設定されていない
チェックする項目は、以下のコマンドで確認することができます。 ただ、resource requirementはあるものの、limitがないなどまだ完璧ではなさそうです。
# kube-linter checks list Name: dangling-service Description: Alert on services that don't have any matching deployments Remediation: Make sure your service's selector correctly matches the labels on one of your deployments. Template: dangling-service Parameters: map[] Enabled by default: true ------------------------------ Name: default-service-account Description: Alert on pods that use the default service account Remediation: Create a dedicated service account for your pod. See https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ for more details. Template: service-account Parameters: map[serviceAccount:^(|default)$] Enabled by default: false ------------------------------ Name: deprecated-service-account-field Description: Alert on deployments that use the deprecated serviceAccount field Remediation: Use the serviceAccountName field instead of the serviceAccount field. Template: deprecated-service-account-field Parameters: map[] Enabled by default: true ------------------------------ Name: env-var-secret Description: Alert on objects using a secret in an environment variable Remediation: Don't use raw secrets in an environment variable. Instead, either mount the secret as a file or use a secretKeyRef. See https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets for more details. Template: env-var Parameters: map[name:(?i).*secret.* value:.+] Enabled by default: true ------------------------------ Name: mismatching-selector Description: Alert on deployments where the selector doesn't match the pod template labels Remediation: Make sure your deployment's selector correctly matches the labels in its pod template. Template: mismatching-selector Parameters: map[] Enabled by default: true ------------------------------ Name: no-anti-affinity Description: Alert on deployments with multiple replicas that don't specify inter pod anti-affinity to ensure that the orchestrator attempts to schedule replicas on different nodes Remediation: Specify anti-affinity in your pod spec to ensure that the orchestrator attempts to schedule replicas on different nodes. You can do this by using podAntiAffinity, specifying a labelSelector that matches pods of this deployment, and setting the topologyKey to kubernetes.io/hostname. See https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity for more details. Template: anti-affinity Parameters: map[minReplicas:2] Enabled by default: true ------------------------------ Name: no-extensions-v1beta Description: Alert on objects using deprecated API versions under extensions v1beta Remediation: Migrate to using the apps/v1 API versions for these objects. See https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/ for more details. Template: disallowed-api-obj Parameters: map[group:extensions version:v1beta.+] Enabled by default: true ------------------------------ Name: no-liveness-probe Description: Alert on containers which don't specify a liveness probe Remediation: Specify a liveness probe in your container. See https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ for more details. Template: liveness-probe Parameters: map[] Enabled by default: false ------------------------------ Name: no-read-only-root-fs Description: Alert on containers not running with a read-only root filesystem Remediation: Set readOnlyRootFilesystem to true in your container's securityContext. Template: read-only-root-fs Parameters: map[] Enabled by default: true ------------------------------ Name: no-readiness-probe Description: Alert on containers which don't specify a readiness probe Remediation: Specify a readiness probe in your container. See https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ for more details. Template: readiness-probe Parameters: map[] Enabled by default: false ------------------------------ Name: non-existent-service-account Description: Alert on pods referencing a service account that isn't found Remediation: Make sure to create the service account, or to refer to an existing service account. Template: non-existent-service-account Parameters: map[] Enabled by default: true ------------------------------ Name: privileged-container Description: Alert on deployments with containers running in privileged mode Remediation: Don't run your container as privileged unless required. Template: privileged Parameters: map[] Enabled by default: true ------------------------------ Name: required-annotation-email Description: Alert on objects without an 'email' annotation with a valid email Remediation: Add an email annotation to your object with the contact information of the object's owner. Template: required-annotation Parameters: map[key:email value:[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+] Enabled by default: false ------------------------------ Name: required-label-owner Description: Alert on objects without the 'owner' label Remediation: Add an email annotation to your object with information about the object's owner. Template: required-label Parameters: map[key:owner] Enabled by default: false ------------------------------ Name: run-as-non-root Description: Alert on containers not set to runAsNonRoot Remediation: Set runAsUser to a non-zero number, and runAsNonRoot to true, in your pod or container securityContext. See https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ for more details. Template: run-as-non-root Parameters: map[] Enabled by default: true ------------------------------ Name: unset-cpu-requirements Description: Alert on containers without CPU requests and limits set Remediation: Set your container's CPU requests and limits depending on its requirements. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits for more details. Template: cpu-requirements Parameters: map[lowerBoundMillis:0 requirementsType:any upperBoundMillis:0] Enabled by default: true ------------------------------ Name: unset-memory-requirements Description: Alert on containers without memory requests and limits set Remediation: Set your container's memory requests and limits depending on its requirements. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits for more details. Template: memory-requirements Parameters: map[lowerBoundMB:0 requirementsType:any upperBoundMB:0] Enabled by default: true ------------------------------ Name: writable-host-mount Description: Alert on containers that mount a host path as writable Remediation: If you need to access files on the host, mount them as readOnly. Template: writable-host-mount Parameters: map[] Enabled by default: false
意図的に、チェック項目を回避する場合は、Annotationに次の項目を記載することで対応できます。
ignore-check.kube-linter.io/<check-name>
今回、resourceに対するrequirement/limitをチェックしないように設定します。
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-lint-test namespace: default labels: app: nginx annotations: ignore-check.kube-linter.io/unset-memory-requirements: "" ignore-check.kube-linter.io/unset-memory-limits: "" ignore-check.kube-linter.io/unset-cpu-requirements: "" ignore-check.kube-linter.io/unset-cpu-limits: ""
再度、kube-linterコマンドを実施します。
# kube-linter lint nginx.yaml nginx.yaml: (object: default/nginx-lint-test 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 your container's securityContext.) nginx.yaml: (object: default/nginx-lint-test 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. See https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ for more details.) Error: found 2 lint errors
ちゃんと設定した4つ分減ったことを確認できました。
最後に
CIにおけるテストに統合するなど、様々な使い方が期待できそうですね!