出发点

如果您所在的组织一直在使用 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` fieldopenAPIV3Schema:properties:    // 需要满足的条件的参数labels:type: arrayitems: stringtargets:- target: admission.k8s.gatekeeper.shrego: |package k8srequiredlabelsviolation[{"msg": msg, "details": {"missing_labels": missing}}] {provided := {label | input.review.object.metadata.labels[label]}  // 获取到创建的对象的所有labelrequired := {label | label := input.parameters.labels[_]}  // 获取到需要提供的labelmissing := 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: appoperator: Invalues: [nginx1]namespaces: ["ns-test"]parameters:labels: ["gatekeeper"]

查看Constraints

kubectl get constraints

测试

apiVersion: v1
kind: Namespace
metadata:name: ns-testlabels: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

如果需要创建自己的约束,但是不知道传入的参数即input是什么,可以在创建模板时violation只保留下面几行,此时创建对象时必定会失败,然后获取到输出的错误信息,里面即包含所有input信息,之后再通过rego语法去获取需要的数据即可
violation[{"msg": msg}] {
    msg := sprintf("input:  %v", [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: K8sRequiredusersvalidation:# Schema for the `parameters` fieldopenAPIV3Schema:properties:users:type: arrayitems: stringtargets:- target: admission.k8s.gatekeeper.shrego: |package k8srequiredusersviolation[{"msg": msg}] {// 把创建时的用户名放在一个集合里user := { input.review.userInfo.username }   // 获取允许创建该pod的用户集合permitUser := {user | user := input.parameters.users[_]}// 集合-集合allow := permitUser - user// 如果减完之后集合还相等,说明这个用户没有在允许的集合中,不满足约束条件allow == permitUsermsg := 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: appoperator: Invalues: [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: pod2labels:app: nginx1
spec:containers:- name: nginx-podimage: nginx:1.12imagePullPolicy: Never

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

k8s创建普通用户_weixin_42758299的博客-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` fieldopenAPIV3Schema:properties:labelkey:type: stringlabelvalues:type: arrayitems: stringtargets:- target: admission.k8s.gatekeeper.shrego: |package resourcesecurityclassification violation_label_and_value(provided, required) = allow {rlt := provided - requiredallow := (rlt != provided)}violation[{"msg": msg}] {providedlabels := {label | label := input.review.object.metadata.labels[_]}providedkey := {key | input.review.object.metadata.labels[key]}requiredkey := input.parameters.labelkeyrequiredlabels := {label | label := input.parameters.labelvalues[_]}kind := input.review.object.kindk := 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

OPA-Gatekeeper使用相关推荐

  1. OPA Gatekeeper 策略入门

    Gatekeeper 是基于 OPA(Open Policy Agent) 的一个 Kubernetes 策略解决方案.在之前的文章中说过,在 PSP/RBAC 等内置方案之外,在 Kubernete ...

  2. OPA和Gatekeeper区别?

    Gaurav Chaware Oct 27th, 2020 In the last couple of posts, I wrote about Open Policy Agent (OPA). Pe ...

  3. 云原生生态周报 Vol. 16 | CNCF 归档 rkt,容器运行时“上古”之战老兵凋零

    作者列表:木苏,临石,得为,等等 业界要闻 安全漏洞 CVE-2019-9512 CVE-2019-9514 http2 的 DOS 漏洞,一旦攻击成功会耗尽服务器的 cpu/mem,从而导致服务不可 ...

  4. Rancher 2.5 正式发布,多项重大更新来袭!

    喜欢就关注我们吧! 近日,Kubernetes 管理平台 Rancher 2.5 正式发布,官方公布了在 Rancher 2.5 中的多项重大更新,包括全新的安装体验.针对边缘集群的大规模 GitOp ...

  5. 使用 CNF 测试套件测试云原生最佳实践

    Joel Hans为CNCF撰写的社区帖子 电信行业是当今日益数字化的经济的支柱,但在发展以满足现代基础设施实践方面面临着艰巨的新挑战.电信是如何陷入这种境地的?由于事故或停机的风险非常严重,该行业几 ...

  6. Kubernetes 学习总结(23)—— 2022 年 Kubernetes 的 5 个趋势

    前言 Kubernetes 在成长,使用它的团队也在成长.早期采用者现在已经进入了自己的领域,能够基于经验和云原生生态系统的增长,以新的方式扩展 Kubernetes 的核心功能."我们将继 ...

  7. k8s pod里访问不到外部ip_安全公告:影响所有K8s版本的设计缺陷

    K8s产品委员会于本周一发布了一个安全公告,该公告揭露了一个K8s影响多租户集群的安全漏洞.该漏洞由Anevia的Etienne Champetier报告.如果潜在的攻击者已经可以创建或编辑服务和Po ...

  8. 谈谈我对云原生与软件供应链安全的思考

    作者:易立 2011 年,互联网技术先驱 Marc Andreessen 宣称,软件正在吞噬世界(Software is eating the world).由软件驱动的行业创新正在颠覆着传统业务模式 ...

  9. 为什么需要 Kubernetes 准入控制器

    Kubernetes 准入控制器是集群管理必要功能.这些控制器主要在后台工作,并且许多可以作为编译插件使用,它可以极大地提高部署的安全性. 准入控制器在 API 请求传递到 APIServer 之前拦 ...

  10. 二十八、K8s最小服务漏洞2-OPA

    一.OPA概述 OPA (Open Policy Agent)背后的主要动机是在整个环境中实现统一的策略实施.通常,组织需要在运行其应用程序的环境中应用各种策略.可能需要这些策略来满足合规性要求.实现 ...

最新文章

  1. tf.keras.losses.categorical_hinge 分类铰链 损失函数 示例
  2. 关于startActivityForResult
  3. 查询数据(使用聚合函数,还是单表)
  4. C语言编写扫雷小游戏
  5. model.parameters(),model.state_dict(),model .load_state_dict()以及torch.load()
  6. 《深入理解Java函数式编程》系列文章
  7. 基于Echarts+HTML5可视化数据大屏展示—新能源车联网综合大数据平台(二)
  8. phpcmsV9留言插件提交后返回上一页实现方法
  9. [CodePlus 2017 11月赛]晨跑 题解(辗转相除法求GCD)
  10. Bailian2757 最长上升子序列【DP】
  11. python 累加m到n的所有素数的和_c#实现:返回n到m之间的所有素数
  12. Javascript:模拟ztree侧边栏的回收
  13. IE下用iframe引入页面时出现SCRIPT5: 拒绝访问(access is denied)
  14. 国内的9家域名顶级注册商
  15. Solidwork软件盗版
  16. android模拟器设置静态ip,静态IP地址版EVE模拟器部署和使用说明
  17. Linux:Linux文件属性
  18. cmd进入指定目录方法
  19. PTA(每日一题)7-75 某校几人
  20. AP微积分全方位解析

热门文章

  1. 计算多个不同鞋码对应的脚长——C语言
  2. emoji表情如何处理
  3. Personalized Top-N Sequential Recommendation via Convolutional Sequence Embedding
  4. JZOJ 幽幽子与森林
  5. Git 最著名报错 “ERROR: Permission to XXX.git denied to user”终极解决方案
  6. java简单实现布谷鸟过滤器的
  7. js中数组filter过滤奇偶数_js--数组的filter()过滤方法的使用
  8. android 免root冻结,自冻FreezeYou(超强免ROOT冻结神器)
  9. 程序员在上海税前12000的工资,真实发到手能拿到多少?
  10. 优酷路由器刷openwrt固件一