验证Kubernetes YAML的最佳实践和策略

本文来自Rancher Labsnode

Kubernetes工做负载最多见的定义是YAML格式的文件。使用YAML所面临的挑战之一是,它至关难以表达manifest文件之间的约束或关系。git

若是你想检查全部部署到集群中的镜像是否从受信任的镜像仓库中提取应该怎么作?如何防止没有PodDisruptionBudgets的部署被提交到集群?github

集成静态检查能够在接近开发生命周期的时候发现错误和策略违规。并且因为围绕资源定义的有效性和安全性的保证获得了改善,你能够相信生产工做负载是遵循最佳实践的。web

Kubernetes YAML文件静态检查的生态系统能够分为如下几类:docker

API验证器:这一类工具能够针对Kubernetes API服务器验证给定的YAML manifest。express

内置检查器:这一类工具捆绑了安全、最佳实践等方面的意见检查。编程

自定义验证器:这一类工具容许用几种语言编写自定义检查,如Rego和Javascript。json

在本文中,你将学习并比较六种不一样的工具:api

  • Kubeval
  • Kube-score
  • Config-lint
  • Copper
  • Conftest
  • Polaris

让咱们开始吧!安全

验证Deployment

在开始比较工具以前,你应该设置一个基准。如下manifest并无遵循最佳实践,可能存在一些问题,你能发现几个问题呢?

apiVersion: apps/v1
kind: Deployment
metadata:
  name: http-echo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: http-echo
  template:
    metadata:
      labels:
        app: http-echo
    spec:
      containers:
      - name: http-echo
        image: hashicorp/http-echo
        args: ["-text", "hello-world"]
        ports:
        - containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
  name: http-echo
spec:
  ports:
  - port: 5678
    protocol: TCP
    targetPort: 5678
  selector:
    app: http-echo

咱们将会使用这个YAML文件来对比不一样的工具。

你能够在这个git仓库中找到上面的YAML清单、文件 base-valid.yaml以及文章中提到的其余manifest:

https://github.com/amitsaha/k...

manifest描述了一个老是在5678端口回复“Hello World”消息的web应用程序。

你能够经过如下方式部署该应用程序:

kubectl apply -f hello-world.yaml

你可使用如下命令测试它:

kubectl port-forward svc/http-echo 8080:5678

你能够访问http://localhost:8080 并确认该应用程序可否按照预期运行。可是它是否遵循了最佳实践呢?

让咱们往下看。

Kubeval

主页:https://www.kubeval.com/

Kubeval的前提是,与Kubernetes的任何交互都要经过它的REST API。所以,你可使用API模式来验证一个给定的YAML输入是否符合该模式。咱们来看看一个例子。

你能够按照项目网站上的说明来安装kubeval,撰写此文时最新版本 是0.15.0。安装完成以后,让咱们用前文讨论的manifest来运行它:

kubeval base-valid.yaml
PASS - base-valid.yaml contains a valid Deployment (http-echo)
PASS - base-valid.yaml contains a valid Service (http-echo)

当成功以后,kubeval退出时代码为0。你可使用如下代码验证退出代码:

echo $?
0

如今,让咱们使用另外一个manifest来测试kubeval:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: http-echo
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: http-echo
    spec:
      containers:
      - name: http-echo
        image: hashicorp/http-echo
        args: ["-text", "hello-world"]
        ports:
        - containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
  name: http-echo
spec:
  ports:
  - port: 5678
    protocol: TCP
    targetPort: 5678
  selector:
    app: http-echo

你能发现问题吗?

让咱们运行kubeval:

kubeval kubeval-invalid.yaml
WARN - kubeval-invalid.yaml contains an invalid Deployment (http-echo) - selector: selector is required
PASS - kubeval-invalid.yaml contains a valid Service (http-echo)

# let's check the return value
echo $?
1

资源并无经过验证。使用app/v1 API版本的Deployment必须包含一个匹配Pod标签的selector。上面的manifest没有包含selector,针对manifest运行kubeval报告了一个错误和一个非零的退出代码。

