根据最佳实践和策略验证 Kubernetes YAML

笔记。 翻译。:随着K8s环境的YAML配置越来越多,对其自动化验证的需求变得越来越迫切。 本次评测的作者不仅选择了用于此任务的现有解决方案,而且还以 Deployment 为例来了解它们是如何工作的。 事实证明,对于那些对此主题感兴趣的人来说,这是非常有用的。

根据最佳实践和策略验证 Kubernetes YAML

TL博士:本文比较了六种静态工具,用于根据最佳实践和要求验证和评估 Kubernetes YAML 文件。

Kubernetes 工作负载通常以 YAML 文档的形式定义。 YAML 的问题之一是难以指定清单文件之间的约束或关系。

如果我们需要确保部署到集群的所有映像都来自受信任的注册表怎么办?

如何防止没有 PodDisruptionBudgets 的 Deployment 被发送到集群?

静态测试的集成使您可以在开发阶段识别错误和策略违规。 这提高了资源定义正确和安全的保证,并使生产工作负载更有可能遵循最佳实践。

Kubernetes静态YAML文件检查生态系统可以分为以下几类:

  • API验证器。 此类别中的工具会根据 Kubernetes API 服务器的要求检查 YAML 清单。
  • 准备好测试人员。 此类工具附带现成的安全性测试、最佳实践合规性测试等。
  • 自定义验证器。 此类别的代表允许您使用各种语言创建自定义测试,例如 Rego 和 Javascript。

在本文中,我们将描述和比较六种不同的工具:

  1. 库贝瓦尔;
  2. kube 分数;
  3. 配置-lint;
  4. 铜;
  5. 比赛;
  6. 北极星。

好吧,让我们开始吧!

检查部署

在开始比较工具之前,让我们先创建一些背景来测试它们。

下面的宣言包含许多错误和不符合最佳实践的情况:您能找到其中多少?

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

(base-valid.yaml)

我们将使用此 YAML 来比较不同的工具。

上述宣言 base-valid.yaml 以及本文中的其他宣言可以在以下位置找到: Git 存储库.

该清单描述了一个 Web 应用程序,其主要任务是向端口 5678 响应“Hello World”消息。可以使用以下命令部署它:

kubectl apply -f hello-world.yaml

所以 - 检查工作:

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

现在去 http://localhost:8080 并确认应用程序正在运行。 但它遵循最佳实践吗? 让我们检查。

1.库贝瓦尔

在心脏 库贝瓦尔 这个想法是,与 Kubernetes 的任何交互都是通过其 REST API 进行的。 换句话说,您可以使用 API 模式来检查给定的 YAML 是否符合它。 让我们看一个例子。

安装说明 kubeval 可在项目网站上找到。

在撰写原始文章时,版本 0.15.0 已经可用。

安装后,让我们为其提供上面的清单:

$ 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

现在让我们尝试使用不同的清单来尝试 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-invalid.yaml)

你能用眼睛发现问题吗? 让我们启动:

$ 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)

# проверим код возврата
$ echo $?
1

该资源尚未得到验证。

使用 API 版本进行部署 apps/v1,必须包含与 pod 标签匹配的选择器。 上面的清单不包含选择器,因此 kubeval 报告错误并以非零代码退出。

我想知道如果我这样做会发生什么 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 警告的错误。 您可以通过添加选择器来修复它:

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

(base-valid.yaml)

kubeval 等工具的好处是可以在部署周期的早期发现此类错误。

此外,这些检查不需要访问集群;它们可以离线执行。

默认情况下,kubeval 根据最新的 Kubernetes API 架构检查资源。 但是,在大多数情况下,您可能需要检查特定的 Kubernetes 版本。 这可以使用标志来完成 --kubernetes-version:

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

请注意,版本必须以格式指定 Major.Minor.Patch.

支持验证的版本列表,请参考 GitHub 上的 JSON 架构,kubeval 使用它进行验证。 如果您需要离线运行 kubeval,请下载模式并使用标志指定其本地位置 --schema-location.

除了单个 YAML 文件之外,kubeval 还可以使用目录和标准输入。

此外,Kubeval 可以轻松集成到 CI 管道中。 那些希望在将清单发送到集群之前运行测试的人会很高兴知道 kubeval 支持三种输出格式:

  1. 纯文本;
  2. JSON;
  3. 测试一切协议 (TAP)。

任何格式都可用于进一步解析输出,以生成所需类型的结果摘要。

kubeval 的缺点之一是它目前无法检查是否符合自定义资源定义 (CRD)。 但是,可以配置 kubeval 别理他们.

Kubeval 是一个检查和评估资源的好工具; 但是,应该强调的是,通过测试并不能保证资源符合最佳实践。

