欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

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
035.集群安全-Pod安全

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
035.集群安全-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
035.集群安全-Pod安全
解释:如上开启pod的特权模式,在创建pod时,系统将提示如上“禁止创建特权模式的pod”的报错信息。

二 podsecuritypolicy配置详解

在podsecuritypolicy对象中可以设置下列字段来控制pod运行时的各种安全策略。

2.1 特权模式配置

privileged:是否允许pod以特权模式运行。

2.2 宿主机资源相关配置

  1. hostpid:是否允许pod共享宿主机的进程空间。
  2. hostipc:是否允许pod共享宿主机的ipc命名空间。
  3. hostnetwork:是否允许pod使用宿主机网络的命名空间。
  4. hostports:是否允许pod使用宿主机的端口号,可以通过hostportrange字段设置允许使用的端口号范围,以[min,max]设置最小端口号和最大端口号。
  5. volumes:允许pod使用的存储卷volume类型,设置为“*”表示允许使用任意volume类型,建议至少允许pod使用下列volume类型。
    1. configmap
    2. downwardapi
    3. emptydir
    4. persistentvolumeclaim
    5. secret
    6. projected
  6. 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的上层目录。
  1. fsgroup:设置允许访问某些volume的group id范围,可以将规则(rule字段)设置为mustrunas、mayrunas或runasany。
    1. mustrunas:需要设置group id的范围,例如1~65535,要求pod的securitycontext.fsgroup设置的值必须属于该group id的范围。
    2. mayrunas:需要设置group id的范围,例如1~65535,不强制要求pod设置securitycontext.fsgroup。
    3. runasany:不限制group id的范围,任何group都可以访问volume。
  2. readonlyrootfilesystem:要求容器运行的根文件系统(rootfilesystem)必须是只读的。
  3. 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 用户和组相关配置

  1. runasuser:设置运行容器的用户id(user id)范围,规则字段(rule)的值可以被设置为mustrunas、mustrunasnonroot或runasany。
    1. mustrunas:需要设置user id的范围,要求pod的securitycontext.runasuser设置的值必须属于该user id的范围。
    2. mustrunasnonroot:必须以非root用户运行容器,要求pod的securitycontext.runasuser设置一个非0的用户id,或者镜像中在user字段设置了用户id,建议同时设置allowprivilegeescalation=false以避免不必要的提升权限操作。
  2. runasany:不限制user id的范围,任何user都可以运行。
    1. runasgroup:设置运行容器的group id范围,规则字段的值可以被设置为mustrunas、mustrunasnonroot或runasany。
    2. mustrunas:需要设置group id的范围,要求pod的securitycontext.runasgroup设置的值必须属于该group id的范围。
    3. mustrunasnonroot:必须以非root组运行容器,要求pod的securitycontext.runasuser设置一个非0的用户id,或者镜像中在user字段设置了用户id,建议同时设置allowprivilegeescalation=false以避免不必要的提升权限操作。
    4. runasany:不限制group id的范围,任何group的用户都可以运行。
  3. supplementalgroups:设置容器可以额外添加的group id范围,可以将规则(rule字段)设置为mustrunas、mayrunas或runasany。
    1. mustrunas:需要设置group id的范围,要求pod的securitycontext.supplementalgroups设置的值必须属于该group id范围。
    2. mayrunas:需要设置group id的范围,不强制要求pod设置securitycontext.supplementalgroups。
    3. runasany:不限制group id的范围,任何supplementalgroups的用户都可以运行。

2.4 提升权限相关配置

  1. allowprivilegeescalation:设置容器内的子进程是否可以提升权限,通常在设置非root用户(mustrunasnonroot)时进行设置。
  2. defaultallowprivilegeescalation:设置allowprivilegeescalation的默认值,设置为disallow时,管理员还可以显式设置allowprivilegeescalation来指定是否允许提升权限。

2.5 linux能力相关配置

  1. allowedcapabilities:设置容器可以使用的linux能力列表,设置为“*”表示允许使用linux的所有能力(如net_admin、sys_time等)。
  2. requireddropcapabilities:设置不允许容器使用的linux能力列表。
  3. defaultaddcapabilities:设置默认为容器添加的linux能力列表,例如sys_time等,docker建议默认设置的linux能力请查看https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linuxcapabilities。

2.6.selinux相关配置

  1. selinux:设置selinux参数,可以将规则字段(rule)的值设置为mustrunas或runasany。
    1. mustrunas:要求设置selinuxoptions,系统将对pod的securitycontext.selinuxoptions设置的值进行校验。
    2. runasany:不限制selinuxoptions的设置。

2.7 其他linux相关配置

  1. allowedprocmounttypes:设置允许的procmounttypes类型列表,可以设置allowedprocmounttypes或defaultprocmount。
  2. apparmor:设置对容器可执行程序的访问控制权限,详情请参考https://kubernetes.io/docs/tutorials/clusters/apparmor/#podsecuritypolicyannotations。
  3. seccomp:设置允许容器使用的系统调用(systemcalls)的profile。
  4. 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
035.集群安全-Pod安全
解释:在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
035.集群安全-Pod安全