你可能想知道,当你用上面的manifest运行kubectl apply -f时会发生什么?

让咱们试一试:

kubectl apply -f kubeval-invalid.yaml
error: error validating "kubeval-invalid.yaml": error validating data: ValidationError(Deployment.spec):
missing required field "selector" in io.k8s.api.apps.v1.DeploymentSpec; if you choose to ignore these errors,
turn validation off with --validate=false

这正是kubeval警告你的错误。你能够经过添加像这样的selector来修复资源。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: http-echo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: http-echo
  template:
    metadata:
      labels:
        app: http-echo
    spec:
      containers:
      - name: http-echo
        image: hashicorp/http-echo
        args: ["-text", "hello-world"]
        ports:
        - containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
  name: http-echo
spec:
  ports:
  - port: 5678
    protocol: TCP
    targetPort: 5678
  selector:
    app: http-echo

像kubeval这样的工具的好处是,你能够在部署周期的早期发现这样的错误。此外,你不须要访问集群来运行检查——它们能够离线运行。默认状况下,kubeval会根据最新的未发布的Kubernetes API模式验证资源。然而,在大多数状况下,你可能但愿根据特定的Kubernetes版本运行验证。你可使用标志--kubernetes-version来测试特定的API版本:

kubeval --kubernetes-version 1.16.1 base-valid.yaml

请注意,版本应该是Major.Minor.Patch.的形式。要查看可用于验证的版本,请查看GitHub上的JSON schema,kubeval使用它来执行验证。

若是你须要离线运行kubeval,你能够下载schemas,而后使用--schema-location标志来使用本地目录。除了单个YAML文件,你还能够针对目录以及标准输入运行kubeval。你还应该知道,Kubeval易于与你的持续集成流水线集成。若是你想在提交你的manifest到集群以前包含检查,那么kubeval支持三种输出格式也许可以对你有所帮助。

  • 纯文本
  • JSON
  • 测试任何东西协议(TAP)

并且你可使用其中一种格式来进一步解析输出,以建立一个自定义的结果摘要。可是,kubeval存在一个局限性,就是它目前还不能对自定义资源定义(CRD)进行验证。不过kubeval能够忽略它们。

尽管Kubeval是检查和验证资源的绝佳选择,但请注意,经过测试的资源并不能保证符合最佳实践。举个例子,在容器镜像中使用最新的标签被认为不是最佳实践。然而,Kubeval并不会将其做为错误报告,它会在没有警告的状况下验证YAML。

若是你想对YAML进行打分,并抓住诸如使用最新的标签这样的违规行为怎么办?如何根据最佳实践检查你的YAML文件?

Kube-score

主页:https://github.com/zegl/kube-...

Kube-score分析YAML清单,并根据内置的检查进行评分。这些检查是根据安全建议和最佳实践而选择的,例如:

  • 以非root用户身份运行容器。
  • 为pods指定健康检查。
  • 定义资源请求和限制。
  • 检查的结果能够是OK、WARNING或CRITICAL。

你能够在线试用kube-score,也能够在本地安装。在写这篇文章时,最新的版本是1.7.0让咱们试着用以前的manifest base-valid.yaml来运行它:

apps/v1/Deployment http-echo
[CRITICAL] Container Image Tag
  · http-echo -> Image with latest tag
      Using a fixed tag is recommended to avoid accidental upgrades
[CRITICAL] Pod NetworkPolicy
  · The pod does not have a matching network policy
      Create a NetworkPolicy that targets this pod
[CRITICAL] Pod Probes
  · Container is missing a readinessProbe
      A readinessProbe should be used to indicate when the service is ready to receive traffic.
      Without it, the Pod is risking to receive traffic before it has booted. It is also used during
      rollouts, and can prevent downtime if a new version of the application is failing.
      More information: https://github.com/zegl/kube-score/blob/master/README_PROBES.md
[CRITICAL] Container Security Context
  · http-echo -> Container has no configured security context
      Set securityContext to run the container in a more secure context.
