035.集群安全-Pod安全,


一 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 宿主机资源相关配置

  • 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的上层目录。
  • 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 用户和组相关配置

  • RunAsAny:不限制User ID的范围,任何User都可以运行。
  • SupplementalGroups:设置容器可以额外添加的Group ID范围,可以将规则(rule字段)设置为MustRunAs、MayRunAs或RunAsAny。
  • 2.4 提升权限相关配置

    2.5 Linux能力相关配置

    2.6.SELinux相关配置

    2.7 其他Linux相关配置

    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

    相关内容

      暂无相关文章