例如,使用标签 latest 在容器中不遵循最佳实践。 然而,kubeval 并不认为这是一个错误,也不会报告它。 也就是说,此类 YAML 的验证将在没有警告的情况下完成。

但是,如果您想评估 YAML 并识别标签之类的违规行为该怎么办 latest? 如何根据最佳实践检查 YAML 文件?

2. Kube-分数

Kube-分数 解析 YAML 清单并根据内置测试对其进行评估。 这些测试是根据安全准则和最佳实践选择的,例如:

  • 不以 root 身份运行容器。
  • Pod 健康检查的可用性。
  • 设置资源请求和限制。

根据测试结果,给出三个结果: OK, 警告 и 危急.

您可以在线尝试 Kube-score 或本地安装。

在撰写原始文章时,kube-score 的最新版本是 1.7.0。

让我们在清单上尝试一下 base-valid.yaml:

$ kube-score score 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 指出了以下缺陷:

  • 未配置就绪检查。
  • 对 CPU 资源和内存没有请求或限制。
  • 未指定 Pod 中断预算。
  • 没有分离的规则 (反亲和力) 以最大限度地提高可用性。
  • 容器以 root 身份运行。

这些都是关于需要解决的缺点的有效观点,以使部署更加高效和可靠。

团队 kube-score 以人类可读的形式显示信息,包括所有类型违规 警告 и 危急,这在开发过程中有很大帮助。

那些希望在 CI 管道中使用此工具的人可以使用该标志启用更压缩的输出 --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 类似,当测试失败时,kube-score 返回非零退出代码 危急。 您还可以启用类似的处理 警告.

此外,还可以检查资源是否符合不同 API 版本(如 kubeval 中)。 然而,这些信息是硬编码在 kube-score 本身中的:您无法选择不同版本的 Kubernetes。 如果您打算升级集群或者您有多个具有不同版本 K8s 的集群,则此限制可能会成为一个大问题。

请注意, 已经有问题了 并提出实现这一机会的建议。

有关 kube-score 的更多信息可以在以下位置找到: 官方网站.

Kube-score 测试是实现最佳实践的绝佳工具,但如果您需要更改测试或添加自己的规则怎么办? 唉,这是不可能的。

Kube-score 不可扩展:您无法向其中添加策略或调整策略。

如果您需要编写自定义测试来验证是否符合公司策略,可以使用以下四种工具之一:config-lint、copper、conftest 或 Polaris。

3.配置-lint

Config-lint 是一个用于验证 YAML、JSON、Terraform、CSV 配置文件和 Kubernetes 清单的工具。

您可以使用安装它 指示 在项目网站上。

截至撰写原始文章时,当前版本是 1.5.0。

Config-lint 没有用于验证 Kubernetes 清单的内置测试。

要进行任何测试,您需要创建适当的规则。 它们被写入称为“规则集”的 YAML 文件中 (规则集),并具有以下结构:

version: 1
description: Rules for Kubernetes spec files
type: Kubernetes
files:
  - "*.yaml"
rules:
   # список правил

(rule.yaml)

让我们更仔细地研究一下:

  • 领域 type 指定 config-lint 将使用什么类型的配置。 对于 K8s 清单,这是 всегда Kubernetes.
  • 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/"

(rule-trusted-repo.yaml)

每个规则必须具有以下属性:

  • id — 规则的唯一标识符;
  • severity - 或许 失败, 警告 и 不符合标准;
  • message — 如果违反规则,则显示该行的内容;
  • resource ——本规则适用的资源类型;
  • assertions — 将评估与该资源相关的条件列表。

在上面的规则中 assertion 标题 every 检查所有容器是否都处于部署状态(key: spec.templates.spec.containers)使用可信图像(即从 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/"

(ruleset.yaml)

要尝试测试,我们将其另存为 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"
  }
]

检查失败。 现在让我们使用正确的图像存储库检查以下清单:

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

(image-valid-mycompany.yaml)

我们使用上面的清单运行相同的测试。 没有发现问题:

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

Config-lint 是一个很有前途的框架,它允许您创建自己的测试来使用 YAML DSL 验证 Kubernetes YAML 清单。

但是如果您需要更复杂的逻辑和测试怎么办? YAML 对此是否太有限了? 如果您可以用完整的编程语言创建测试怎么办?

4。 铜

铜V2 是一个使用自定义测试验证清单的框架(类似于 config-lint)。

但它与后者的不同之处在于它不使用 YAML 来描述测试。 测试可以用 JavaScript 编写。 Copper 提供了一个包含几个基本工具的库,它可以帮助您读取有关 Kubernetes 对象的信息并报告错误。