[CRITICAL] Container Resources
  · http-echo -> CPU limit is not set
      Resource limits are recommended to avoid resource DDOS. Set resources.limits.cpu
  · http-echo -> Memory limit is not set
      Resource limits are recommended to avoid resource DDOS. Set resources.limits.memory
  · http-echo -> CPU request is not set
      Resource requests are recommended to make sure that the application can start and run without
      crashing. Set resources.requests.cpu
  · http-echo -> Memory request is not set
      Resource requests are recommended to make sure that the application can start and run without crashing.
      Set resources.requests.memory
[CRITICAL] Deployment has PodDisruptionBudget
  · No matching PodDisruptionBudget was found
      It is recommended to define a PodDisruptionBudget to avoid unexpected downtime during Kubernetes
      maintenance operations, such as when draining a node.
[WARNING] Deployment has host PodAntiAffinity
  · Deployment does not have a host podAntiAffinity set
      It is recommended to set a podAntiAffinity that stops multiple pods from a deployment from
      being scheduled on the same node. This increases availability in case the node becomes unavailable.

YAML文件经过了kubeval检查,但kube-score指出了几个不足之处。

  • 缺乏了readiness probe
  • 缺乏内存和CPU请求和限制。
  • 缺乏Poddisruptionbudgets
  • 缺乏反亲和规则以最大化可用性。
  • 容器以root身份运行。

这些都是你应该解决的有效点,以使你的部署更加健壮和可靠。kube-score命令会输出一个可读性高的结果,包含全部的WARNING和CRITICAL违规行为,这在开发过程当中是很是好的。若是你打算把它做为持续集成流水线的一部分,你能够用--output-format ci这个标志来使用更简洁的输出,它还能够打印级别为OK的检查:

kube-score score base-valid.yaml --output-format ci
[OK] http-echo apps/v1/Deployment
[OK] http-echo apps/v1/Deployment
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) CPU limit is not set
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Memory limit is not set
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) CPU request is not set
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Memory request is not set
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Image with latest tag
[OK] http-echo apps/v1/Deployment
[CRITICAL] http-echo apps/v1/Deployment: The pod does not have a matching network policy
[CRITICAL] http-echo apps/v1/Deployment: Container is missing a readinessProbe
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Container has no configured security context
[CRITICAL] http-echo apps/v1/Deployment: No matching PodDisruptionBudget was found
[WARNING] http-echo apps/v1/Deployment: Deployment does not have a host podAntiAffinity set
[OK] http-echo v1/Service
[OK] http-echo v1/Service
[OK] http-echo v1/Service
[OK] http-echo v1/Service

与kubeval相似,当有一个CRITICAL检查失败时,kube-score会返回一个非零的退出代码,但你配置它在WARNINGs时也会失败。还有一个内置的检查来验证不一样API版本的资源,相似于kubeval。然而,这些信息是硬编码在kube-score自己,你不能选择不一样的Kubernetes版本。所以,若是你升级你的集群或你有几个不一样的集群运行不一样的版本,这可能会限制你使用这一工具。

请注意,有一个open issue能够实现这个功能。你能够在官方网站上了解更多关于kube-score的信息:https://github.com/zegl/kube-...

Kube-score检查是执行最佳实践的优秀工具,但若是你想自定义,或者添加本身的规则呢?暂时不能够,Kube-score的设计不是可扩展的,你不能添加或调整政策。若是你想写自定义检查来遵照你的组织政策,你可使用接下来的四个选项之——config-lint、copper、conftest或polaris。

Config-lint

Config-lint是一个旨在验证以YAML、JSON、Terraform、CSV和Kubernetes manifest编写的配置文件的工具。你可使用项目网站上的说明安装它:

https://stelligent.github.io/...

在撰写本文时,最新的版本是1.5.0。

Config-lint没有内置对Kubernetes manifest的检查。你必须编写本身的规则来执行验证。这些规则被写成YAML文件,称为规则集,具备如下结构:

version: 1
description: Rules for Kubernetes spec files
type: Kubernetes
files:
  - "*.yaml"
rules:
   # list of rules

