推薦一款Kubernetes YAML文件靜態(tài)分析工具KubeLinter
在 Kubernetes 的世界中,我們使用 YAML 文件,對其進(jìn)行部署以創(chuàng)建各種 Kubernetes 對象,但挑戰(zhàn)在于編寫它們時(shí)是否遵循最佳實(shí)踐?我們使用的是正確的標(biāo)準(zhǔn)配置集嗎?在部署應(yīng)用程序甚至 Helm 圖表之前,可以檢查 YAML 嗎?所有這些問題的答案都是肯定的,我們可以。2020年10月28日,StackRox 引入了一個(gè)名為 KubeLinter 的新開源工具,旨在識別 YAML 文件中的任何錯(cuò)誤配置。
根據(jù)定義,KubeLinter 是一個(gè)靜態(tài)分析工具,用于檢查 Kubernetes YAML 文件和 Helm 圖表,以確保其中所代表的應(yīng)用程序遵循最佳實(shí)踐。將 YAML 文件提供給該工具后,它將通過內(nèi)置檢查運(yùn)行,然后詳細(xì)報(bào)告任何錯(cuò)誤以及解決這些錯(cuò)誤的補(bǔ)救措施。關(guān)于此工具的最好之處在于它是可配置和可擴(kuò)展的:可以啟用或禁用內(nèi)置檢查,并且您可以定義和使用自己的自定義檢查。
用法
我將在 Mac 上安裝 KubeLinter,但只需下載適用于您操作系統(tǒng)的發(fā)行版,即可將相同的說明用于Linux。
你可以從https://github.com/stackrox/kube-linter/releases/下載 KubeLinter CLI,如下所示:
- $ curl -LO https://github.com/stackrox/kube-linter/releases/download/0.1.1/kube-linter-darwin.zip
- $ unzip kube-linter-darwin.zip
- $ mv kube-linter /usr/local/bin
- #check if it's working
- $ kube-linter version
- 0.1.1
現(xiàn)在,為了簡單地檢查單個(gè) YAML 文件,只需提供 YAML 文件名。假設(shè) deploy.yaml 您要檢查以下文件,以檢查其當(dāng)前目錄中保存的最佳安全性和配置做法:
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: portainer
- namespace: portainer
- labels:
- io.portainer.kubernetes.application.stack: portainer
- app.kubernetes.io/name: portainer
- app.kubernetes.io/instance: portainer
- app.kubernetes.io/version: "2.0.0"
- spec:
- replicas: 1
- strategy:
- type: "Recreate"
- selector:
- matchLabels:
- app.kubernetes.io/name: portainer
- app.kubernetes.io/instance: portainer
- template:
- metadata:
- labels:
- app.kubernetes.io/name: portainer
- app.kubernetes.io/instance: portainer
- spec:
- serviceAccountName: portainer-sa-clusteradmin
- volumes:
- - name: "data"
- persistentVolumeClaim:
- claimName: portainer
- containers:
- - name: portainer
- image: "portainer/portainer-ce:latest"
- imagePullPolicy: IfNotPresent
- args: [ '--tunnel-port','30776' ]
- volumeMounts:
- - name: data
- mountPath: /data
- ports:
- - name: http
- containerPort: 9000
- protocol: TCP
- - name: tcp-edge
- containerPort: 8000
- protocol: TCP
- livenessProbe:
- httpGet:
- path: /
- port: 9000
- readinessProbe:
- httpGet:
- path: /
- port: 9000
- resources:
- {}
讓我們進(jìn)行測試 kube-linter lint deploy.yaml。我們應(yīng)該得到如下輸出:
- deploy.yaml: (object: portainer/portainer apps/v1, Kind=Deployment) container "portainer" 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.)
- deploy.yaml: (object: portainer/portainer apps/v1, Kind=Deployment) serviceAccount "portainer-sa-clusteradmin" not found (check: non-existent-service-account, remediation: Make sure to create the service account, or to refer to an existing service account.)
- deploy.yaml: (object: portainer/portainer apps/v1, Kind=Deployment) container "portainer" 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.)
- deploy.yaml: (object: portainer/portainer apps/v1, Kind=Deployment) container "portainer" 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.)
- deploy.yaml: (object: portainer/portainer apps/v1, Kind=Deployment) container "portainer" 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.)
- deploy.yaml: (object: portainer/portainer apps/v1, Kind=Deployment) container "portainer" 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.)
- deploy.yaml: (object: portainer/portainer apps/v1, Kind=Deployment) container "portainer" 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 7 lint errors
檢測類型
如您所見,YAML 文件中發(fā)現(xiàn)了錯(cuò)誤,每個(gè)錯(cuò)誤都有明確的補(bǔ)救步驟。
如果您想看一下內(nèi)置檢查,可以在https://github.com/stackrox/kube-linter/blob/main/docs/genic/checks.md中列出所有這些檢查,或者也可以使用 KubeLinter 查看清單:
- $ 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
- |
- |
- |
- and many more
忽略檢測
您可以使用以下注釋忽略針對 YAML 文件的特定檢查,也可以根據(jù)需要忽略檢查組:
- ignore-check.kube-linter.io/<check-name>
例如:
- ignore-check.kube-linter.io/unset-cpu-requirements
您可以像上面這樣在上面的部署文件示例中添加忽略檢查規(guī)則:
- metadata:
- name: portainer
- namespace: portainer
- labels:
- io.portainer.kubernetes.application.stack: portainer
- app.kubernetes.io/name: portainer
- app.kubernetes.io/instance: portainer
- app.kubernetes.io/version: "2.0.0"
- annotations:
- ignore-check.kube-linter.io/unset-cpu-requirements : "cpu requirements not required"
現(xiàn)在,當(dāng)您 kube-linter lint deploy.yaml 再次運(yùn)行時(shí),您應(yīng)該不會看到與 CPU 要求相關(guān)的錯(cuò)誤提示。
使用配置運(yùn)行
KubeLinter 也可以使用配置運(yùn)行,您可以在其中提供要包含/排除的所有檢測信息。以下是存儲庫中的示例配置:
- # customChecks defines custom checks.
- customChecks:
- - name: "required-label-app"
- template: "required-label"
- params:
- key: "app"
- checks:
- # if doNotAutoAddDefaults is true, default checks are not automatically added.
- doNotAutoAddDefaults: false
- # addAllBuiltIn, if set, adds all built-in checks. This allows users to
- # explicitly opt-out of checks that are not relevant using Exclude.
- # Takes precedence over doNotAutoAddDefaults, if both are set.
- addAllBuiltIn: false
- # include explicitly adds checks, by name. You can reference any of the built-in checks.
- # Note that customChecks defined above are included automatically.
- include:
- - "required-label-owner"
- # exclude explicitly excludes checks, by name. exclude has the highest priority: if a check is
- # in exclude, then it is not considered, even if it is in include as well.
- exclude:
- - "privileged"
如果你運(yùn)行kubelinter --config config lint deploy.yaml,其中 config 與上述配置的文件,你應(yīng)該可以看到添加了需要標(biāo)簽的檢查:
deploy.yaml: (object: portainer/portainer apps/v1, Kind=Deployment) no label matching "owner=<any>" found (check: required-label-owner, remediation: Add an email annotation to your object with information about the object's owner.)
當(dāng)內(nèi)置到 CI 管道中時(shí),KubeLinter 可以證明是非常有用的工具??梢詸z查和驗(yàn)證推送到存儲庫中的編排文件,以獲取最佳實(shí)踐和安全考慮,并在檢測到問題時(shí)生成警報(bào)。
這樣,可以將部署到集群的應(yīng)用程序進(jìn)行健康的就緒檢查。該項(xiàng)目處于 Alpha 階段,但有望作為 CI 集成工具在實(shí)際部署到生產(chǎn)之前驗(yàn)證所有部署。