Gatekeeper 是基于 OPA的一个 Kubernetes 策略解决方案,可替代PSP或者部分RBAC功能。
当在集群中部署了Gatekeeper组件,APIServer所有的创建、更新或者删除操作都会触发
Gatekeeper来处理,如果不满足策略则拒绝
OPA(Open Policy Agent): 是一个开源的、通用策略引擎,可以将策略编写为代码。提供
一个种高级声明性语言-Rego来编写策略,并把决策这一步骤从复杂的业务逻辑中解耦出来。
OPA可以用来做什么?
• 拒绝不符合条件的YAML部署
• 允许使用哪些仓库中的镜像
• 允许在哪个时间段访问系统
• 等

部署Gatekeeper:
kubectl apply -f https://raw.githubusercontent.com/open-policy
agent/gatekeeper/release-3.7/deploy/gatekeeper.yaml
Gatekeeper的策略由两个资源对象组成:
• Template:策略逻辑实现的地方,使用rego语言
• Contsraint:负责Kubernetes资源对象的过滤或者为Template提供输入参数
案例1:禁止容器启用特权
第一步,需要删除psp
vi /etc/kubernetes/manifests/kube-apiserver.yaml
...
- --enable-admission-plugins=NodeRestriction
...
systemctl restart kubelet
网站地址: https://open-policy-agent.github.io/gatekeeper/website/docs/install/
下载部署:kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/release-3.7/deploy/gatekeeper.yaml
模板
[root@k8s-master opa]# cat privileged_tpl.yaml
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:name: privileged
spec:crd:spec:names:kind: privilegedtargets:- target: admission.k8s.gatekeeper.shrego: |package admissionviolation[{"msg": msg}] { # 如果violation为true说明违反约束containers = input.review.object.spec.template.spec.containersc_name := containers[0].namecontainers[0].securityContext.privileged # 如果返回false或者没获取到值说明通过msg := sprintf("提示:'%v'容器禁止启用特权!",[c_name])}约束
[root@k8s-master opa]# cat privileged_constraints.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: privileged
metadata:name: privileged
spec:match: # 匹配的资源kinds:- apiGroups: ["apps"]kinds:- "Deployment"- "DaemonSet"- "StatefulSet"查看
[root@k8s-master opa]# kubectl get constraints
NAME AGE
privileged 25s[root@k8s-master opa]# kubectl get ConstraintTemplate
NAME AGE
privileged 118s
[root@k8s-master opa]# cat T_deplyment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:creationTimestamp: nulllabels:app: nginxname: nginx
spec:replicas: 1selector:matchLabels:app: nginxstrategy: {}template:metadata:creationTimestamp: nulllabels:app: nginxspec:containers:- image: nginxname: nginxsecurityContext:privileged: trueports:- containerPort: 80resources: {}
status: {}
案例:只允许使用特定的镜像仓库
[root@k8s-master opa]# cat image-check_tpl.yaml
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:name: image-check
spec:crd:spec:names:kind: image-checkvalidation:openAPIV3Schema: properties: # 需要满足条件的参数prefix:type: stringtargets:- target: admission.k8s.gatekeeper.shrego: |package imageviolation[{"msg": msg}] { containers = input.review.object.spec.template.spec.containersimage := containers[0].imagenot startswith(image, input.parameters.prefix)msg := sprintf("提示:'%v'镜像地址不在可信任仓库!", [image])}[root@k8s-master opa]# cat image-check_constraints.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: image-check
metadata:name: image-check
spec:match:kinds:- apiGroups: ["apps"] kinds:- "Deployment"- "DaemonSet"- "StatefulSet"parameters: # 传递给opa的参数prefix: "lizhenliang/"