让咱们来详细看看。type字段表示你将用config-lint检查什么类型的配置——通常是Kubernetes manifest。

files字段除了接受单个文件外,还接受一个目录做为输入。

rules字段是你能够定义自定义检查的地方。比方说,你但愿检查Deployment中的镜像是否老是从受信任的镜像仓库(如my-company.com/myapp:1.0)中提取。实现这种检查的 config-lint 规则能够是这样的:

- id: MY_DEPLOYMENT_IMAGE_TAG
  severity: FAILURE
  message: Deployment must use a valid image tag
  resource: Deployment
  assertions:
    - every:
        key: spec.template.spec.containers
        expressions:
          - key: image
            op: starts-with
            value: "my-company.com/"

每条规则必须具备如下属性。

  • id——这是对规则的惟一标识。
  • severity——它必须是FAILURE、WARNING和NON_COMPLIANT中的一个。
  • message——若是违反了一个规则,这个字符串的内容会被显示出来。
  • resource——你但愿这个规则被应用到的资源种类。
  • assertions——将对指定资源进行评估的条件列表。

在上面的规则中,every assertion检查每一个容器中的Deployment(key:spec.templates.spec.contains)是否使用受信任的镜像(即以 "my-company.com/"开头的镜像)。

完整的规则集看起来以下:

version: 1
description: Rules for Kubernetes spec files
type: Kubernetes
files:
  - "*.yaml"
rules:
  - id: DEPLOYMENT_IMAGE_REPOSITORY
    severity: FAILURE
    message: Deployment must use a valid image repository
    resource: Deployment
    assertions:
      - every:
          key: spec.template.spec.containers
          expressions:
            - key: image
              op: starts-with
              value: "my-company.com/"

若是你想要测试检查,你能够将规则集保存为check_image_repo.yaml

如今,让咱们对base-valid.yaml文件进行验证。

config-lint -rules check_image_repo.yaml base-valid.yaml
[
  {
  "AssertionMessage": "Every expression fails: And expression fails: image does not start with my-company.com/",
  "Category": "",
  "CreatedAt": "2020-06-04T01:29:25Z",
  "Filename": "test-data/base-valid.yaml",
  "LineNumber": 0,
  "ResourceID": "http-echo",
  "ResourceType": "Deployment",
  "RuleID": "DEPLOYMENT_IMAGE_REPOSITORY",
  "RuleMessage": "Deployment must use a valid image repository",
  "Status": "FAILURE"
  }
]

它失败了。如今,让咱们考虑如下manifest和有效的镜像仓库:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: http-echo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: http-echo
  template:
    metadata:
      labels:
        app: http-echo
    spec:
      containers:
      - name: http-echo
        image: my-company.com/http-echo:1.0
        args: ["-text", "hello-world"]
        ports:
        - containerPort: 5678

使用以上manifest运行相同的检查而且将不会报告违规:

config-lint -rules check_image_repo.yaml image-valid-mycompany.yaml
[]

Config-lint是一个颇有前途的框架,它可让你使用YAML DSL为Kubernetes YAML manifest编写自定义检查。但若是你想表达更复杂的逻辑和检查呢?是否是YAML的限制性太大?若是你能用真正的编程语言来表达这些检查呢?

Copper

主页:https://github.com/cloud66-os...

Copper V2是一个使用自定义检查来验证清单的框架——就像config-lint同样。然而,Copper并无使用YAML来定义检查。取而代之的是,测试是用JavaScript编写的,Copper提供了一个库,里面有一些基本的帮助程序来协助读取Kubernetes对象和报告错误。

你能够按照官方文档来安装Copper。在写这篇文章的时候,最新的版本是2.0.1:

https://github.com/cloud66-os...

与config-lint相似,Copper没有内置检查。让咱们写一个检查,以确保部署只能从受信任的仓库(如my-company.com)拉取容器镜像。建立一个新文件check_image_repo.js,内容以下:

