導讀
Pod容器想要獲取集群的資源信息,需要配置角色和ServiceAccount進行授權。為了更精細地控制Pod對資源的使用方式,Kubernetes從1.4版本開始引入了PodSecurityPolicy資源對象對Pod的安全策略進行管理。
Pod特權模式
容器內的進程獲得的特權幾乎與容器外的進程相同。使用特權模式,可以更容易地將網絡和卷插件編寫為獨立的pod,不需要編譯到kubelet中。
PodSecurityPolicy
官網定義
Pod 安全策略(Pod Security Policy) 是集群級別的資源,它能夠控制Pod規約 中與安全性相關的各個方面。PodSecurityPolicy 對象定義了一組Pod運行時必須遵循的條件及相關字段的默認值,只有 Pod 滿足這些條件才會被系統接受。
Pod 安全策略允許管理員控制如下方面:
Pod 安全策略 由設置和策略組成,它們能夠控制 Pod 訪問的安全特征。這些設置分為如下三類:
(1)基於布爾值控制 :這種類型的字段默認為最嚴格限制的值。
(2)基於被允許的值集合控制 :這種類型的字段會與這組值進行對比,以確認值被允許。
(3)基於策略控制 :設置項通過一種策略提供的機制來生成該值,這種機制能夠確保指定的值落在被允許的這組值中。
開啟
如果需要開啟PodSecurityPolicy,需要在kube-apiserver的啟動參數中設置如下參數
--enable-admission-plugins=PodSecurityPolicy
在開啟PodSecurityPolicy准入控制器后,k8s默認不允許創建任何Pod,需要創建PodSecurityPolicy和RBAC授權策略,Pod才能創建成功。
注:修改kube-apiserver配置文件/etc/kubernetes/manifests/kube-apiserver.yaml,由於是static pod,所以修改就會生效。
系統默認此參數為:
--enable-admission-plugins=NodeRestriction
開啟之后創建Pod會出現如下錯誤:
創建PodSecurityPolicy
下列PodSecurityPolicy表示是不允許創建特權模式的Pod
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: psp-non-privileged
spec:
privileged: false #不允許特權模式的Pod
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
runAsUser:
rule: RunAsAny
fsGroup:
rule: RunAsAny
volumes:
- '*'
創建之后查看:
kubectl get psp 或者 kubectl get podSecurityPolicy
之后再次創建Pod就能創建成功
上面的PodSecurytiPolicy是設置了不允許創建特權模式的Pod,例如,在下面的YAML配置文件pod-privileged.yaml中為Pod設置了特權模式:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
securityContext:
privileged: true
創建的時候會報如下錯誤:
unable to validate against any pod security policy
PodSecurityPolicy配置詳解
在PodSecurityPolicy對象中可以設置下列字段來控制Pod運行時的各種安全策略
(1)特權模式相關配置
privileged:是否允許Pod以特權模式運行
(2)宿主機資源相關配置
1、hostPID:是否允許Pod共享宿主機的進程空間
2、hostIPC:是否允許Pod共享宿主機的IPC命名空間
3、hostNetwork:是否允許Pod共享宿主機網絡的命名空間
4、hostPorts:是否允許Pod使用宿主機的端口號,可以通過hostPortRange字段設置允許使用的端口號范圍,以[min, max]設置最小端口號和最大端口號
5、Volumes:允許Pod使用的存儲卷Volume類型,設置為“*”表示允許使用任意Volume類型,建議至少允許Pod使用下列Volume類型。configMap,emptyDir、downwardAPI、persistentVolumeClaim、secret、projected
6、AllowedHostPaths:允許Pod使用宿主機的hostPath路徑名稱,可通過pathPrefix字段設置路徑的前綴,並可以設置是否只讀屬性,例如:只允許Pod訪問宿主機上以“/foo”為前綴的路徑,包 括“/foo”“/foo/”“/foo/bar”等,
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: all-hostpath-volumes
spec:
volumes:
- hostPath
allowedHostPaths:
- pathPrefix: "/foo"
readOnly: true
7、FSGroup:設置允許訪問某些Volume的Group ID范圍,可以將rule字段設置為ManyRunAs、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。
8、ReadOnlyRootFilesystem:要求容器運行的根文件系統(root filesystem)必須是只讀的
9、allowedFlexVolumes:對於類型為flexVolume的存儲卷,設置允許使用的驅動類型,例如:
apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: allowedflexvolumes spec: volumes: - flexVolume allowedFlexVolumes: - driver: example/lvm - driver: example/cifs
(3)用戶和組相關配置
1、RunAsUser:設置運行容器的用戶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都可以運行。
2、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的用戶都可以運行。
3、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的用戶都可以運行。
(4)提升權限相關配置
1、AllowPrivilegeEscalation:用於設置容器內的子進程是否可以提升權限,通常在設置非Root用戶(MustRunAsNonRoot)時進行設置。
2、DefaultAllowPrivilegeEscalation:設置AllowPrivilegeEscalation的默認值,設置為disallow時,管理員還可以顯式設置 AllowPrivilegeEscalation來指定是否允許提升權限。
(5)Linux能力相關配置
1、AllowedCapabilities:設置容器使用的linux能力列表,設置為“*”表示允許使用Linux的所有能力(如NET_ADMIN、SYS_TIME等)。
2、RequiredDropCapabilities:設置不允許容器使用的linux能力列表
3、DefaultAddCapabilities:設置默認為容器添加的Linux能力列表,例如SYS_TIME等
(6)SELinux相關配置
seLinux:設置SELinux參數,可以將規則字段(rule)的值設置為MustRunAs或RunAsAny。
MustRunAs:要求設置seLinuxOptions,系統將對Pod的securityContext.seLinuxOptions設置的值進行校驗。
RunAsAny:不限制seLinuxOptions的設置
(7)其它Linux相關配置
1、AllowedProcMountType:設置允許的PropMountTypes類型列表,可以設置allowedProcMountTypes或DefaultProcMount。
2、AppArmor:設置對容器可執行程序的訪問控制權限,
3、Seccomp:設置允許容器使用的系統調用(System Calls)的profile
4、Sysctl:設置允許調整的內核參數,
(8)列舉兩種常用的PodSecurityPolicy安全策略配置
1、基本沒有限制的安全策略,允許創建任意安全設置的Pod。
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: privileged
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: "*"
spec:
privileged: true #不允許創建特權模式的Pod
allowPrivilegeEscalation: true #設置子進程是否可以提升權限,配置MustRunAsNonRoot
allowedCapabilities:
- '*'
volumes:
- '*'
hostNetwork: true
hostPorts:
- min: 0
max: 65535
hostIPC: true
hostPID: true
runAsUser:
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'
2、要求Pod運行用戶為非特權用戶;禁止提升權限;不允許使用宿主機網絡、端口號、IPC等資源;限制可以使用的Volume類型,等等
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: retricted
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default'
seccomp.security.alpha.kubernetes.io/defaultProfileNames: 'docker/default'
apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default'
apparmor.security.beta.kubernetes.io/defaultProfileNames: 'runtime/default'
spec:
privileged: false
allowPrivilegeEscalation: false
requiredDropCapabilities:
- ALL
volumes:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
- 'persistentVolumeClaim'
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
rule: 'MustRunAsNonRoot'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'MustRunAsRoot'
ranges:
- min: 1
max: 65535
fsGroup:
rule: 'MustRunAsRoot'
ranges:
- min: 1
max: 65535
readOnlyRootFilesystem: false
Kubernetes建議使用RBAC授權機制來設置針對Pod安全策略的授權,通常應該對Pod的ServiceAccount進行授權。
例如,可以創建如下ClusterRole(也可以創建Role)並將其設置為允許使用PodSecurityPolicy:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: role-name rules: - apiGroups: ['policy'] resources: ['podsecuritypolicies'] verbs: ['use'] resourceNames: - #允許使用的PodSecurityPolicy列表
然后創建一個ClusterRoleBinding與用戶和ServiceAccount進行綁定
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: bind-name ruleRef: kind: ClusterRole name: role-name apiGroup: rabc.authorization.k8s.io subjects: - kind: ServiceAccount name: serviceaccount namespace: - kind: User name: username apiGroup: rbac.authorization.k8s.io
也可以創建RoleBinding對與該RoleBinding相同的Namespace中的Pod進行授權,通常可以與某個系統級別的Group關聯配置,例如:
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: bind-name namespace: namespace #該RoleBinding所屬的namespace roleRef: kind: Role name: apiGroup: rabc.authorization.k8s.io subjects: #授權該Namespace中的全部ServiceAccount - kind: Group apiGroup: rabc.authorization.k8s.io name: system:serviceaccounts #授權該Namespace的全部用戶 - kind: User apiGroup: rabc.authorization.k8s.io name: system:authenticated
Pod的安全設置詳解
Pod和容器的安全策略可以在Pod或Container的securityContext字段中設置,如果在Pod和Container級別都設置了相同的安全類型字段,容器將使用Container級別的設置。
在Pod級別可以設置的安全措施如下:
◎ runAsUser:容器內運行程序的用戶ID。
◎ 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相關設置。
例如:Pod級別的安全設置,作用於該Pod內的全部容器
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
volumes:
- name: sec-ctx-vol
emptyDir: {}
containers:
- name: sec-ctx-demo
image: nginx
volumeMounts:
- name: sec-ctx-demo
mountPath: /data/demo
securityContext:
allowPrivilegeEscalation: false
◎ runAsUser=1000:所有容器都將以User ID 1000運行程序,所有新生成文件的User ID也被設置為1000。
◎ runAsGroup=3000:所有容器都將以Group ID 3000運行程序,所有新生成文件的Group ID也被設置為3000。
◎ fsGroup=2000:掛載的卷“/data/demo”及其中創建的文件都將屬於Group ID 2000。
Container級別的安全設置,作用於特定的容器。
apiVersion: v1
kind: Pod
metadata:
name: scd-2
spec:
securityContext:
runAsUser: 1000
containers:
- name: scd-2
image: nginx:latest
imagePullPolicy: IfNotPresent
securityContext:
runAsUser: 2000
allowPrivilegeEscalation: false
為Container設置可用的Linux能力,為容器設置允許使用的Linux能力包括NET_ADMIN和SYS_TIME。
apiVersion: v1
kind: Pod
metadata:
name: scd-3
spec:
containers:
- name: scd-3
image: nginx
securityContext:
capabilities:
add: ["NET_ADMIN","SYS_TIME"]
===============================
我是Liusy,一個喜歡健身的程序員。
獲取更多干貨以及最新消息,請關注公眾號:上古偽神
如果對您有幫助,點個關注就是對我最大的支持!!!
