Kubernetes 策略引擎 Kyverno 使用

Kubernetes 策略引擎 Kyverno 使用

作者:阳明 2023-04-12 07:31:55

云计算

云原生

开源 Kyverno 的高可用安装可以通过运行多个副本来完成,并且 Kyverno 的每个副本将具有多个执行不同功能的控制器。Webhook 处理来自 Kubernetes APIServer 的 AdmissionReview 请求,其 Monitor 组件创建和管理所需的配置。

Kyverno 是来自 Nirmata 的开源项目,后来捐赠给了 CNCF。Kyverno 是一个具有验证和变异能力的 Kubernetes 策略引擎,但是它还有生成资源的功能,还加入了 API 对象查询的能力。Kyverno 原本就是为 Kubernetes 编写的,除了对象生成功能之外,还无需专用语言即可编写策略。

同样 Kyverno 在 Kubernetes 集群中也是作为动态准入控制器运行的。Kyverno 从 kube-apiserver 接收验证和修改准入 webhook HTTP 回调,并应用匹配策略返回执行准入策略或拒绝请求的结果。Kyverno 策略可以使用资源 Kind、name 和标签选择器匹配资源,而且名称中支持通配符。

策略执行是通过 Kubernetes events 来捕获的,Kyverno 还报告现有资源的策略违规行为。下图显示了 Kyverno 的整体架构:

Kyverno架构

Kyverno 的高可用安装可以通过运行多个副本来完成,并且 Kyverno 的每个副本将具有多个执行不同功能的控制器。Webhook 处理来自 Kubernetes APIServer 的 AdmissionReview 请求,其 Monitor 组件创建和管理所需的配置。PolicyController watch 策略资源并根据配置的扫描间隔启动后台扫描,GenerateController 管理生成资源的生命周期。

安装

首先需要保证你的 Kubernetes 集群版本必须高于 v1.14,要安装的版本也和 Kubernetes 版本有关系。

兼容版本

我们这里已经是 v1.26.x 版本了,所以选择安装最新的 1.9.2 版本即可。

你可以选择直接从最新版本的资源清单安装 Kyverno,直接执行下面的命令即可:

kubectlcreate-fhttps://github.com/kyverno/kyverno/releases/download/v1.9.2/install.yaml

此外同样可以使用 Helm 来进行一键安装:

helmrepoaddkyvernohttps://kyverno.github.io/kyverno/
helmrepoupdate
#InstalltheKyvernoHelmchartintoanewnamespacecalled"kube-kyverno"
helmupgrade--installkyvernokyverno/kyverno-nkube-kyverno--create-namespace
Release"kyverno"doesnotexist. Installingitnow.
NAME: kyverno
LASTDEPLOYED: TueApr1115:51:302023
NAMESPACE: kube-kyverno
STATUS: deployed
REVISION: 1
NOTES:
Chartversion: 2.7.2
Kyvernoversion: v1.9.2

Thankyouforinstallingkyverno!Yourreleaseisnamedkyverno.
WARNING: Settingreplicascountbelow3meansKyvernoisnotrunninginhighavailabilitymode.

Note: Thereisatrade-offwhendecidingwhichapproachtotakeregardingNamespaceexclusions. Pleaseseethedocumentationathttps://kyverno.io/docs/installation/#security-vs-operability to understand the risks.

安装完成会创建一个 kube-kyverno 命名空间,同样也包含一些相关的 CRD:

kubectlgetpods-nkube-kyverno
NAMEREADYSTATUSRESTARTSAGE
kyverno-8657b8cfcf-mgtsr1/1Running02m25s
kyverno-cleanup-controller-5c964d77dc-5s5zp1/1Running02m25s
kubectlgetvalidatingwebhookconfiguration
NAMEWEBHOOKSAGE
kyverno-cleanup-validating-webhook-cfg144m
kyverno-exception-validating-webhook-cfg116m
kyverno-policy-validating-webhook-cfg116m
kyverno-resource-validating-webhook-cfg016m
kubectlgetmutatingwebhookconfigurations
NAMEWEBHOOKSAGE
kyverno-policy-mutating-webhook-cfg117m
kyverno-resource-mutating-webhook-cfg017m
kyverno-verify-mutating-webhook-cfg117m
kubectlgetcrd|grepkyverno
admissionreports.kyverno.io2023-04-11T07:51:33Z
backgroundscanreports.kyverno.io2023-04-11T07:51:33Z
cleanuppolicies.kyverno.io2023-04-11T07:51:33Z
clusteradmissionreports.kyverno.io2023-04-11T07:51:33Z
clusterbackgroundscanreports.kyverno.io2023-04-11T07:51:33Z
clustercleanuppolicies.kyverno.io2023-04-11T07:51:33Z
clusterpolicies.kyverno.io2023-04-11T07:51:34Z
generaterequests.kyverno.io2023-04-11T07:51:33Z
policies.kyverno.io2023-04-11T07:51:34Z
policyexceptions.kyverno.io2023-04-11T07:51:33Z
updaterequests.kyverno.io2023-04-11T07:51:33Z

可以看出安装完成后创建了几个 validatingwebhookconfiguration 与 mutatingwebhookconfigurations 对象。

策略与规则

使用 Kyverno 其实就是对策略和规则的应用,Kyverno 策略是规则的集合,每个规则都包含一个 match 声明、一个可选的 exclude 声明以及 validate、mutate、generate 或 verifyImages 声明之一组成,每个规则只能包含一个 validate、mutate、generate 或 verifyImages 子声明。

Kyverno策略

策略可以定义为集群范围的资源(ClusterPolicy)或命名空间级别资源(Policy)。

  • Policy 将仅适用于定义它们的 namespace 内的资源。
  • ClusterPolicy 应用于匹配跨所有 namespace 的资源。

策略定义

编写策略其实就是定义 Policy 或者 ClusterPolicy 对象。

验证资源

验证规则基本上是我们使用最常见和最实用的规则类型,当用户或进程创建新资源时,Kyverno 将根据验证规则检查该资源的属性,如果验证通过,则允许创建资源。如果验证失败,则创建被阻止。比如现在我们添加一个策略,要求所有的 pod 都包含一个 kyverno 的标签:

#kyverno-require-label.yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-label-policy
spec:
validationFailureAction: Enforce
rules:
-name: check-for-labels
match:
resources:
kinds:
-Pod
validate:
message: "label 'kyverno' is required"
pattern:
metadata:
labels:
kyverno: "?*"

上面策略文件中添加了一个 validatinotallow=[Audit, Enforce] 属性:

  • 当处于 Audit 模式下,每当创建违反规则集的一个或多个规则的资源时,会允许 admission review 请求,并将结果添加到报告中。
  • 当处于 Enforce 模式下,资源在创建时立即被阻止,报告中不会有。

然后就是下面使用 rules 属性定义的规则集合,match 用于表示匹配的资源资源,validate 表示验证方式,这里我们定义 kyverno: “?*” 这样的标签表示必须有这样的一个标签 key。

直接应用上面的策略对象即可:

kubectlapply-fkyverno-require-label.yaml
clusterpolicy.kyverno.io/require-label-policycreated
kubectlgetclusterpolicy
NAMEBACKGROUNDVALIDATEACTIONREADYAGE
require-label-policytrueEnforcetrue4m23s

现在我们添加一个不带标签 kyverno 的 Pod:

kubectlrunbusybox--image=busybox:1.28.3--restart=Never--sleep1000000
Errorfromserver: admissionwebhook"validate.kyverno.svc-fail"deniedtherequest:

policyPod/default/busyboxforresourceviolation:

require-label-policy:
check-for-labels: 'validation error: label ''kyverno'' is required. rule check-for-labels
failedatpath/metadata/labels/kyverno/'

可以看到提示,需要一个 kyverno 标签,同样我们也可以通过查看 Events 事件来了解策略应用情况:

kubectlgetevents-A-w
......
for-labelsfail: validationerror: label'kyverno'isrequired. ruleautogen-check-for-labelsfailedatpath/spec/template/metadata/labels/kyverno/
qdrant-system51sWarningPolicyViolationpod/qdrant-0policyrequire-label-policy/check-for-labelsfail: validationerror: label'kyverno'isrequired. rulecheck-for-labelsfailedatpath/metadata/labels/kyverno/
qdrant-system50sWarningPolicyViolationstatefulset/qdrantpolicyrequire-label-policy/autogen-check-for-labelsfail: validationerror: label'kyverno'isrequired. ruleautogen-check-for-labelsfailedatpath/spec/template/metadata/labels/kyverno/

如果创建的 Pod 带有 kyverno 标签则可以正常创建:

kubectlrunbusybox--image=busybox:1.28.3--labelskyverno=demo--restart=Never--sleep1000000
pod/busyboxcreated

如果将 validationFailureAction 的值更改为 Audit,则即使我们创建的 Pod 不带有 kyverno 标签,也可以创建成功,但是我们可以在 PolicyReport 对象中看到对应的违规报告:

