035.集群安全-Pod安全
程序员文章站
2022-06-19 10:20:36
一Pod安全 1.1PodSecurityPolicy启用 为了更精细地控制Pod对资源的使用方式,Kubernetes从1.4版本开始引入了PodSecurityPolicy资源对象对Pod的安全策略进行管理,并在1.1版本中升级为Beta版,到1.14版本时趋于成熟。 若想启用PodSecu ......
一 pod安全
1.1 podsecuritypolicy启用
为了更精细地控制pod对资源的使用方式,kubernetes从1.4版本开始引入了podsecuritypolicy资源对象对pod的安全策略进行管理,并在1.1版本中升级为beta版,到1.14版本时趋于成熟。
若想启用podsecuritypolicy机制,需要在kube-apiserver服务的启动参数--enable-admission-plugins中进行设置:
[root@k8smaster01 ~]# vi /etc/systemd/system/kube-apiserver.service
1 …… 2 --enable-admission-plugins=podsecuritypolicy \ 3 ……
[root@k8smaster01 ~]# systemctl daemon-reload
[root@k8smaster01 ~]# systemctl restart kube-apiserver.service
在开启podsecuritypolicy准入控制器后,kubernetes默认不允许创建任何pod,需要创建podsecuritypolicy策略和相应的rbac授权策略(authorizing policies),pod才能创建成功。
[root@k8smaster01 study]# vi nginx-pod.yaml #测试创建pod
1 apiversion: v1 2 kind: pod 3 metadata: 4 name: nginx 5 spec: 6 containers: 7 - name: nginx 8 image: nginx 9 ports: 10 - name: web 11 containerport: 80
[root@k8smaster01 study]# kubectl create -f nginx-pod.yaml
1.2 podsecuritypolicy配置
[root@k8smaster01 study]# vi psp-non-privileged.yaml
1 apiversion: policy/v1beta1 2 kind: podsecuritypolicy 3 metadata: 4 name: psp-non-privileged 5 spec: 6 privileged: false #不允许特权模式的pod 7 selinux: 8 rule: runasany 9 supplementalgroups: 10 rule: runasany 11 runasuser: 12 rule: runasany 13 fsgroup: 14 rule: runasany 15 volumes: 16 - '*'
[root@k8smaster01 study]# kubectl create -f psp-non-privileged.yaml
[root@k8smaster01 study]# kubectl get psp psp-non-privileged #查看策略
[root@k8smaster01 study]# kubectl create -f nginx-pod.yaml #再次创建pod
解释:如上podsecuritypolicy“psp-non-privileged”设置了privileged:false,表示不允许创建特权模式的pod。
[root@k8smaster01 study]# vi nginx-pod2.yaml #开启pod的特权模式
1 apiversion: v1 2 kind: pod 3 metadata: 4 name: nginx2 5 spec: 6 containers: 7 - name: nginx2 8 image: nginx 9 securitycontext: 10 privileged: true 11 ports: 12 - name: web 13 containerport: 80
[root@k8smaster01 study]# kubectl create -f nginx-pod2.yaml
解释:如上开启pod的特权模式,在创建pod时,系统将提示如上“禁止创建特权模式的pod”的报错信息。
二 podsecuritypolicy配置详解
在podsecuritypolicy对象中可以设置下列字段来控制pod运行时的各种安全策略。
2.1 特权模式配置
privileged:是否允许pod以特权模式运行。
2.2 宿主机资源相关配置
- hostpid:是否允许pod共享宿主机的进程空间。
- hostipc:是否允许pod共享宿主机的ipc命名空间。
- hostnetwork:是否允许pod使用宿主机网络的命名空间。
- hostports:是否允许pod使用宿主机的端口号,可以通过hostportrange字段设置允许使用的端口号范围,以[min,max]设置最小端口号和最大端口号。
- volumes:允许pod使用的存储卷volume类型,设置为“*”表示允许使用任意volume类型,建议至少允许pod使用下列volume类型。
- configmap
- downwardapi
- emptydir
- persistentvolumeclaim
- secret
- projected
- allowedhostpaths:允许pod使用宿主机的hostpath路径名称,可以通过pathprefix字段设置路径的前缀,并可以设置是否为只读属性。
示例1:
1 apiversion: policy/v1beta1 2 kind: podsecuritypolicy 3 metadata: 4 name: allow-hostpath-volumes 5 spec: 6 volumes: 7 - hostpath 8 allowedhostpaths: 9 - pathprefix: "/foo" 10 readonly: true
解释:结果为允许pod访问宿主机上以“/foo”为前缀的路径,包括“/foo”“/foo/”“/foo/bar”等,但不能访问“/fool”“/etc/foo”等路径,也不允许通过“/foo/../”表达式访问/foo的上层目录。
- fsgroup:设置允许访问某些volume的group id范围,可以将规则(rule字段)设置为mustrunas、mayrunas或runasany。
- mustrunas:需要设置group id的范围,例如1~65535,要求pod的securitycontext.fsgroup设置的值必须属于该group id的范围。
- mayrunas:需要设置group id的范围,例如1~65535,不强制要求pod设置securitycontext.fsgroup。
- runasany:不限制group id的范围,任何group都可以访问volume。
- readonlyrootfilesystem:要求容器运行的根文件系统(rootfilesystem)必须是只读的。
- allowedflexvolumes:对于类型为flexvolume的存储卷,设置允许使用的驱动类型。
示例2:
1 apiversion: policy/v1beta1 2 kind: podsecuritypolicy 3 metadata: 4 name: allow-flex-volumes 5 spec: 6 volumes: 7 - flexvolume 8 allowedflexvolumes: 9 - driver: example/lvm 10 - driver: example/cifs
2.3 用户和组相关配置
- runasuser:设置运行容器的用户id(user id)范围,规则字段(rule)的值可以被设置为mustrunas、mustrunasnonroot或runasany。
- mustrunas:需要设置user id的范围,要求pod的securitycontext.runasuser设置的值必须属于该user id的范围。
- mustrunasnonroot:必须以非root用户运行容器,要求pod的securitycontext.runasuser设置一个非0的用户id,或者镜像中在user字段设置了用户id,建议同时设置allowprivilegeescalation=false以避免不必要的提升权限操作。
- runasany:不限制user id的范围,任何user都可以运行。
- runasgroup:设置运行容器的group id范围,规则字段的值可以被设置为mustrunas、mustrunasnonroot或runasany。
- mustrunas:需要设置group id的范围,要求pod的securitycontext.runasgroup设置的值必须属于该group id的范围。
- mustrunasnonroot:必须以非root组运行容器,要求pod的securitycontext.runasuser设置一个非0的用户id,或者镜像中在user字段设置了用户id,建议同时设置allowprivilegeescalation=false以避免不必要的提升权限操作。
- runasany:不限制group id的范围,任何group的用户都可以运行。
- supplementalgroups:设置容器可以额外添加的group id范围,可以将规则(rule字段)设置为mustrunas、mayrunas或runasany。
- mustrunas:需要设置group id的范围,要求pod的securitycontext.supplementalgroups设置的值必须属于该group id范围。
- mayrunas:需要设置group id的范围,不强制要求pod设置securitycontext.supplementalgroups。
- runasany:不限制group id的范围,任何supplementalgroups的用户都可以运行。
2.4 提升权限相关配置
- allowprivilegeescalation:设置容器内的子进程是否可以提升权限,通常在设置非root用户(mustrunasnonroot)时进行设置。
- defaultallowprivilegeescalation:设置allowprivilegeescalation的默认值,设置为disallow时,管理员还可以显式设置allowprivilegeescalation来指定是否允许提升权限。
2.5 linux能力相关配置
- allowedcapabilities:设置容器可以使用的linux能力列表,设置为“*”表示允许使用linux的所有能力(如net_admin、sys_time等)。
- requireddropcapabilities:设置不允许容器使用的linux能力列表。
- defaultaddcapabilities:设置默认为容器添加的linux能力列表,例如sys_time等,docker建议默认设置的linux能力请查看https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linuxcapabilities。
2.6.selinux相关配置
- selinux:设置selinux参数,可以将规则字段(rule)的值设置为mustrunas或runasany。
- mustrunas:要求设置selinuxoptions,系统将对pod的securitycontext.selinuxoptions设置的值进行校验。
- runasany:不限制selinuxoptions的设置。
2.7 其他linux相关配置
- allowedprocmounttypes:设置允许的procmounttypes类型列表,可以设置allowedprocmounttypes或defaultprocmount。
- apparmor:设置对容器可执行程序的访问控制权限,详情请参考https://kubernetes.io/docs/tutorials/clusters/apparmor/#podsecuritypolicyannotations。
- seccomp:设置允许容器使用的系统调用(systemcalls)的profile。
- sysctl:设置允许调整的内核参数,详情请参考https://kubernetes.io/docs/concepts/cluster-administration/sysctlcluster/#podsecuritypolicy。
2.8 常见podsecuritypolicy安全策略配置
示例1:基本没有限制的安全策略,允许创建任意安全设置的pod。
1 apiversion: policy/v1beta1 2 kind: podsecuritypolicy 3 metadata: 4 name: privileged 5 annotations: 6 seccomp.security.alpha.kubernetes.io/allowedprofilenames: '*' 7 spec: 8 privileged: true 9 allowprivilegeescalation: true 10 allowedcapabilities: 11 - '*' 12 volumes: 13 - '*' 14 hostnetwork: true 15 hostports: 16 - min: 0 17 max: 65535 18 hostipc: true 19 hostpid: true 20 runasuser: 21 rule: 'runasany' 22 selinux: 23 rule: 'runasany' 24 supplementalgroups: 25 rule: 'runasany' 26 fsgroup: 27 rule: 'runasany'
示例2:要求pod运行用户为非特权用户;禁止提升权限;不允许使用宿主机网络、端口号、ipc等资源;限制可以使用的volume类型等。
1 apiversion: policy/v1beta1 2 kind: podsecuritypolicy 3 metadata: 4 name: restricted 5 annotations: 6 seccomp.security.alpha.kubernetes.io/allowedprofilenames: 'docker/default' 7 apparmor.security.beta.kubernetes.io/allowedprofilenames: 'runtime/default' 8 seccomp.security.alpha.kubernetes.io/defaultprofilename: 'docker/default' 9 apparmor.security.beta.kubernetes.io/dafaultprofilename: 'runtime/default' 10 spec: 11 privileged: false 12 allowprivilegeescalation: false 13 requireddropcapabilities: 14 - all 15 volumes: 16 - 'configmap' 17 - 'emptydir' 18 - 'projected' 19 - 'secret' 20 - 'downwardapi' 21 - 'persistentvolumeclaim' 22 hostnetwork: false 23 hostipc: false 24 hostpid: false 25 runasuser: 26 rule: 'mustrunasnonroot' 27 selinux: 28 rule: 'mustrunas' 29 ranges: 30 - min: 1 31 max: 65535 32 fsgroup: 33 rule: 'mustrunas' 34 ranges: 35 - min: 1 36 max: 65535 37 readonlyrootfilesystem: false
示例3:创建如下clusterrole(也可以创建role)并将其设置为:允许使用podsecuritypolicy。
1 kind: clusterrole 2 apiversion: rbac.authorization.k8s.io/v1 3 metadata: 4 name: <role name> 5 rules: 6 - apigroup: ['policy'] 7 resources: ['podsecuritypolicies'] 8 verbs: ['use'] 9 resourcenames: 10 - <list of policies to authorize> # 允许使用的podsecuritypolicy列表
然后创建一个clusterrolebinding与用户和serviceaccount进行绑定。
1 kind: clusterrolebinding 2 apiversion: rbac.authorization.k8s.io/v1 3 metadata: 4 name: <binding name> 5 roleref: 6 kind: clusterrole 7 name: <roke name> # 之前创建的clusterrole名称 8 apigroup: rbac.authorization.k8s.io 9 subjects: 10 # 对特定namespace中的serviceaccount进行授权 11 - kind: serviceaccount 12 name: <authorized servie account name> # serviceaccount 的名称 13 namespace: <authorized pod namespace> # namespace的名称 14 # 对特定用户进行授权(不推荐) 15 - kind: user 16 apigroup: rbac.authorization.k8s.io 17 name: <authorized user name> # 用户名
三 pod的安全设置详解
3.1 pod安全策略类型
当kubernetes集群中设置了podsecuritypolicy策略之后,系统将对pod和container级别的安全设置进行校验,对于不满足podsecuritypolicy安全策略的pod,系统将拒绝创建。
pod和容器的安全策略可以在pod或container的securitycontext字段中进行设置,如果在pod和container级别都设置了相同的安全类型字段,容器将使用container级别的设置。
在pod级别可以设置的安全策略类型如下:
- runasgroup:容器内运行程序的用户组id。
- runasnonroot:是否必须以非root用户运行程序。
- fsgroup:selinux相关设置。
- selinuxoptions:selinux相关设置。
- supplementalgroups:允许容器使用的其他用户组id。
- sysctls:设置允许调整的内核参数。
- 在container级别可以设置的安全策略类型如下。
- runasuser:容器内运行程序的用户id。
- runasgroup:容器内运行程序的用户组id。
- runasnonroot:是否必须以非root用户运行程序。
- privileged:是否以特权模式运行。
- allowprivilegeescalation:是否允许提升权限。
- readonlyrootfilesystem:根文件系统是否为只读属性。
- capabilities:linux能力列表。
- selinuxoptions:selinux相关设置。
示例1:
[root@k8smaster01 study]# vi security-context-pod01.yaml
1 apiversion: v1 2 kind: pod 3 metadata: 4 name: security-context-demo 5 spec: 6 securitycontext: 7 runasuser: 1000 8 runasgroup: 3000 9 fsgroup: 2000 10 volumes: 11 - name: sec-ctx-vol 12 emptydir: {} 13 containers: 14 - name: sec-ctx-demo 15 image: tomcat 16 volumemounts: 17 - name: sec-ctx-vol 18 mountpath: /data/demo 19 securitycontext: 20 allowprivilegeescalation: false
[root@k8smaster01 study]# kubectl create -f security-context-pod01.yaml
[root@k8smaster01 study]# kubectl exec -ti security-context-demo /bin/bash
$ ps aux #运行进程的用户id为1000
$ ls -l /data/ #挂载的目录group id为2000
total 0
drwxrwsrwx 2 root 2000 6 nov 28 13:56 demo
解释:在spec.securitycontext中设置了如下参数。
runasuser=1000:所有容器都将以user id 1000运行程序,所有新生成文件的user id也被设置为1000。
runasgroup=3000:所有容器都将以group id 3000运行程序,所有新生成文件的group id也被设置为3000。
fsgroup=2000:挂载的卷“/data/demo”及其中创建的文件都将属于group id 2000。
3.3 container安全策略类型
- runasuser: 容器内运行程序的用户id。
- runasgroup: 容器内运行程序的用户组id。
- runasnonroot: 是否必须以非root用户运行程序。
- privileged: 是否以特权模式运行。
- allowprivilegeescalation: 是否允许提升权限。
- readonlyrootfilesystem: 根文件系统是否为只读属性。
- capabilities: linux能力列表。
- selinuxoptions: selinux相关设置。
示例2:
[root@k8smaster01 study]# vi security-context-pod02.yaml
1 apiversion: v1 2 kind: pod 3 metadata: 4 name: security-context-demo-2 5 spec: 6 securitycontext: 7 runasuser: 1000 8 containers: 9 - name: sec-ctx-demo-2 10 image: tomcat 11 securitycontext: 12 runasuser: 2000 13 allowprivilegeescalation: false
[root@k8smaster01 study]# kubectl create -f security-context-pod02.yaml
[root@k8smaster01 study]# kubectl exec security-context-demo-2 /bin/bash
$ ps aux #运行进程的用户id为1000
下一篇: pomelo源码解析之组件解析(四)