概念:
- PodSecurityPolicy,简称PSP,是K8s中Pod部署时重要的安全校验手段,能够有效地约束应用运行时行为安全。
- 使用PSP对象定义一组Pod在运行时必须遵循的条件及相关字段的默认值,只有Pod满足这些条件才会被K8s接受。
- Pod安全策略实现为一个准入控制器,默认没有启用,当启用后会强制实施Pod安全策略,没有满足的Pod将无法创建。因此,建议在启用PSP之前先添加策略并对其授权。
启用Pod安全策略:
- kube-apiserver.yaml配置文件添加准入控制器。
- 重启kubelet,systemctl restart kubelet
玩法思路:
- 创建SA服务账号。
- 将SA绑定到系统内置Role edit。
- 创建使用PSP权限的Role qingjun。
- 将SA绑定到角色qingjun上。
- 定义PodSecurityPolicy策略。
注意事项:
- 使用复杂,权限模型存在缺陷,控制不明确,一旦出现问题不好定位,所以将再1.21版本弃用PSP,在1.25版本删除PSP。 弃用官方文献
- 替代方案KEP 2579。
- 替代外部控制器方案:K-Rail、 Kyverno、 OPA/Gatekeeper 。
2.1.1 安全策略限制维度
配置项描述privileged启动特权容器。hostPID,hostIPC使用主机namespaces。hostNetwork,hostPorts使用主机网络和端口。volumes允许使用的挂载卷类型。allowedHostPaths允许hostPath类型挂载卷在主机上挂载的路径,通过pathPrefix字段声明允许挂载的主机路径前缀组。allowedFlexVolumes允许使用的指定FlexVolume驱动。fsGroup配置Pod中挂载卷使用的辅组ID。readOnlyRootFilesystem约束启动Pod使用只读的root文件系统。runAsUser,runAsGroup,supplementalGroups指定Pod中容器启动的用户ID以及主组和辅组ID。allowPrivilegeEscalation,defaultAllowPrivilegeEscalation约束Pod中是否允许配置allowPrivilegeEscalation=true,该配置会控制setuid的使用,同时控制程序是否可以使用额外的特权系统调用。defaultAddCapabilities,requiredDropCapabilities,allowedCapabilities控制Pod中使用的Linux Capabilities。seLinux控制Pod使用seLinux配置。allowedProcMountTypes控制Pod允许使用的ProcMountTypes。annotations配置Pod中容器使用的AppArmor或seccomp。forbiddenSysctls,allowedUnsafeSysctls控制Pod中容器使用的sysctl配置。
2.2 OPA Gatekeeper方案
前提了解:
- OPA(Open Policy Agent):是一个开源的、通用策略引擎,可以将策略编写为代码。提供一个种高级声明性语言-Rego来编写策略,并把决策这一步骤从复杂的业务逻辑中解耦出来。
- 是PSP的替代方案,属于外部准入控制器。
- OPA官网
- Gatekeeper项目地址
- Gatekeeper文档
OPA可以用来做什么?
- 拒绝不符合条件的YAML部署。
- 允许使用哪些仓库中的镜像。
- 允许在哪个时间段访问系统。
- 等等。
OPA Gatekeeper的概念:
- Gatekeeper 是基于 OPA的一个 Kubernetes 策略解决方案,可替代PSP或者部分RBAC功能。因为OPA与K8s对接偏向于底层,不好使用,所以社区就基于OPA引擎开发了OPA Gatekeeper的解决方案,方便使用。
- 当在集群中部署了Gatekeeper组件,APIServer所有的创建、更新或者删除操作都会触发Gatekeeper来处理,如果不满足策略则拒绝。
工作流程图:
2.2.1 安装Gatekeeper
1.下载准备安装yaml文件,下载地址
2.导入文件一键部署,并查看。
[root@k8s-master1 opa]# kubectl apply -f gatekeeper.yaml
2.2.2 编写策略
Gatekeeper的策略由两个资源对象组成:
- Template模板:在后面我们需要自定义限制策略,策略是怎么实现的就需要我们先写一个实现逻辑,这里就把这个实现逻辑称之为模板,使用rego语言。
- Contsraint约束:自定义限制策略,当我们创建任何一个资源时可以先通过这个约束来进行过滤处理,违反约束就代表能限制你创建自动动作,不让你创建这个资源。所以约束就是负责K8s资源对象的过滤或者为Template模板提供输入参数。
实现思路:
- 先使用rego语言编写Template模板,在这个模板里自定义实现逻辑,就相当于写一个脚本逻辑。
- 自定义Constraint约束,约束格式类似rbac授权那种,要限制什么资源,这个资源在什么组。
- 当我们创建一个资源时,比如创建deployment时,若是触发了约束,则就会带入到模板里,看是否能违反约束,若是违反约束就相当于出发了开关,不让你创建deployment。
模板核心字段释义:
- 字段containers = input.review.object.spec.template.spec.containers - input.review.object :抓取约束模板里自定义的限制资源。比如我在约束模板里限制deployment资源,这里就是是抓取的deployment资源。- .spec.template.spec.containers:代表获取资源对象的yaml文件里.spec.template.spec.containers内容,可以用kubectl explan获取。比如我在约束模板里限制的是deployment资源,那么当我创建deployment资源时就会抓取deployment.yaml文件里的spec.template.spec.containers下的内容,如下图,就是获取下图中的红框内容。此时拿到这块内容,再根据模板里的逻辑进行判断,看最后是否输出的true,若是则代表违反约束,你就不能创建deployment资源。
2.2.3 案例1
需求:
- 禁止容器启用特权。若用户创建的资源里有开启特权容器参数,则限制用户不能创建资源。
实现代码逻辑:
- violation函数返回的是布尔值True或者False。我取deployment.yaml文件里的特权容器参数,若返回值为false,则不会继续往下执行函数,属于放行不做拦截;若返回值为true,则说明整个函数表达式已通过,代表违反约束需要拦截,就相当于触碰到开关起到拦截作用。
1.编写模板和约束,在模板里使用rego脚本匹配约束里面的的资源。
##模板
[root@k8s-master1 opa]# cat privileged_tpl.yaml
apiVersion: templates.gatekeeper.sh/v1beta1
kind
版权归原作者 杭州湾Java仔 所有, 如有侵权,请联系我们删除。