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: privileged
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package admission
violation[{"msg": msg}] { # 如果violation为true说明违反约束
containers = input.review.object.spec.template.spec.containers
c_name := containers[0].name
containers[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: null
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
securityContext:
privileged: true
ports:
- containerPort: 80
resources: {}
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-check
validation:
openAPIV3Schema:
properties: # 需要满足条件的参数
prefix:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package image
violation[{"msg": msg}] {
containers = input.review.object.spec.template.spec.containers
image := containers[0].image
not 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/"