安装 Copper 的步骤可以在 官方文档.

2.0.1 是撰写原始文章时该实用程序的最新版本。

与 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, 使用命令 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

很明显,在 Copper 的帮助下,您可以执行更复杂的测试 - 例如,检查 Ingress 清单中的域名或拒绝在特权模式下运行的 pod。

Copper 内置了各种实用功能:

  • DockerImage 读取指定的输入文件并创建具有以下属性的对象:
    • name - 图像的名称,
    • tag - 图像标签,
    • registry - 图像注册表,
    • registry_url - 协议 (https://)和图像注册表,
    • fqin — 图像的完整位置。
  • 功能 findByName 有助于按给定类型查找资源(kind)和姓名(name)来自输入文件。
  • 功能 findByLabels 有助于按指定类型查找资源(kind)和标签(labels).

您可以查看所有可用的服务功能 这里.

默认情况下,它将整个输入 YAML 文件加载到变量中 $$ 并使其可用于脚本编写(对于具有 jQuery 经验的人来说这是一种熟悉的技术)。

Copper 的主要优点是显而易见的:您不需要掌握专门的语言,您可以使用各种 JavaScript 功能来创建自己的测试,例如字符串插值、函数等。

还应该注意的是,当前版本的 Copper 适用于 ES5 版本的 JavaScript 引擎,而不是 ES6。

详情请参阅 项目官网.

但是,如果您并不真正喜欢 JavaScript,而更喜欢专门为创建查询和描述策略而设计的语言,那么您应该关注 conftest。

5.竞赛

Conftest是一个用于测试配置数据的框架。 也适合测试/验证 Kubernetes 清单。 使用专门的查询语言描述测试 雷哥.

您可以使用安装conftest 指示列在项目网站上。

在撰写原始文章时,可用的最新版本是 0.18.2。

与 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])
}

现在我们来测试一下 base-valid.yaml 通过 conftest:

$ 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。 其真实性被视为违规。 如果阻塞 deny 对于几个区块,conftest 会相互独立地检查它们,并且任何区块的真实性都将被视为违规。

除了默认输出之外,conftest 还支持 JSON、TAP 和表格格式 - 如果您需要将报告嵌入到现有的 CI 管道中,这是一个非常有用的功能。 您可以使用标志设置所​​需的格式 --output.

为了更容易调试策略,conftest 有一个标志 --trace。 它输出conftest 如何解析指定策略文件的跟踪。

竞赛政策可以作为工件在 OCI(开放容器倡议)注册表中发布和共享。

Команды push и pull 允许您发布工件或从远程注册表检索现有工件。 让我们尝试使用以下命令将我们创建的策略发布到本地 Docker 注册表 conftest push.

启动本地 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。 它将下载由上一个命令创建的包:

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

临时目录中会出现一个子目录 policy包含我们的策略文件:

$ 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) 或您自己的注册表。

工件格式与 打开策略代理包 (OPA),它允许您使用 conftest 从现有 OPA 包运行测试。

您可以在以下位置了解有关策略共享和 conftest 其他功能的更多信息: 项目官网.

6。 北极星

本文将讨论的最后一个工具是 Polaris. (他去年的声明我们 已经翻译了 - 约。 翻译)

Polaris 可以安装在集群中,也可以在命令行模式下使用。 正如您可能已经猜到的,它允许您静态分析 Kubernetes 清单。

在命令行模式下运行时,可以使用内置测试,涵盖安全性和最佳实践等领域(类似于 kube-score)。 此外,您还可以创建自己的测试(如 config-lint、copper 和 conftest)。

换句话说,Polaris 结合了这两类工具的优点:内置测试和自定义测试。

要在命令行模式下安装 Polaris,请使用 项目网站上的说明.

在撰写原始文章时,版本 1.0.3 已经可用。

安装完成后,您可以在清单上运行 Polaris base-valid.yaml 使用以下命令:

$ polaris audit --audit-path base-valid.yaml

它将输出 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": [
    /* длинный список */
  ]
}

提供完整输出 这里.

与 kube-score 一样,Polaris 可以识别清单不符合最佳实践的区域中的问题:

  • 没有对 Pod 进行健康检查。
  • 未指定容器镜像的标签。
  • 容器以 root 身份运行。
  • 未指定内存和 CPU 的请求和限制。

每个测试根据其结果被分配一定的关键程度: 警告 или 危险。 要了解有关可用内置测试的更多信息,请参阅 文件资料.

如果不需要详细信息,您可以指定标志 --format score。 在这种情况下,Polaris 将输出一个范围从 1 到 100 的数字 - 得分了 (即评估):

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

