035.叢集安全-Pod安全
阿新 • • 發佈:2020-03-21
一 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.service1 …… 2 --enable-admission-plugins=PodSecurityPolicy \ 3 ……
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
1.2 PodSecurityPolicy配置
[root@k8smaster01 study]# vi psp-non-privileged.yaml1 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 - '*'
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 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的儲存卷,設定允許使用的驅動型別。
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 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相關設定。
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