$$.forEach(function($){
    if ($.kind === 'Deployment') {
        $.spec.template.spec.containers.forEach(function(container) {
            var image = new DockerImage(container.image);
            if (image.registry.lastIndexOf('my-company.com/') != 0) {
                errors.add_error('no_company_repo',"Image " + $.metadata.name + " is not from my-company.com repo", 1)
            }
        });
    }
});

如今,要根据咱们的base-valid.yaml manifest运行这项检查,可使用copper validate命令:

copper validate --in=base-valid.yaml --validator=check_image_tag.js
Check no_company_repo failed with severity 1 due to Image http-echo is not from my-company.com repo
Validation failed

正如你所想的,你能够编写更复杂的检查,好比验证Ingress manifest的域名,或者拒绝任何做为特权运行的Pod。Copper有一些内置的助手:

DockerImage函数读取指定的输入文件并建立一个包含如下属性的对象:

  • name-包含镜像名称
  • tag-包含镜像tag
  • registry-镜像仓库
  • registry_url-包含协议和镜像仓库
  • fqin表明整个彻底合格的镜像位置。
  • findByName函数能够帮助从输入文件中找到给定kind和name的资源。
  • findByLabels函数能够帮助查找资源提供的kindlabels

你能够在这里看到全部可用的帮助程序:

https://github.com/cloud66-os...

默认状况下,它将整个输入的YAML文件加载到$$变量中,并使其在你的脚本中可用(若是你过去使用jQuery,你可能会发现这个模式很熟悉)。

除了不用学习自定义语言外,你还可使用整个JavaScript语言来编写你的检查,如字符串插值、函数等。值得注意的是,目前的copper版本嵌入了ES5版本的JavaScript引擎,而不是ES6。想要了解更多,能够访问项目官网:

https://github.com/cloud66-os...

若是Javascript不是你的首选语言,或者你更喜欢用于查询和描述策略的语言,你应该看看conftest。

Conftest

Conftest是一个配置数据的测试框架,可用于检查和验证Kubernetes manifest。测试使用专门构建的查询语言Rego编写。

你能够按照项目网站上的说明安装conftest,在撰写本文时,最新的版本是0.18.2:

https://www.conftest.dev/inst...

与config-lint和copper相似,conftest也没有任何内置的检查。因此咱们经过编写一个策略来试试。和前面的例子同样,你将检查容器是否来自一个可信的来源。

建立一个新的目录,conftest-checks和一个名为check_image_registry.rego的文件,内容以下:

package main

deny[msg] {

  input.kind == "Deployment"
  image := input.spec.template.spec.containers[_].image
  not startswith(image, "my-company.com/")
  msg := sprintf("image '%v' doesn't come from my-company.com repository", [image])
}

如今让咱们运行conftest来验证manifest base-valid.yaml

conftest test --policy ./conftest-checks base-valid.yaml
FAIL - base-valid.yaml - image 'hashicorp/http-echo' doesn't come from my-company.com repository
1 tests, 1 passed, 0 warnings, 1 failure

固然,它是失败的,由于镜像不受信任。上面的Rego文件指定了一个deny块,当为true时就会评估为违规。当你有多个deny块时,conftest会独立检查它们,整体结果是任何一个块的违规都会致使总体违规。

除了默认的输出格式外,conftest还支持JSON、TAP和经过--output标志的表格格式,若是你但愿将报告与现有的持续集成流水线集成,那么这些格式将会颇有帮助。为了帮助调试策略,conftest有一个方便的--trace标志,它能够打印conftest如何解析指定策略文件的跟踪。

Conftest策略能够做为artefacts在OCI(Open Container Initiative)仓库中发布和共享。命令push和pull容许发布一个工件和从远程仓库中提取一个现有的artefact。

让咱们看看使用conftest push将上述策略发布到本地docker仓库的演示。使用如下命令启动本地docker仓库:

docker run -it --rm -p 5000:5000 registry

从另外一个终端,导航到上面建立的conftest-checks目录,并运行如下命令:

conftest push 127.0.0.1:5000/amitsaha/opa-bundle-example:latest

该命令应成功完成,并显示如下信息:

2020/06/10 14:25:43 pushed bundle with digest: sha256:e9765f201364c1a8a182ca637bc88201db3417bacc091e7ef8211f6c2fd2609c

如今,建立一个临时目录,运行conftest pull命令,将上述bundle下载到临时目录中:

cd $(mktemp -d)
conftest pull 127.0.0.1:5000/amitsaha/opa-bundle-example:latest

你会看到,在包含以前push的策略文件的临时目录中,有一个新的子目录策略:

tree
.
└── policy
  └── check_image_registry.rego

你甚至能够直接从仓库中运行测试:

conftest test --update 127.0.0.1:5000/amitsaha/opa-bundle-example:latest base-valid.yaml
..
FAIL - base-valid.yaml - image 'hashicorp/http-echo' doesn't come from my-company.com repository
2 tests, 1 passed, 0 warnings, 1 failure

不幸的是,DockerHub还不是支持的镜像仓库之一。然而,若是你正在使用Azure容器仓库(ACR)或运行你的容器仓库,可能会经过测试。

artefact格式与开放策略代理 (OPA) 绑定使用的格式相同,这使得使用 conftest 从现有的 OPA 绑定中运行测试成为可能。

你能够在官方网站上了解更多关于共享策略和conftest的其余功能:

https://www.conftest.dev/

Polaris

主页:https://github.com/FairwindsO...

本文将探讨的最后一个工具是polaris。Polaris既能够安装在集群内部,也能够做为命令行工具静态地分析Kubernetes manifest。看成为命令行工具运行时,它包括几个内置的检查,涵盖安全和最佳实践等领域,相似于kube-score。此外,你还能够用它来编写相似config-lint、copper和conftest的自定义检查。换句话说,polaris结合了两个类别中最好的:内置和自定义检查器。

你能够按照项目网站上的说明安装polaris命令行工具。在写这篇文章的时候,最新的版本是1.0.3:

https://github.com/FairwindsO...

安装完成后,你可使用如下命令针对base-valid.yaml manifest运行polaris:

polaris audit --audit-path base-valid.yam

上述命令将打印一个JSON格式的字符串,详细说明运行的检查和每一个测试的结果。输出结果的结构以下:

{
  "PolarisOutputVersion": "1.0",
  "AuditTime": "0001-01-01T00:00:00Z",
  "SourceType": "Path",
  "SourceName": "test-data/base-valid.yaml",
  "DisplayName": "test-data/base-valid.yaml",
  "ClusterInfo": {
    "Version": "unknown",
    "Nodes": 0,
    "Pods": 2,
    "Namespaces": 0,
    "Controllers": 2
  },
  "Results": [
    /* long list */
  ]
}

你能够在下方连接中获取完整的输出:

https://github.com/amitsaha/k...

与kube-score相似,polaris也发现了一些manifest未达到建议的最佳实践的状况,其中包括:

  • 缺乏健康检查的pod。
  • 容器镜像没有指定标签。
  • 容器以root身份运行。
  • 没有设置CPU和内存请求和限制。
  • 每项检查都被划分为警告或危险的严重程度。

要了解有关当前内置检查的更多信息,请参阅文档:

https://github.com/FairwindsO...

若是你对详细的结果不感兴趣,传递标志--format score会打印一个范围为1-100的数字,polaris将其称为分数(score):

polaris audit --audit-path test-data/base-valid.yaml --format score
68

分数越接近100,符合度越高。若是你检查polaris audit命令的退出代码,你会发现它是0。要使polaris审计退出时的代码是非0,能够利用另外两个标志。

--set-exit-code-below-score标志接受范围为1-100的阈值分数,当分数低于阈值时,将以4的退出代码退出。当你的基线分数是75分,而你想在分数低于75分时发出警报时,这很是有用。

当任何危险检查失败时,--set-exit-code-on-danger标志将以3的退出代码退出。

如今让咱们看看如何为polaris定义一个自定义检查,以测试Deployment中的容器镜像是否来自可信任的镜像仓库。自定义检查以YAML格式定义,测试自己使用JSON Schema描述。下面的YAML代码段定义了一个新的检查checkImageRepo:

checkImageRepo:
  successMessage: Image registry is valid
  failureMessage: Image registry is not valid
  category: Images
  target: Container
  schema:
    '$schema': http://json-schema.org/draft-07/schema
    type: object
    properties:
      image:
        type: string
        pattern: ^my-company.com/.+$

让咱们仔细看看:

  • successMessage是检查成功时显示的字符串。
  • failureMessage是指当测试不成功时显示的信息。
  • category指的是其中一个类别—镜像、健康检查、安全、网络和资源。
  • target是一个字符串,用于肯定检查所针对的规范对象,应该是Container、Pod或Controller中的一个。
  • 测试自己是在schema对象中使用JSON模式定义的。这里的检查使用模式关键字来匹配镜像是否来自容许的仓库。

要运行上面定义的检查,你须要建立一个Polaris配置文件,以下所示:

checks:
  checkImageRepo: danger
customChecks:
  checkImageRepo:
    successMessage: Image registry is valid
    failureMessage: Image registry is not valid
    category: Images
    target: Container
    schema:
      '$schema': http://json-schema.org/draft-07/schema
      type: object
      properties:
        image:
          type: string
          pattern: ^my-company.com/.+$

让咱们来分析一下这个文件。

  • check字段指定了检查和它们的严重性。因为你想在镜像不受信任时发出警报,因此checkImageRepo被分配了一个danger严重程度。
  • 而后在customChecks对象中定义checkImageRepo检查自己。

你能够将上面的文件保存为custom_check.yaml,而后用你想要验证的YAML manifest运行polaris audit

你能够用base-valid.yaml manifest进行测试:

polaris audit --config custom_check.yaml --audit-path base-valid.yaml

你会发现,polaris audit只运行了上面定义的自定义检查,但没有成功。若是你将容器镜像修改成my-company.com/http-echo:1.0,polaris将报告成功。Github仓库中包含了修改后的manifest,因此你能够根据image-valid-mycompany.yaml manifest测试前面的命令。

可是如何同时运行内置和自定义检查呢?上面的配置文件应该更新全部内置的检查标识符,看起来应该以下:

checks:
  cpuRequestsMissing: warning
  cpuLimitsMissing: warning
  # Other inbuilt checks..
  # ..
  # custom checks
  checkImageRepo: danger
customChecks:
  checkImageRepo:
    successMessage: Image registry is valid
    failureMessage: Image registry is not valid
    category: Images
    target: Container
    schema:
      '$schema': http://json-schema.org/draft-07/schema
      type: object
      properties:
        image:
          type: string
          pattern: ^my-company.com/.+$

你能够在这里看到一个完整的配置文件的例子:

https://github.com/amitsaha/k...

你能够用自定义和内置检查来测试base-valid.yaml manifest:

polaris audit --config config_with_custom_check.yaml --audit-path base-valid.yaml

Polaris用你的自定义检查加强了内置检查,从而结合了两种方式的最佳状态。然而,若是不能使用更强大的语言,如Rego或JavaScript,可能会限制编写更复杂的检查。

要了解更多关于polaris的信息,请查看项目网站:

https://github.com/FairwindsO...

总 结

虽然有不少工具能够验证、打分和精简Kubernetes YAML文件,但重要的是要有一个心理模型来了解你将如何设计和执行检查。举个例子,若是你想让Kubernetes manifest经过一个流水线,kubeval能够是这样一个流水线的第一步,由于它验证对象定义是否符合Kubernetes API模式。一旦这项检查成功,也许你能够继续进行更详细的测试,好比标准最佳实践和自定义策略。Kube-score和polaris在这里是最优秀的选择。

若是你有复杂的需求,而且想要自定义检查的细节,你应该考虑copper、config-lint和conftest。虽然conftest和config-lint都使用了更多的YAML来定义自定义验证规则,但copper给你提供了一个真正的编程语言,使其至关有吸引力。可是,你应该使用其中的一个,从头开始写全部的检查,仍是应该使用Polaris,只写额外的自定义检查?这要根据状况而定。

相关文章
相关标签/搜索