<!--StartFragment-->
## **前 言**
<!--EndFragment-->
<!--StartFragment-->
**[Amazon Elastic Kubernetes Service](https://aws.amazon.com/cn/eks/?trk=cndc-detail) ( [Amazon EKS](https://aws.amazon.com/cn/eks/?trk=cndc-detail) )** 是一项云上的托管 Kubernetes(K8S)****服务,使用该服务您可以轻松地在亚马逊云上部署、管理和扩展容器化的应用程序。
[Amazon EKS](https://aws.amazon.com/cn/eks/?trk=cndc-detail):
https\://aws.amazon.com/cn/eks/
在越来越多用户采用 [Amazon EKS](https://aws.amazon.com/cn/eks/?trk=cndc-detail) 集群部署运行容器应用时,随着使用的深入,大家会发现,或无意的配置错误,或恶意的容器注入,预期外的更改可能会被应用到集群中,这可能会中断集群的操作或破坏集群的完整性,一个典型的例子就是在集群中创建了不必要的特权容器造成了风险敞口。为了控制Pod安全,Kubernetes 提供了 **Pod 安全策略 (PSP)** 资源。PSP 指定一组安全设置,Pod 在集群中创建或更新之前必须满足这些设置。
Pod 安全策略 (PSP):
https\://kubernetes.io/docs/concepts/security/pod-security-policy/
<!--EndFragment-->
<!--StartFragment-->
但是,从 Kubernetes 1.21 版开始,PSP 已被弃用,并在 Kubernetes 1.25 版中被彻底删除。Kubernetes 项目**记录**了 PSP 被弃用的原因。简而言之,PSP 让大多数用户感到困惑。这种混乱导致了许多错误配置;使集群受到过度限制或过度宽松的设置而不受保护。所有这些问题都促使人们需要一种新的、更加用户友好和确定性的 Pod 安全解决方案。
记录:
https\://kubernetes.io/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/
在新的Kubernetes设计中,PSP 会被 **Pod 安全准入 (PSA) 取代**,这是一种内置准入控制器,可实现 **Pod 安全标准 (PSS)** 中概述的安全控制。PSA 和 PSS 在 Kubernetes 1.23 中都达到了 beta 状态,并在[Amazon EKS](https://aws.amazon.com/cn/eks/?trk=cndc-detail) 1.23版本中默认启用。除PSA和PSS以外,用户也可以通过开源社区的策略即代码(PaC)解决方案用以替换PSP。
<!--EndFragment-->
<!--StartFragment-->
Pod 安全准入 (PSA):
https\://kubernetes.io/docs/concepts/security/pod-security-admission/
Pod 安全标准 (PSS):
https\://kubernetes.io/docs/concepts/security/pod-security-standards/
<!--EndFragment-->
<!--StartFragment-->
PSS 作为一种原生的安全实践,它提供了一种简单但强大的安全准入控制,用户只需要进行简单的 annotation 配置即可让这些安全检查生效,防止规定外的资源进入集群。
但 PSS 也有其局限性,PSS 目前仅可以使用内置的3种级别的策略,无法自定义安全策略。企业在使用 EKS 的过程中,会逐渐形成各种规范,从容器的命名,标签,到资源中各种属性字段配置的最佳实践,以及根据企业合规安全方面要求禁止使用的用法等等,这些规范的会形成一组策略(Policy),用于集群控制资源的创建等方面的行为。
出于对控制的日益增长的需求,已经出现了策略即代码 (PaC) 解决方案来满足这些需求。在 Kubernetes 集群中强制执行行为并限制更改范围是客户面临的共同挑战, 使用策略来应用基于规则的 Kubernetes 资源控制是 的一种动态且公认 管理 Kubernetes 配置的方法。启用自动化的策略是 Kubernetes 管理上共同关心的问题。PaC 解决方案是启用 Kubernetes 集群并提供规定和自动化控制的最佳实践。
PaC 解决方案为组织提供了通过代码编写策略规则的能力。通过这种方法,组织可以重用 DevOps 和 GitOps 策略来管理和跨容器集群应用这些策略。
<!--EndFragment-->
<!--StartFragment-->
**什么是 Kyverno**
<!--EndFragment-->
<!--StartFragment-->
对于 Kubernetes,开源软件 (OSS)社区中提供了多种 PaC 解决方案,例如 OPA(Open Policy Agent),Kyverno 等。其中 OPA 是较成熟的策略引擎方案,但由于 OPA 的策略使用一种 **“Rego”** 语言,且不同于已知编程语言语法,虽然 OPA 在除 Kubernetes 外的多数领域都有着广泛应用,但仍然有一定的学习曲线。
Rego:
https\://www\.openpolicyagent.org/docs/latest/policy-language/
<!--EndFragment-->
<!--StartFragment-->
而 Kyverno 作为一种专用于 Kubernetes 的策略引擎,其最大的特点是其策略语言完全沿用 Kubernetes 的 manifest YAML 文件的写法,熟悉编写 Kubernetes YAML 的开发运维人员可快速上手编写所需的策略。因此,本文将使用 Kyverno 在 [Amazon EKS](https://aws.amazon.com/cn/eks/?trk=cndc-detail) 实施 PaC 进行探讨。
Kyverno 的原理是通过扩展 Kubernetes 的准入控制器(Admission Controller),进行动态准入控制,其流程可以简述为在 Kubernetes 的 Mutating 准入控制器和 Validating 准入控制器注入其自身的 webhook, 当资源的创建/更新请求进入准入控制器后,Kyverno 的 webhook 会收到准入控制器的 Admission Review 对象,然后通过 Kyverno 的控制器进行对应的处理并将处理结果返回给准入控制器
<!--EndFragment-->
<!--EndFragment-->
![image.png](https://dev-media.amazoncloud.cn/cca8eb16501445fdafc3c572cba59131_image.png "image.png")
<!--StartFragment-->
下面就让我们通过几个例子从实战中了解一下如何通过 Kyverno 实现策略即代码。
<!--EndFragment-->
<!--StartFragment-->
**工具安装**
<!--EndFragment-->
<!--StartFragment-->
eksctl:https\://eksctl.io/introduction/#installation
kubectl:https\://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html
helm:https\://helm.sh/docs/intro/install/
<!--EndFragment-->
<!--StartFragment-->
**部署 EKS 测试集群**
<!--EndFragment-->
<!--StartFragment-->
用户可以通过Amazon控制台界面或 CLI 工具 **eksctl** 对[Amazon EKS](https://aws.amazon.com/cn/eks/?trk=cndc-detail) 进行集群操作。本文下述测试将使用eksctl进行集群的创建/删除,同时基于 Kyverno 1.8.1 版本进行安装验证。
eksctl:https\://eksctl.io/
<!--EndFragment-->
<!--StartFragment-->
**01**
<!--EndFragment-->
<!--StartFragment-->
首先通过 eksctl CLI 创建一个用于测试的EKS集群,Kyverno 策略会影响资源创建的结果,请务必不要在生产环境中测试。
`eksctl create cluster --name eks-kyverno-test\\`
该命令会在 Amazon CLI 配置的默认的 Amazon region 中创建一个带2个 m5.large 节点的 EKS 集群,API 节点访问类型为 Public
<!--EndFragment-->
<!--StartFragment-->
**02**
<!--EndFragment-->
<!--StartFragment-->
通过 Helm 部署 Kyverno,在本文中,我们将通过 Helm 安装Kyverno, 安装Chart version 2.6.1,对应Kyverno version 1.8.1。
<!--EndFragment-->
<!--StartFragment-->
```
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm install kyverno kyverno/kyverno -n kyverno --version 2.6.1 --create-namespace --set replicaCount=1
```
<!--EndFragment-->
<!--StartFragment-->
如果在生产环境部署使用时,应将 replicaCount 设置至少为3以保证高可用
<!--EndFragment-->
<!--StartFragment-->
**03**
<!--EndFragment-->
<!--StartFragment-->
确认部署情况
正确部署后,Kyverno 应有2个 service 和1个 deployment 运行在 kyverno namespace 下
<!--StartFragment-->
<!--EndFragment-->
![image.png](https://dev-media.amazoncloud.cn/d0ddcb2b90144f169520f6036d3cf8fb_image.png "image.png")
同时观察 `validatingwebhookconfigurations` 和 `mutatingwebhookconfigurations` 资源,在未应用任何策略前,我们可以看到如下图所示,kyverno 的部分 webhook 已注册成功,随着 validate/mutate 策略的应用后,其对应的 resource webhook 也会随之进行注册。
<!--EndFragment-->
<!--EndFragment-->
![image.png](https://dev-media.amazoncloud.cn/da168012cecc4e87884b5aa97fce5d59_image.png "image.png")
<!--StartFragment-->
**Kyverno 策略模板**
<!--EndFragment-->
<!--StartFragment-->
Kyverno 的策略模板跟 Kubernetes 的 YAML 格式一致,这也是 Kyverno 的最大的特点,只要熟悉 Kubernetes 资源 YAML 的写法就能很快上手编写 Kyverno 策略。
Kyverno 的 YAML 结构分为以下几个部分:
– Policy 本身的属性,包含一组 Rule 的集合
– 每个 Rule 包含一个匹配/排除的资源
– 每个 Rule 包含一个行为模式(validate/generate/mutate/verify)
<!--EndFragment-->
<!--EndFragment-->
![image.png](https://dev-media.amazoncloud.cn/519b64aa2daa46c0aba2be46828671d1_image.png "image.png")
<!--StartFragment-->
我们接下来来看一下这些策略如何编写和应用。
<!--EndFragment-->
<!--StartFragment-->
**应用 Kyverno 策略**
<!--EndFragment-->
<!--StartFragment-->
Kyverno 支持多种策略,常见的有验证(validate),变更(mutate),生成(generate)以及更多的使用方式,在本文中将主要对这3种较常见的策略进行解读,其他策略的应用可参考 Kyverno 官方文档说明。
<!--EndFragment-->
<!--StartFragment-->
## **1 兼容 PSS 的策略**
<!--EndFragment-->
<!--StartFragment-->
Kyverno 提供了兼容 PSS 的策略模式,可通过 PSS 类似的方式快速应用预置的安全策略,建议在安装 Kyverno 后至少需要安装配置 baseline 的安全模式以保证集群的安全运行。
首先我们通过 helm 安装 Kyverno 提供的 PSS 策略。
` helm install kyverno-policies kyverno/kyverno-policies -n kyverno`
以上命令会部署默认 Baseline 组的策略,提供基础限制性的策略,禁止已知的策略提升。默认情况下,这些策略会被设置为 Audit 模式,在该模式下,不会真正的阻挡资源的创建,而是在 Policy Report(Kyverno的一种资源)中报告相关资源。关于 Kyverno 的 Policy Report 详见下文描述。我们可以配置不同的 helm value 来更改安装策略时的参数,例如对上面的命令增加下列参数,就会安装策略为 Restricted 组的策略并设置为 enforce (阻止)模式。更多的 helm 配置可参考其 kyverno policies charts 的 github 页面。以下示例仍以 baseline 以及 audit 模式进行演示。
`--set podSecurityStandard=restricted --set validationFailureAction=enforce`
我们测试在 baseline 策略下运行特权容器, 会发现集群并不会阻止 pod 的创建,但是对应 validate 失败的信息会反馈在 Kyverno 的 Policy Report 中。
<!--EndFragment-->
<!--StartFragment-->
```
cat > baseline-pod.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: baseline-pod-1
namespace: default
spec:
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'sleep 999']
securityContext:
privileged: true
EOF
kubectl apply -f baseline-pod.yaml
```
<!--StartFragment-->
执行完毕可以看到Pod可以正常创建在 default namespace 下。
<!--StartFragment-->
![image.png](https://dev-media.amazoncloud.cn/86e182694ab84b398a07a7219adec322_image.png "image.png")
运行 `kubectl get polr -A`,可看到 PSS 每个 Policy 对应一个 report,在特权容器检查项 `disallow-privileged-containers` 有一项 FAIL。
<!--EndFragment-->
<!--StartFragment-->
![image.png](https://dev-media.amazoncloud.cn/83a7f41cc3db449fbaa29408ce870c8a_image.png "image.png")
<!--StartFragment-->
用 `kubectl describe polr/cpol-disallow-privileged-containers `查看对应 Policy Report 的内容,可以看到其中详细描述了该 Pod 在 `disallow-privileged-containers` 策略检查时失败。
<!--EndFragment-->
<!--StartFragment-->
![image.png](https://dev-media.amazoncloud.cn/3e89fbb4f6214131b90b0ce840319338_image.png "image.png")
<!--StartFragment-->
通常在开始使用 Kyverno 时,我们可以安装上述策略并维持在 audit 模式以保证对集群无影响,当通过一段时间的运行并检查 Policy Report 的检查结果后,如果策略运行符合我们的预期,可以将策略配置为 `enforce` 模式,让其阻挡不符合要求的资源进入集群。
清理环境
` kubectl delete -f baseline-pod.yaml `
<!--EndFragment-->
<!--StartFragment-->
## **2 validate(验证)行为**
首先我们先部署一个 validate 行为的示例策略。
```
cat > cpol-pod-require-labels.yaml << EOF
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: pod-require-labels
annotations:
policies.kyverno.io/category: Compliance
policies.kyverno.io/description: Rules to enforce labels on Deployment and Pod resources
spec:
validationFailureAction: enforce
rules:
- name: pod-labels
match:
resources:
kinds:
- Pod
validate:
message: "labels app, owner, env are required"
pattern:
metadata:
labels:
app: "?*"
owner: "?*"
env: "?*"
EOF
kubectl apply -f cpol-pod-require-labels.yaml
```
<!--StartFragment-->
上面这个策略定义了:
– 策略模式为 `validationFailureAction: enforce`,当验证失败时,阻止资源在集群中创建
– 策略应用在所有的pod上,pod上的必须有 `app,owner, env` 3个label
将策略应用到集群中后我们可以通过` kubectl get cpol` 来查看策略是否已正确创建
<!--EndFragment-->
<!--StartFragment-->
![image.png](https://dev-media.amazoncloud.cn/e551303f20874588b3ac86bc67e16a03_image.png "image.png")
<!--StartFragment-->
接下来我们尝试创建一个不带任何 label 的 pod 到集群中
<!--EndFragment-->
<!--StartFragment-->
```
cat > pod-without-label.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: pod-without-label
namespace: default
spec:
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'sleep 999']
EOF
kubectl apply -f pod-without-label.yaml
```
<!--EndFragment-->
<!--StartFragment-->
我们可以看见执行 apply 时,会报错被策略阻挡,并给出了被哪条规则阻挡以及验证出错时的消息(定义在上述 Policy 中的 validate/message 字段)
<!--EndFragment-->
![image.png](https://dev-media.amazoncloud.cn/38e02a57211b4579a8e85bca24f16800_image.png "image.png")
<!--StartFragment-->
接下来我们新建一个带指定 label 的 pod,再次尝试创建
```
cat > pod-with-label.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: pod-with-label
namespace: default
labels:
app: test-app
owner: barry
env: test
spec:
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'sleep 999']
EOF
kubectl apply -f pod-with-label.yaml
```
<!--EndFragment-->
<!--StartFragment-->
这次我们可以看到 pod 可以成功创建了,这说明策略已正常生效
<!--EndFragment-->
<!--StartFragment-->
![image.png](https://dev-media.amazoncloud.cn/9f571cebc9364ff583acb27d4db9afdb_image.png "image.png")
<!--StartFragment-->
validate 策略是使用最多的策略,通过配置满足业务和合规上的要求,我们可以在资源创建到集群中之前记录(audit)或阻挡(enforce)其行为。例如,不满足 label 要求的资源不允许创建,或者指定 namespace 中的资源的 image 必须来自某个指定的 repo 前缀等等。
清理环境以避免上述应用的策略对后续测试产生影响
```
kubectl delete -f cpol-pod-require-labels.yaml
kubectl delete -f pod-with-label.yaml
```
<!--EndFragment-->
<!--StartFragment-->
## **3 mutate(变更)行为**
<!--EndFragment-->
<!--StartFragment-->
首先我们先创建一个 mutate 行为的示例策略
<!--EndFragment-->
<!--StartFragment-->
```
cat > cpol-set-image-pull.yaml << EOF
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: set-image-pull-policy
spec:
rules:
- name: set-image-pull-policy
match:
any:
- resources:
kinds:
- Pod
mutate:
patchStrategicMerge:
spec:
containers:
- (image): "*:latest"
imagePullPolicy: "IfNotPresent"
EOF
kubectl apply -f cpol-set-image-pull.yaml
```
<!--EndFragment-->
<!--StartFragment-->
这个策略定义了:
– 策略应用在所有pod上
– 匹配 `image` 使用“latest“结尾,将其 `imagePullPolicy` 修改为 `IfNotPresent` 。这里 (image) 是一种叫做 **Conditional Anchor**的特殊语法,它的作用时仅当 image 这个 tag 匹配它的值中声明的模式时,才会进行后续的动作,否则跳过
Conditional Anchor:
https\://kyverno.io/docs/writing-policies/mutate/#conditional-anchor
我们用一个测试 pod 来验证策略是否生效,下面这个测试 pod 的 `image` 的格式使用了 \*:latest 格式,但 `imagePullPolicy` 设置为了 `Never` 。假如镜像是未被拉取过的,在这个策略下就会因不主动拉取镜像而导致启动失败。我们来看看如何通过mutate行为来避免此类错误。
<!--EndFragment-->
<!--StartFragment-->
```
cat > pod-never-pull-image.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: pod-never-pull-image
namespace: default
spec:
containers:
- name: busybox
image: busybox:latest
imagePullPolicy: Never
command: ['sh', '-c', 'sleep 999']
EOF
kubectl apply -f pod-never-pull-image.yaml
```
<!--EndFragment-->
<!--StartFragment-->
Pod 成功创建后,我们查看一下这个Pod的详细信息,`kubectl get pod/pod-never-pull-image -o yaml` 可以看到其 `imagePullPolicy` 不再是之前声明的 `Never`,而是被策略修改为了` IfNotPresent`
<!--EndFragment-->
<!--EndFragment-->
![image.png](https://dev-media.amazoncloud.cn/7fe09e5f66084188918a3cfb0a8bba9e_image.png "image.png")
<!--StartFragment-->
接下来我们来看看 mutate 的另一种用法,mutate 不仅可以修改资源的配置,也可以增加配置项,例如下面这个示例就实现了一个类似容器注入的功能。
首先我们先编写策略并应用到集群中。
<!--EndFragment-->
```
cat > cpol-add-image.yaml << EOF
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: strategic-merge-patch
spec:
rules:
- name: add-image-policy
match:
any:
- resources:
kinds:
- Pod
mutate:
patchStrategicMerge:
metadata:
labels:
name: "{{request.object.metadata.name}}"
spec:
containers:
- name: "nginx"
image: "nginx:latest"
imagePullPolicy: "Never"
command:
- ls
EOF
kubectl apply -f cpol-add-image.yaml
```
<!--EndFragment-->
<!--StartFragment-->
这个策略定义了:
– 策略应用在所有 pod 上
– 对 Pod 增加一个叫 name 的 label,其值取自自身的name
– 在 Pod 中增加一个 nginx 的容器,由于这里我们将注入的 nginx 容器的镜像拉取策略设置为 Never,如果集群中没有 nginx 的 image 的话,这个 Pod 会运行失败,但并不影响我们验证 mutate 对 Pod 变更的结果。
接下来我们用下面的测试 Pod 来验证一下策略
<!--EndFragment-->
```
cat > pod-with-single-image.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: pod-with-single-image
namespace: default
spec:
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'sleep 999']
EOF
kubectl apply -f pod-with-single-image.yaml
```
<!--EndFragment-->
<!--StartFragment-->
当 Pod 成功创建后,我们观察一下 Pod 的详细信息,会发现 label 和容器都如预期一样添加到原 Pod 中了
<!--EndFragment-->
<!--EndFragment-->
![image.png](https://dev-media.amazoncloud.cn/e14c242fcfec4aab8c4d169e16766add_image.png "image.png")
![image.png](https://dev-media.amazoncloud.cn/867ed6cb814248c0869c188e7ea0215a_image.png "image.png")
<!--StartFragment-->
mutate 是一种很强大的工具,我们可以将一些常见的集群配置要求或最佳实践通过 mutate 配置到集群,例如镜像拉取策略,默认 label,注入容器等等,将这些工作变成集群的“默认”配置并自动应用到匹配的资源上。对于这类可以用“默认”行为处理的场景,mutate 是很好的选择。同时 mutating admission 发生在 validating admission 之前的阶段,所以资源是以 mutate 后再进行 validate,并不会因为 mutate 导致逃逸 validate 的检查。
<!--EndFragment-->
<!--StartFragment-->
<!--EndFragment-->
![image.png](https://dev-media.amazoncloud.cn/6579335b585b469faf1fa2aeb1ce3fd5_image.png "image.png")
<!--StartFragment-->
但必须强调的是,mutate 也是一把双刃剑,因为对原资源进行修改是可能发生副作用的,比如修改了错误的字段,或将同名的镜像错误更新,又或者是更新导致后续validate阶段无法通过等等,都可能影响应用的正常使用,因此,在使用 mutate 策略时,务必要了解 mutate 的行为模式以及进行充分测试。
清理环境以避免上述应用的策略对后续测试产生影响
<!--EndFragment-->
<!--StartFragment-->
```
kubectl delete -f cpol-add-image.yaml
kubectl delete -f cpol-set-image-pull.yaml
kubectl delete -f pod-never-pull-image.yaml
kubectl delete -f pod-with-single-image.yaml
```
<!--EndFragment-->
<!--StartFragment-->
## **4 generate(生成)行为**
<!--EndFragment-->
<!--StartFragment-->
generate 策略与 mutate 策略不同的地方是,mutate策略是修改准入集群的资源本身,比如创建一个Pod时,mutate 的应用范围只会在这个 pod 本身。而generate 策略是根据准入集群的资源,创建出额外的Kubernetes 资源。
下面这个示例,我们会看到通过一个 generate 策略,在创建一个新的 namespace 时,额外在其中生成一个 ConfigMap。
首先我们编写一个 generate 策略并应用到集群中
<!--EndFragment-->
```
cat > cpol-gen-cm.yaml << EOF
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: gen-default-cm
spec:
rules:
- name: generate ConfigMap
match:
any:
- resources:
kinds:
- Namespace
exclude:
any:
- resources:
namespaces:
- kube-system
- default
- kube-public
- kyverno
generate:
synchronize: true
apiVersion: v1
kind: ConfigMap
name: test-cm
namespace: "{{request.object.metadata.name}}"
data:
kind: ConfigMap
metadata:
labels:
somekey: somevalue
data:
KEY1: "Value1"
KEY2: "Value2"
EOF
kubectl apply -f cpol-gen-cm.yaml
```
<!--EndFragment-->
<!--StartFragment-->
这个策略定义了:
– 应用在 namespace 资源上,但排除 kube-system , default , kube-public , kyverno 这几个 namesapce
– 创建一个新的叫 test-cm 的 configmap,并置于请求创建的同名 namespace 中
– 这个 ConfigMap 带有默认的预设值
接下来我们创建一个叫 test-ns-1的namespace,创建后我们可以看到在这个 namespace 下已经出现了一个 test-cm 的 ConfigMap
<!--EndFragment-->
<!--StartFragment-->
![image.png](https://dev-media.amazoncloud.cn/81f843b38ab24532b5afcb09955d6087_image.png "image.png")
<!--StartFragment-->
查看这个 ConfigMap,我们可以看到它的 label 和预设的值都如预期在策略中定义的一样。
<!--EndFragment-->
<!--EndFragment-->
![image.png](https://dev-media.amazoncloud.cn/954352a67b2d4a95a84ff763e6d7d9a9_image.png "image.png")
<!--StartFragment-->
generate 策略通常会用于集群环境配置上,例如当新建资源时,创建一些支撑性的资源,或者是创建默认的 NetworkPolicy, RoleBinding 等访问控制相关资源。
常见的例子如在多租户的 EKS 集群中,创建租户的 namespace 时一并创建对象 RBAC 等访问控制资源。通过将此类行为编写为策略,可减少人工操作的负担和避免遗漏。generate 也可以复制已有的资源来产生新的资源,限于篇幅,此处不再展开。
<!--EndFragment-->
<!--StartFragment-->
**清理环境**
<!--EndFragment-->
<!--StartFragment-->
通过 Amazon 控制台或 eksctl 命令删除该测试 EKS 集群以清理环境,避免产生额外的费用。
`eksctl delete cluster --name eks-kyverno-test`
<!--EndFragment-->
<!--StartFragment-->
### **总 结**
<!--EndFragment-->
<!--StartFragment-->
通过上面几个简单的例子,我们可以快速了解到 Kyverno 是什么,能做什么。但限于篇幅,无法对 Kyverno 所有的功能进行介绍,有兴趣的读者可以参考 Kyverno 官方文档进行深入阅读。
除此之外,Kyverno 也提供了 **CLI 工具**,以协助用户在 Policy 部署到集群前进行验证以避免预期外的效果。
CLI 工具:
https\://kyverno.io/docs/kyverno-cli/
<!--EndFragment-->
<!--StartFragment-->
策略即代码解决方案提供了自动防护机制,既可以启用用户又可以防止不需要的行为。选择正确的策略即代码解决方案并非易事,Kyverno 解决方案亦并非唯一选择,组织在做出正确选择时必须从多个因素进行考虑, 根据测试和概念验证的结果选择合适企业自身的策略即代码方案。
无论选择哪种解决方案,策略即代码正在成为 DevOps 和纵深防御策略的基础组成部分。
<!--EndFragment-->
<!--StartFragment-->
**参 考 链 接**
<!--EndFragment-->
<!--StartFragment-->
- Kyverno文档 :https\://kyverno.io/docs/
- Kyverno Policy库 :https\://kyverno.io/policies/
- Kyverno Policy on [Amazon EKS](https://aws.amazon.com/cn/eks/?trk=cndc-detail)示例 :https\://github.com/aws/aws-eks-best-practices/tree/master/policies/kyverno
<!--EndFragment-->
<!--StartFragment-->
**本篇作者**
![image.png](https://dev-media.amazoncloud.cn/5855fe7f91cd413182c0a06537ff0117_image.png "image.png")
<!--StartFragment-->
**王冰**
*亚马逊云科技金融行业解决方案架构师, 主要负责企业客户上云,帮助客户进行云架构设计和技术咨询,专注于容器、数据库等技术方向。*
<!--EndFragment-->