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

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
clipboard
解釋:如上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
clipboard
解釋:如上開啟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
clipboard
解釋:在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
clipboard


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM