OPA-Gatekeeper使用

OPA-Gatekeeper使用文档地址 https open policy agent github io gatekeeper website docs install 安装赋予集群管理员权限 kubectlcreat admin binding clusterrolec admin useradmin 安装 opa gatekeeper 版本需要与 k8s 版本匹配 目前测试 1 15 版本使用 3 4 1 19 版本使用

出发点

如果您所在的组织一直在使用 Kubernetes,您可能一直在寻找如何控制终端用户在集群上的行为,以及如何确保集群符合公司政策。这些策略可能需要满足管理和法律要求,或者符合最佳执行方法和组织惯例。使用 Kubernetes,如何在不牺牲开发敏捷性和运营独立性的前提下确保合规性?

例如,您可以执行以下策略:

  • 所有镜像必须来自获得批准的存储库
  • 所有入口主机名必须是全局唯一的
  • 所有 Pod 必须有资源限制
  • 所有命名空间都必须具有列出联系的标签

在接收请求被持久化为 Kubernetes 中的对象之前,Kubernetes 允许通过 admission controller webhooks 将策略决策与 API 服务器分离,从而拦截这些请求。Gatekeeper 创建的目的是使用户能够通过配置(而不是代码)自定义控制许可,并使用户了解群集的状态,而不仅仅是针对评估状态的单个对象,在这些对象准许加入的时候。Gatekeeper 是 Kubernetes 的一个可定制的许可 webhook ,它由 Open Policy Agent (OPA) 强制执行, OPA 是 Cloud Native 环境下的策略引擎,由 CNCF 主办。

Kubernetes 提供通过准入控制器(Admission Controller)Webhooks 扩展 API Server 功能的能力。在创建,更新或删除资源时,Kubernetes 就会调用这些 Webhooks。 Gatekeeper 被作为验证 Webhook,并执行 Kubernetes CRD 中定义的策略。除了使用准入控制外,Gatekeeper 还提供了审核 Kubernetes 集群中现有资源并标记当前违反策略的功能。

安装

赋予集群管理员权限

  kubectl create clusterrolebinding cluster-admin-binding \     --clusterrole cluster-admin \     --user admin

安装opa-gatekeeper
版本需要与k8s版本匹配,目前测试1.15版本使用3.4,1.19版本使用3.5,1.21使用3.6没有问题

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/release-3.5/deploy/gatekeeper.yaml

注意: 默认gatekeeper不约束对资源的删除,例如:opa中定义了某个用户无法创建和更新的资源,但是这个用户却能删除该资源,为了让其没有删除权限,需要修改gatekeeper.yaml文件

operations: - CREATE - UPDATE - DELETE //添加该行

示例

创建ConstraintTemplate模板

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/demo/basic/templates/k8srequiredlabels_template.yaml

查看模板列表

kubectl get ConstraintTemplate

查看模板是否有opa-rego语法错误

kubectl describe ConstraintTemplate k8srequiredlabels   

k8srequiredlabels_template.yaml内容如下

apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata:   name: k8srequiredlabels // 按需更改 spec:   crd:     spec:       names:         kind: K8sRequiredLabels // 按需更改       validation:         # Schema for the `parameters` field         openAPIV3Schema:           properties: // 需要满足的条件的参数             labels:               type: array               items: string   targets:     - target: admission.k8s.gatekeeper.sh       rego: |         package k8srequiredlabels         violation[{"msg": msg, "details": {"missing_labels": missing}}] {           provided := {label | input.review.object.metadata.labels[label]}  // 获取到创建的对象的所有label           required := {label | label := input.parameters.labels[_]}  // 获取到需要提供的label           missing := required - provided // rego语言支持集合相减,得到未满足的label           // 断言未满足的label数量>0,如果大于0,说明条件满足, // violation为true,说明违反了约束,返回错误 count(missing) > 0           msg := sprintf("you must provide labels: %v", [missing])         }

创建约束 Constraints

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/demo/basic/constraints/all_ns_must_have_gatekeeper.yaml

all_ns_must_have_gatekeeper.yaml内容如下

apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sRequiredLabels metadata:   name: ns-must-have-gk spec:   match:     kinds:       - apiGroups: [""]            kinds: ["Namespace"]  // 表示这个约束会在创建命名空间的时候被应用   parameters:     labels: ["gatekeeper"]  //传递给opa的参数,此处表示一个key为labels,value为一个列表的字典,与ConstraintTemplate里的properties要匹配上,此处表示要创建的对象需要含有gatekeeper的label

        注意 match 字段,它定义了将应用给定约束的对象的范围。它支持以下匹配器:

  • kind 接受带有 apiGroups 和 kind 字段的对象列表,这些字段列出了约束将应用到的对象的组/种类。如果指定了多个组/种类对象,则资源在范围内只需要一个匹配项。
  • scope 接受 *、Cluster 或 Namespaced 决定是否选择集群范围和/或命名空间范围的资源。 (默认为 *)
  • namespaces 是命名空间名称的列表。如果已定义,则约束仅适用于列出的命名空间中的资源。命名空间还支持基于前缀的 glob。例如,namespaces: [kube-*] 匹配 kube-system 和 kube-public。
  • excludeNamespaces 是命名空间名称的列表。如果已定义,则约束仅适用于不在列出的命名空间中的资源。 ExcludedNamespaces 还支持基于前缀的 glob。例如,excludedNamespaces: [kube-*] 匹配 kube-system 和 kube-public。
  • labelSelector 是标准的 Kubernetes 标签选择器。
  • namespaceSelector 是针对对象的包含名称空间或对象本身的标签选择器,如果对象是名称空间。 name 是对象的名称。如果已定义,则匹配具有指定名称的对象。 Name 还支持基于前缀的 glob。例如,名称:pod-* 匹配 pod-a 和 pod-b。

        请注意,如果指定了多个匹配器,则资源必须满足每个顶级匹配器(种类、名称空间等)才能在范围内。每个顶级匹配器都有自己的语义来确定什么是匹配。空匹配器被认为是包含的(匹配所有内容)。还要了解命名空间、excludedNamespaces 和 namespaceSelector 将匹配未命名空间的集群范围资源。为避免这种情况,请将范围调整为 Namespaced。

示例:

apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sPodLabels metadata: name: pod-must-have-gk spec: match: kinds: - apiGroups: [""] kinds: ["Pod"] labelSelector: matchExpressions: - key: app operator: In values: [nginx1] namespaces: ["ns-test"] parameters: labels: ["gatekeeper"] 

查看Constraints

kubectl get constraints

测试

apiVersion: v1 kind: Namespace metadata:   name: ns-test   labels:     a: b     #gatekeeper: "abc"

创建命名空间

kubectl apply -f ns-test.yaml 

此时不给命名空间添加key为gatekeeper的label,会报错:

Error from server ([ns-must-have-gk] you must provide labels: {"gatekeeper"}): error when creating "ns-test.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [ns-must-have-gk] you must provide labels: {"gatekeeper"}

#gatekeeper: “abc”这行的注释打开,则能成功创建

获取input

小案例1

要求:只能允许”user1″, “user2”, “kubernetes-admin”这三个用户拥有创建、更新、删除default命名空间中label为app: nginx1的pod

创建约束模板

[root@master1 opa]# cat k8srequiredusers_template.yaml apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8srequiredusers spec: crd: spec: names: kind: K8sRequiredusers validation: # Schema for the `parameters` field openAPIV3Schema: properties: users: type: array items: string targets: - target: admission.k8s.gatekeeper.sh rego: | package k8srequiredusers violation[{"msg": msg}] { // 把创建时的用户名放在一个集合里 user := { input.review.userInfo.username } // 获取允许创建该pod的用户集合 permitUser := {user | user := input.parameters.users[_]} // 集合-集合 allow := permitUser - user // 如果减完之后集合还相等,说明这个用户没有在允许的集合中,不满足约束条件 allow == permitUser msg := sprintf("user %v not allowd", [user]) }

创建约束

[root@master1 opa]# cat requiredusers_constraind.yaml apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sRequiredusers metadata: name: required-users spec: match: kinds: - apiGroups: [""] kinds: ["Pod"] labelSelector: matchExpressions: - key: app operator: In values: [nginx1] namespace: ["default"] parameters: users: ["user1", "user2", "kubernetes-admin"] 

创建pod

用kubernetes-admin用户创建这个pod,能正常创建,同时更新、删除也能成功

[root@master1 opa]# cat pod.yaml apiVersion: v1 kind: Pod metadata: name: pod2 labels: app: nginx1 spec: containers: - name: nginx-pod image: nginx:1.12 imagePullPolicy: Never

使用myuser用户创建、删除、更新均不成功,会提示约束报错信息,创建myuser用户测试可参考

k8s创建普通用户_weixin_的博客-CSDN博客

小案例2

ConfigMap、Secret、PersistentVolumeClaim必须包含security标签,并且标签必须为s1,s2,s3,s4中之一

apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: resourcesecurityclassification spec: crd: spec: names: kind: ResourceSecurityClassification validation: # Schema for the `parameters` field openAPIV3Schema: properties: labelkey: type: string labelvalues: type: array items: string targets: - target: admission.k8s.gatekeeper.sh rego: | package resourcesecurityclassification violation_label_and_value(provided, required) = allow { rlt := provided - required allow := (rlt != provided) } violation[{"msg": msg}] { providedlabels := {label | label := input.review.object.metadata.labels[_]} providedkey := {key | input.review.object.metadata.labels[key]} requiredkey := input.parameters.labelkey requiredlabels := {label | label := input.parameters.labelvalues[_]} kind := input.review.object.kind k := violation_label_and_value(providedkey, { requiredkey }) v := violation_label_and_value(requiredlabels, providedlabels) { k } & { v } != { true } msg := sprintf("[%v] must have label: [%v] and must have one of the following values: %v", [kind, requiredkey, requiredlabels]) } --- apiVersion: constraints.gatekeeper.sh/v1beta1 kind: ResourceSecurityClassification metadata: name: resources-must-have-security-classification spec: match: kinds: - apiGroups: [""] kinds: ["ConfigMap","Secret","PersistentVolumeClaim"] parameters: labelkey: "security" labelvalues: ["s1", "s2", "s3", "s4"] 

官方地址:https://open-policy-agent.github.io/gatekeeper/website/docs/install

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/221921.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午4:59
下一篇 2026年3月17日 下午4:59


相关推荐

  • 下拉刷新实现

    下拉刷新实现下拉刷新在 Android 应用开发中是一种很常见的交互方式 在实际开发中都会引用第三方的下拉刷新库来实现 第三方库通常都经过多个应用程序集成测试 有着相对较高的稳定性和可靠性 里面的代码逻辑也相对比较庞杂 对新手相对不太友好 学习起来比较费时费力 本节就通过前面学习的 Android 视图基本原理来实现自定义的下拉刷新库 补白和边距补白 Padding 指的是视图内部的内容与视图边界之间的距离 通常

    2026年3月18日
    2
  • pycharmimport时找不到指定文件_pycharm系统找不到指定文件

    pycharmimport时找不到指定文件_pycharm系统找不到指定文件1、现象系统提示找不到指定的文件:Errorrunning’hello’:Cannotrunprogram"B:\pystudy\venv\Scripts\python.exe"(indirectory"\python-study"):CreateProcesserror=2,系统找不到指定的文件。2、原因原来的工程目录(B盘)下,保存了python的编…

    2022年8月28日
    17
  • CherryStudio使用指南——详细教程让你玩懂AI

    CherryStudio使用指南——详细教程让你玩懂AI

    2026年3月15日
    3
  • 行业首发,九号电动车支持 OpenClaw 龙虾接入

    行业首发,九号电动车支持 OpenClaw 龙虾接入

    2026年3月13日
    3
  • javascript typescript_typescript python

    javascript typescript_typescript python前言:无论在学习什么语言的时候,我们都需要明白其该怎么样去定义一个变量或者Function,那么今天我们来看看TypeScript的数据类型。文章目录:一.Ts与Js的区别二.Ts的数据![在这里插入图片描述](https://img-blog.csdnimg.cn/8904446afa764db282b731721429ebda.png)三.数据类型应用1.any类型:2.number类型:3.string类型:4.Array类型:(1).[]:(2).数组泛型:一.Ts与Js的区别众所周知:Jav

    2022年8月20日
    5
  • Java中this关键字的详解

    Java中this关键字的详解在 java 的学习中 当接触到类这一章的时候 就会避免不了的接触到 this 关键字 首先 this 关键字指向的是当前对象的引用作用 this 属性名称指的是访问类中的成员变量 用来区分成员变量和局部变量 重名问题 classTest 08 publ

    2026年3月20日
    2

发表回复

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

关注全栈程序员社区公众号