在 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 -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
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
现在,为了简单地检查单个 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:
{}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
让我们进行测试 kube-linter lint deploy.yaml。我们应该得到如下输出:
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
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
检测类型
如您所见,YAML 文件中发现了错误,每个错误都有明确的补救步骤。
如果您想看一下内置检查,可以在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
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
忽略检测
您可以使用以下注释忽略针对 YAML 文件的特定检查,也可以根据需要忽略检查组:
ignore-check.kube-linter.io/<check-name>
- 1.
例如:
ignore-check.kube-linter.io/unset-cpu-requirements
- 1.
您可以像上面这样在上面的部署文件示例中添加忽略检查规则:
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"
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
现在,当您 kube-linter lint deploy.yaml 再次运行时,您应该不会看到与 CPU 要求相关的错误提示。
使用配置运行
KubeLinter 也可以使用配置运行,您可以在其中提供要包含/排除的所有检测信息。以下是存储库中的示例配置:
# 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"
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
如果你运行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 集成工具在实际部署到生产之前验证所有部署。