本文来自Rancher Labs

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

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

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

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

  • API验证器:这一类工具可以针对Kubernetes API服务器验证给定的YAML manifest。

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

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

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

  • 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/kubernetes-static-checkers-demo

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-score

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-score

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

Config-lint

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

https://stelligent.github.io/config-lint/#/install

在撰写本文时,最新的版本是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-oss/copper

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

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

https://github.com/cloud66-oss/copper#installation

与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-oss/copper/tree/master/libjs

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

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

https://github.com/cloud66-oss/copper

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

Conftest

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

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

https://www.conftest.dev/install/

与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/FairwindsOps/polaris

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

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

https://github.com/FairwindsOps/polaris/blob/master/docs/usage.md#cli

安装完成后,你可以使用以下命令针对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/kubernetes-static-checkers-demo/blob/master/base-valid-polaris-result.json

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

  • 缺少健康检查的pod。

  • 容器镜像没有指定标签。

  • 容器以root身份运行。

  • 没有设置CPU和内存请求和限制。

  • 每项检查都被划分为警告或危险的严重程度。

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

https://github.com/FairwindsOps/polaris/blob/master/docs/usage.md#checks

如果你对详细的结果不感兴趣,传递标志--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/kubernetes-static-checkers-demo/blob/master/polaris-configs/config_with_custom_check.yaml

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

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

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

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

https://github.com/FairwindsOps/polaris

总 结

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

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

验证Kubernetes YAML的最佳实践和策略的更多相关文章

  1. 在CentOS 7.6 以 kubeadm 安装 Kubernetes 1.15 最佳实践

    前言 Kubernetes作为容器编排工具,简化容器管理,提升工作效率而颇受青睐.很多新手部署Kubernetes由于"scientifically上网"问题举步维艰,本文以实战经 ...

  2. Kubernetes YAML最佳实践和策略

    Kubernetes工作负载最常用YAML格式的文件来定义. YAML的问题之一就是很难描述清单文件之间的约束或关系. 如果你希望检查是否已从受信任的注册表中提取部署到群集中的所有映像,该怎么办? 如 ...

  3. Kubernetes 微服务最佳实践

    本文由个人笔记 ryan4yin/knowledge 整理而来 本文主要介绍我个人在使用 Kubernetes 的过程中,总结出的一套「Kubernetes 配置」,是我个人的「最佳实践」. 其中大部 ...

  4. Kubernetes 服务部署最佳实践(二) ——如何提高服务可用性

    引言 上一篇文章我们围绕如何合理利用资源的主题做了一些最佳实践的分享,这一次我们就如何提高服务可用性的主题来展开探讨. 怎样提高我们部署服务的可用性呢?K8S 设计本身就考虑到了各种故障的可能性,并提 ...

  5. Kubernetes生产环境最佳实践

    点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 众所周知,Kubernetes很难! 以下是在生产中使用 ...

  6. Kubernetes 服务部署最佳实践(一) ——如何更好地设置 Request 与 Limit

    如何为容器配置 Request 与 Limit? 这是一个即常见又棘手的问题,这个根据服务类型,需求与场景的不同而不同,没有固定的答案,这里结合生产经验总结了一些最佳实践,可以作为参考. 所有容器都应 ...

  7. kubeadm安装Kubernetes 1.14最佳实践

    前言 Kubernetes作为容器编排工具,简化容器管理,提升工作效率而颇受青睐.很多新手部署Kubernetes由于“上网”问题举步维艰,本文以实战经验详解kubeadm不用“翻墙”部署Kubern ...

  8. forge k8s/kubernetes ci/cd 最佳实践

    forge的官网是: http://forge.sh forge工具是一个部署工具, 将你的应用自动更新到kubernets集群中, 只需要配置简洁的配置文件和模板即可. 其它的就交给forge, 它 ...

  9. Kubernetes集群的监控报警策略最佳实践

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/M2l0ZgSsVc7r69eFdTj/article/details/79652064 本文为Kub ...

随机推荐

  1. Flask 基础组件(七):蓝图

    1 蓝图资源 蓝图有自己的目录,它的所有资源都在其目录下.蓝图的资源目录是由创建Blueprint对象时传入的模块名”__name__”所在的位置决定的.同时,我们可以指定蓝图自己的模板目录和静态目录 ...

  2. 数据可视化之分析篇(五)如何使用Power BI计算新客户数量?

    https://zhuanlan.zhihu.com/p/65119988 每个企业的经营活动都是围绕着客户而开展的,在服务好老客户的同时,不断开拓新客户是每个企业的经营目标之一. 开拓新客户必然要付 ...

  3. Python 图像处理 OpenCV (14):图像金字塔

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  4. Video 自动播放

    先说ios ios之前的政策是视频只能在用户主动操作后才能播放,且播放时必须全屏. 随着 iOS 10 的正式发布,Safari 也迎来了大量更新,首先划出重点:1)iOS 10 Safari 支持特 ...

  5. 老司机带你玩转面试(3):Redis 高可用之主从模式

    前文回顾 建议前面文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 「老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩.击穿. ...

  6. “我放弃了年薪20W的offer......”

    我的职业生涯开始和大多数测试人一样,开始接触都是纯功能界面测试.那时候在一家电商公司做测试,做了有一段时间,熟悉产品的业务流程以及熟练测试工作流程规范之后,效率提高了,工作比较轻松,也得到了更好的机会 ...

  7. Cyber Security - Palo Alto Firewall Objects Addresses, Services, and Groups(2)

    Users Objects and Groups Creating local user objects. Creating local user groups. https://docs.paloa ...

  8. two types of friend

    两类朋友 第一类,普通朋友,并不能分享一些隐私的感情,只能说一些事情,有一些只是认识的人或者虽然认识很多年但是也只能是这样的! 第二类,关心你,可以交流感清,明显更加亲密一点. 不要对第一类朋友说第二 ...

  9. Python 实现图像快速傅里叶变换和离散余弦变换

    图像的正交变换在数字图像的处理与分析中起着很重要的作用,被广泛应用于图像增强.去噪.压缩编码等众多领域.本文手工实现了二维离散傅里叶变换和二维离散余弦变换算法,并在多个图像样本上进行测试,以探究二者的 ...

  10. 学会DevOps 能拿多少工资?DevOps 怎么自学?

    落地高薪!DevOps为何受宠? DevOps在近几年的发展势头可谓是迅猛无比,已经有越来越多的企业机构开始尝试落地,从国外的微软谷歌到国内的阿里腾讯,DevOps已经从时髦概念落地最佳实践,进而改变 ...