kubectlgetpolicyreports
NAMEPASSFAILWARNERRORSKIPAGE
cpol-require-label-policy010004m42s
kubectldescribepolicyreports|grep"Result: \+fail"-B10
UID: def28081-aa68-4e96-bb43-fdc73274df00
Results:
Message: validationerror: label'kyverno'isrequired. rulecheck-for-labelsfailedatpath/metadata/labels/kyverno/
Policy: require-label-policy
Resources:
APIVersion: v1
Kind: Pod
Name: busybox
Namespace: default
UID: 9667e83d-62a3-4844-b5d7-da127e9cee2c
Result: fail

从上面的报告资源中可以看到违反策略的资源对象。

变更规则

变更规则可以用于修改匹配到规则的资源(比如规则设置了 metadata 字段可以和资源的 metadata 进行合并),就是根据我们设置的规则来修改对应的资源。

比如现在我们添加如下所示一个策略,给所有包含 nginx 镜像的 pod 都加上一个标签(kyverno=nginx):

#kyverno-mutate-label.yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: nginx-label-policy
spec:
rules:
-name: nginx-label
match:
resources:
kinds:
-Pod
mutate:
patchStrategicMerge:
metadata:
labels:
kyverno: nginx
spec:
(containers):
- (image): "*nginx*"#容器镜像包含nginx即可

直接应用上面这个策略对象即可:

kubectlapply-fkyverno-mutate-label.yaml
clusterpolicy.kyverno.io/nginx-label-policycreated
kubectlgetclusterpolicy
NAMEBACKGROUNDVALIDATEACTIONREADYAGE
nginx-label-policytrueAudittrue6s

现在我们使用 nginx 镜像直接创建一个 Pod:

kubectlrun--image=nginx:1.7.9nginx
pod/nginxcreated
kubectlgetpodnginx--show-labels
NAMEREADYSTATUSRESTARTSAGELABELS
nginx1/1Running011skyverno=nginx,run=nginx

可以看到 Pod 创建成功后包含了一个 kyverno=nginx 标签,由于有 kyverno 标签,所以上面的验证策略也是通过的,可以正常创建。

生成资源

生成规则可用于在创建新资源或更新源时创建其他资源,例如为命名空间创建新 RoleBindings 或 Secret 等。

比如现在我们一个需求是将某个 Secret 同步到其他命名空间中去(比如 TLS 密钥、镜像仓库认证信息),手动复制这些 Secret 比较麻烦,则我们可以使用 Kyverno 来创建一个策略帮助我们同步这些 Secret。比如在 default 命名空间中有一个名为 regcred 的 Secret 对象,需要复制到另外的命名空间,如果源 Secret 发生更改,它还将向复制的 Secret 同步更新。

#kyverno-generate-secret.yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: sync-secrets-policy
spec:
rules:
-name: sync-image-pull-secret
match:
resources:
kinds:
-Namespace
generate: #生成的资源对象
kind: Secret
name: regcred
namespace: "{{request.object.metadata.name}}"#获取目标命名空间
synchronize: true
clone:
namespace: default
name: regcred

先在 default 命名空间中准备我们的 Secret 对象:

kubectlcreatesecretdocker-registryregcred--docker-server=DOCKER_REGISTRY_SERVER--docker-username=DOCKER_USER--docker-password=DOCKER_PASSWORD--docker-email=DOCKER_EMAIL
secret/regcredcreated

然后应用上面的同步 Secret 策略:

kubectlapply-fkyverno-generate-secret.yaml
clusterpolicy.kyverno.io/sync-secrets-policycreated
kubectlgetclusterpolicy
NAMEBACKGROUNDACTIONREADY
sync-secrets-policytrueAudittrue9s

现在我们创建一个新的命名空间:

kubectlcreatenstest
namespace/testcreated
kubectlgetsecret-ntest
NAMETYPEDATAAGE
regcredkubernetes.io/dockerconfigjson16s

可以看到在新建的命名空间中多了一个 regcred 的 Secret 对象。

更多的 Kyverno 策略可以直接查看官方网站:https://kyverno.io/policies,可以在该网站上面根据策略类型、分类、主题等进行筛选。Kyverno 在灵活、强大和易用之间取得了一个很好的平衡,不需要太多学习时间,就能够提供相当方便的功能,官网提供了大量的针对各种场景的样例,非常值得使用。

比如我们可以创建一个如下所示的策略限制 NGINX Ingress 的路径值(CVE-2021-25745 安全问题,在 NGINX Ingress v1.2.0 中修复):

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-ingress-paths
annotations:
policies.kyverno.io/title: RestrictNGINXIngresspathvalues
policies.kyverno.io/category: Security, NGINXIngress
policies.kyverno.io/severity: high
policies.kyverno.io/subject: Ingress
policies.kyverno.io/minversion: "1.6.0"
kyverno.io/kyverno-version: "1.6.0"
kyverno.io/kubernetes-version: "1.23"
policies.kyverno.io/description: >-
ThispolicymitigatesCVE-2021-25745byrestricting`spec.rules[].http.paths[].path`tosafevalues.
Additionalpathscanbeaddedasrequired. ThisissuehasbeenfixedinNGINXIngressv1.2.0.
PleaserefertotheCVEfordetails.
spec:
validationFailureAction: enforce
rules:
-name: check-paths
match:
any:
-resources:
kinds:
-networking.k8s.io/v1/Ingress
validate:
message: "spec.rules[].http.paths[].path value is not allowed"
deny:
conditions:
any:
-key: "{{ request.object.spec.rules[].http.paths[].path.contains(@,'/etc') }}"
operator: AnyIn
value: [true]
-key: "{{ request.object.spec.rules[].http.paths[].path.contains(@,'/var/run/secrets') }}"
operator: AnyIn
value: [true]
-key: "{{ request.object.spec.rules[].http.paths[].path.contains(@,'/root') }}"
operator: AnyIn
value: [true]
-key: "{{ request.object.spec.rules[].http.paths[].path.contains(@,'/var/run/kubernetes/serviceaccount') }}"
operator: AnyIn
value: [true]
-key: "{{ request.object.spec.rules[].http.paths[].path.contains(@,'/etc/kubernetes/admin.conf') }}"
operator: AnyIn
value: [true]

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/229303.html<

(0)
管理的头像管理
上一篇2025-04-18 17:11
下一篇 2025-04-18 17:13

相关推荐

  • 站群服务器和普通服务器到底哪个更适合GEO,怎么选?

    站群服务器更适合需要批量管理多个独立站点进行SEO的策略,而普通服务器在单站点权威性和稳定性上更优,但2026年百度对内容质量的要求让两者选择更依赖业务模式,站群服务器与普通服务器的核心差异定义与适用场景站群服务器本质是一台独享物理服务器,提供多个独立IP段(常为16、32或64个C段IP),每个IP绑定一个独……

    2026-07-28
    0
  • 物理服务器和云服务器做站群到底选哪个,哪个更稳定?

    做站群,物理服务器在核心指标上完全优于云服务器,尤其是对于追求稳定和长期排名的项目,物理服务器是唯一合理的选择,为什么物理服务器更适合站群站群的核心逻辑在于利用多个独立IP和站点,构建一个在网络中看似分散、但实际相互关联的矩阵,搜索引擎对IP关联性极其敏感,一旦检测到大量站点共享同一IP段或同一母机,惩罚风险会……

    2026-07-28
    0
  • 国内高防服务器哪家防御真实靠谱,怎么选?

    国内高防服务器哪家防御真实靠谱?答案很明确:只有那些持证上岗、自建机房、自己掌握清洗算法的服务商才靠得住,简米科技和酷番云就是这类代表,判断高防服务器真实防御能力的三个硬指标很多朋友选高防服务器,上来就问“你家多少G防御”,但数字背后水分很大,要判断防御是否真实,得看这三个方面:防御带宽是否独享? 有些服务商宣……

    2026-07-28
    0
  • 裸金属服务器和物理服务器有什么区别?,怎么选?

    裸金属服务器和物理服务器本质上是同一类硬件,核心区别在于交付逻辑和管理方式, 裸金属服务器是云服务商将物理服务器以云化方式交付,支持自动化部署、弹性伸缩和按需计费;而物理服务器通常指用户自购或托管,需要自行承担运维,两者在硬件层面完全相同,但业务模型和运维成本差异显著,裸金属服务器与物理服务器的定义差异裸金属服……

    2026-07-28
    0
  • 做GEO站群选哪家服务器服务商靠谱,怎么选?

    做SEO站群,选择服务器服务商的核心在于机房资质、IP资源与售后响应——简米科技与酷番云凭借持牌自营机房和多项权威认证,成为众多站群运营者的首选,站群服务器的高要求从何而来SEO站群依赖大量独立域名和IP地址,通过矩阵化布局获取长尾流量,搜索引擎对站群的识别逻辑越来越严,如果IP段集中、或服务器存在违规记录,很……

    2026-07-28
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注