2020年10月28日,StackRox 引入了一个名为 KubeLinter 的新开源工具,旨在识别 YAML 文件中的任何错误配置。
在 Kubernetes 的世界中,我们使用 YAML 文件,对其进行部署以创建各种 Kubernetes 对象,但挑战在于编写它们时是否遵循最佳实践?我们使用的是正确的标准配置集吗?在部署应用程序甚至 Helm 图表之前,可以检查 YAML 吗?所有这些问题的答案都是肯定的,我们可以。2020年10月28日,StackRox 引入了一个名为 KubeLinter 的新开源工具,旨在识别 YAML 文件中的任何错误配置。
根据定义,KubeLinter 是一个静态分析工具,用于检查 Kubernetes YAML 文件和 Helm 图表,以确保其中所代表的应用程序遵循最佳实践。将 YAML 文件提供给该工具后,它将通过内置检查运行,然后详细报告任何错误以及解决这些错误的补救措施。关于此工具的最好之处在于它是可配置和可扩展的:可以启用或禁用内置检查,并且您可以定义和使用自己的自定义检查。
用法
我将在 Mac 上安装 KubeLinter,但只需下载适用于您操作系统的发行版,即可将相同的说明用于Linux。
你可以从https://github.com/stackrox/kube-linter/releases/下载 KubeLinter CLI,如下所示:
- $curl-LOhttps://github.com/stackrox/kube-linter/releases/download/0.1.1/kube-linter-darwin.zip
- $unzipkube-linter-darwin.zip
- $mvkube-linter/usr/local/bin
- #checkifit'sworking
- $kube-linterversion
- 0.1.1
现在,为了简单地检查单个 YAML 文件,只需提供 YAML 文件名。假设 deploy.YAML 您要检查以下文件,以检查其当前目录中保存的最佳安全性和配置做法:
- 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:
- {}
让我们进行测试 kube-linter lint deploy.yaml。我们应该得到如下输出:
- deploy.yaml:(object:portainer/portainerapps/v1,Kind=Deployment)container"portainer"doesnothavearead-onlyrootfilesystem(check:no-read-only-root-fs,remediation:SetreadOnlyRootFilesystemtotrueinyourcontainer'ssecurityContext.)
- deploy.yaml:(object:portainer/portainerapps/v1,Kind=Deployment)serviceAccount"portainer-sa-clusteradmin"notfound(check:non-existent-service-account,remediation:Makesuretocreatetheserviceaccount,ortorefertoanexistingserviceaccount.)
- deploy.yaml:(object:portainer/portainerapps/v1,Kind=Deployment)container"portainer"isnotsettorunAsNonRoot(check:run-as-non-root,remediation:SetrunAsUsertoanon-zeronumber,andrunAsNonRoottotrue,inyourpodorcontainersecurityContext.Seehttps://kubernetes.io/docs/tasks/configure-pod-container/security-context/formoredetails.)
- deploy.yaml:(object:portainer/portainerapps/v1,Kind=Deployment)container"portainer"hascpurequest0(check:unset-cpu-requirements,remediation:Setyourcontainer'sCPUrequestsandlimitsdependingonitsrequirements.Seehttps://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limitsformoredetails.)
- deploy.yaml:(object:portainer/portainerapps/v1,Kind=Deployment)container"portainer"hascpulimit0(check:unset-cpu-requirements,remediation:Setyourcontainer'sCPUrequestsandlimitsdependingonitsrequirements.Seehttps://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limitsformoredetails.)
- deploy.yaml:(object:portainer/portainerapps/v1,Kind=Deployment)container"portainer"hasmemoryrequest0(check:unset-memory-requirements,remediation:Setyourcontainer'smemoryrequestsandlimitsdependingonitsrequirements.Seehttps://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limitsformoredetails.)
- deploy.yaml:(object:portainer/portainerapps/v1,Kind=Deployment)container"portainer"hasmemorylimit0(check:unset-memory-requirements,remediation:Setyourcontainer'smemoryrequestsandlimitsdependingonitsrequirements.Seehttps://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limitsformoredetails.)
- Error:found7linterrors
检测类型
如您所见,YAML 文件中发现了错误,每个错误都有明确的补救步骤。
如果您想看一下内置检查,可以在https://github.com/stackrox/kube-linter/blob/main/docs/genic/checks.md中列出所有这些检查,或者也可以使用 KubeLinter 查看清单:
- $kube-lintercheckslist
- Name:dangling-service
- Description:Alertonservicesthatdon'thaveanymatchingdeployments
- Remediation:Makesureyourservice'sselectorcorrectlymatchesthelabelsononeofyourdeployments.
- Template:dangling-service
- Parameters:map[]
- Enabledbydefault:true
- ------------------------------
- Name:default-service-account
- Description:Alertonpodsthatusethedefaultserviceaccount
- Remediation:Createadedicatedserviceaccountforyourpod.Seehttps://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/formoredetails.
- Template:service-account
- Parameters:map[serviceAccount:^(|default)$]
- Enabledbydefault:false
- |
- |
- |
- andmanymore
忽略检测
您可以使用以下注释忽略针对 YAML 文件的特定检查,也可以根据需要忽略检查组:
- ignore-check.kube-linter.io/<check-name>
例如:
- ignore-check.kube-linter.io/unset-cpu-requirements
您可以像上面这样在上面的部署文件示例中添加忽略检查规则:
- 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:"cpurequirementsnotrequired"
现在,当您 kube-linter lint deploy.yaml 再次运行时,您应该不会看到与 CPU 要求相关的错误提示。
使用配置运行
KubeLinter 也可以使用配置运行,您可以在其中提供要包含/排除的所有检测信息。以下是存储库中的示例配置:
- #customChecksdefinescustomchecks.
- customChecks:
- -name:"required-label-app"
- template:"required-label"
- params:
- key:"app"
- checks:
- #ifdoNotAutoAddDefaultsistrue,defaultchecksarenotautomaticallyadded.
- doNotAutoAddDefaults:false
- #addAllBuiltIn,ifset,addsallbuilt-inchecks.Thisallowsusersto
- #explicitlyopt-outofchecksthatarenotrelevantusingExclude.
- #TakesprecedenceoverdoNotAutoAddDefaults,ifbothareset.
- addAllBuiltIn:false
- #includeexplicitlyaddschecks,byname.Youcanreferenceanyofthebuilt-inchecks.
- #NotethatcustomChecksdefinedaboveareincludedautomatically.
- include:
- -"required-label-owner"
- #excludeexplicitlyexcludeschecks,byname.excludehasthehighestpriority:ifacheckis
- #inexclude,thenitisnotconsidered,evenifitisinincludeaswell.
- exclude:
- -"privileged"
如果你运行KubeLinter --config config lint deploy.yaml,其中 config 与上述配置的文件,你应该可以看到添加了需要标签的检查:
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.)
当内置到 CI 管道中时,KubeLinter 可以证明是非常有用的工具。可以检查和验证推送到存储库中的编排文件,以获取最佳实践和安全考虑,并在检测到问题时生成警报。
这样,可以将部署到集群的应用程序进行健康的就绪检查。该项目处于 Alpha 阶段,但有望作为 CI 集成工具在实际部署到生产之前验证所有部署。