分数越接近100,一致程度越高。 如果您检查命令的退出代码 polaris audit,结果证明它等于0。

使 polaris audit 您可以使用两个标志终止非零代码的工作:

  • --set-exit-code-below-score 采用 1-100 范围内的阈值作为参数。 在这种情况下,如果分数低于阈值,命令将以退出代码 4 退出。 当您有某个阈值(例如 75)并且分数低于您需要收到警报时,这非常有用。
  • --set-exit-code-on-danger 如果危险测试之一失败,将导致命令失败并显示代码 3。

现在让我们尝试创建一个自定义测试来检查图像是否取自受信任的存储库。 自定义测试以 YAML 格式指定,测试本身使用 JSON 架构进行描述。

以下 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 — 表示类别之一: Images, Health Checks, Security, Networking и Resources;
  • target--- 确定对象的类型(spec) 进行测试。 可能的值: Container, Pod или Controller;
  • 测试本身在对象中指定 schema 使用 JSON 模式。 本次测试的关键词是 pattern 用于将图像源与所需图像进行比较。

要运行上述测试,您需要创建以下 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/.+$

(polaris-conf.yaml)

我们来解析一下这个文件:

  • checks 规定了测试及其关键级别。 由于希望在从不受信任的来源获取图像时收到警告,因此我们在此处设置级别 danger.
  • 测试本身 checkImageRepo 然后注册到对象中 customChecks.

将文件另存为 custom_check.yaml。 现在你可以运行 polaris audit 带有需要验证的 YAML 清单。

让我们测试一下我们的宣言 base-valid.yaml:

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

团队 polaris audit 仅运行了上面指定的用户测试,但失败了。

如果将图像修复为 my-company.com/http-echo:1.0,北极星将成功完成。 包含这些变化的宣言已经在 储存库这样你就可以检查清单上的上一个命令 image-valid-mycompany.yaml.

现在问题来了:如何将内置测试与自定义测试一起运行? 容易地! 您只需将内置测试标识符添加到配置文件中即可。 结果,它将采用以下形式:

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/.+$

(config_with_custom_check.yaml)

提供了完整配置文件的示例 这里.

检查舱单 base-valid.yaml使用内置和自定义测试,您可以使用以下命令:

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

Polaris 用定制测试补充了内置测试,从而结合了两全其美的优点。

另一方面,无法使用更强大的语言(例如 Rego 或 JavaScript)可能成为阻止创建更复杂测试的限制因素。

有关北极星的更多信息,请访问 项目网站.

总结

虽然有许多工具可用于检查和评估 Kubernetes YAML 文件, 清楚地了解如何设计和执行测试非常重要.

Например, 如果您通过管道获取 Kubernetes 清单,那么 kubeval 可能是此类管道中的第一步。 它将监视对象定义是否符合 Kubernetes API 架构。

一旦完成这样的审查,就可以进行更复杂的测试,例如是否符合标准最佳实践和特定政策。 这就是 kube-score 和 Polaris 派上用场的地方。

对于那些有复杂需求并需要详细定制测试的人,copper、config-lint 和 conftest 会比较合适.

Conftest 和 config-lint 使用 YAML 来定义自定义测试,而 Copper 使您可以访问完整的编程语言,这使其成为一个非常有吸引力的选择。

另一方面,是否值得使用其中一个工具并因此手动创建所有测试,或者更喜欢 Polaris 并仅添加需要的内容? 这个问题没有明确的答案.

下表提供了每个工具的简要说明:

工具
命运
限制
用户测试

库贝瓦尔
根据特定版本的 API 架构验证 YAML 清单
无法与 CRD 一起使用
没有

kube-分数
根据最佳实践分析 YAML 清单
无法选择您的 Kubernetes API 版本来检查资源
没有


用于为 YAML 清单创建自定义 JavaScript 测试的通用框架
没有内置测试。 文档不完善

配置-lint
用于使用嵌入在 YAML 中的特定于域的语言创建测试的通用框架。 支持各种配置格式(例如 Terraform)
没有现成的测试。 内置断言和函数可能还不够

会议测试
使用 Rego(一种专门的查询语言)创建您自己的测试的框架。 允许通过 OCI 捆绑共享策略
没有内置测试。 我得学习雷戈。 发布策略时不支持 Docker Hub

Polaris
根据标准最佳实践审查 YAML 清单。 允许您使用 JSON Schema 创建自己的测试
基于 JSON Schema 的测试能力可能还不够

由于这些工具不依赖于对 Kubernetes 集群的访问,因此它们很容易安装。 它们允许您过滤源文件并向项目中拉取请求的作者提供快速反馈。

译者PS

另请阅读我们的博客:

来源: habr.com

添加评论