Pod容器想要獲取集羣的資源信息,須要配置角色和ServiceAccount進行受權。爲了更精細地控制Pod對資源的使用方式,Kubernetes從1.4版本開始引入了PodSecurityPolicy資源對象對Pod的安全策略進行管理。linux
容器內的進程得到的特權幾乎與容器外的進程相同。使用特權模式,能夠更容易地將網絡和卷插件編寫爲獨立的pod,不須要編譯到kubelet中。nginx
官網定義程序員
Pod 安全策略(Pod Security Policy) 是集羣級別的資源,它可以控制Pod規約 中與安全性相關的各個方面。PodSecurityPolicy 對象定義了一組Pod運行時必須遵循的條件及相關字段的默認值,只有 Pod 知足這些條件纔會被系統接受。docker
Pod 安全策略容許管理員控制以下方面:api
Pod 安全策略 由設置和策略組成,它們可以控制 Pod 訪問的安全特徵。這些設置分爲以下三類:安全
(1)基於布爾值控制 :這種類型的字段默認爲最嚴格限制的值。bash
(2)基於被容許的值集合控制 :這種類型的字段會與這組值進行對比,以確認值被容許。網絡
(3)基於策略控制 :設置項經過一種策略提供的機制來生成該值,這種機制可以確保指定的值落在被容許的這組值中。app
開啓flex
若是須要開啓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對象中能夠設置下列字段來控制Pod運行時的各類安全策略
(1)特權模式相關配置
privileged:是否容許Pod以特權模式運行
(2)宿主機資源相關配置
一、hostPID:是否容許Pod共享宿主機的進程空間
二、hostIPC:是否容許Pod共享宿主機的IPC命名空間
三、hostNetwork:是否容許Pod共享宿主機網絡的命名空間
四、hostPorts:是否容許Pod使用宿主機的端口號,能夠經過hostPortRange字段設置容許使用的端口號範圍,以[min, max]設置最小端口號和最大端口號
五、Volumes:容許Pod使用的存儲卷Volume類型,設置爲「*」表示容許使用任意Volume類型,建議至少容許Pod使用下列Volume類型。configMap,emptyDir、downwardAPI、persistentVolumeClaim、secret、projected
六、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
七、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。
八、ReadOnlyRootFilesystem:要求容器運行的根文件系統(root filesystem)必須是隻讀的
九、allowedFlexVolumes:對於類型爲flexVolume的存儲卷,設置容許使用的驅動類型,例如:
apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: allowedflexvolumes spec: volumes: - flexVolume allowedFlexVolumes: - driver: example/lvm - driver: example/cifs
(3)用戶和組相關配置
一、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均可以運行。
二、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的用戶均可以運行。
(4)提高權限相關配置
一、AllowPrivilegeEscalation:用於設置容器內的子進程是否能夠提高權限,一般在設置非Root用戶(MustRunAsNonRoot)時進行設置。
二、DefaultAllowPrivilegeEscalation:設置AllowPrivilegeEscalation的默認值,設置爲disallow時,管理員還能夠顯式設置 AllowPrivilegeEscalation來指定是否容許提高權限。
(5)Linux能力相關配置
一、AllowedCapabilities:設置容器使用的linux能力列表,設置爲「*」表示容許使用Linux的全部能力(如NET_ADMIN、SYS_TIME等)。
二、RequiredDropCapabilities:設置不容許容器使用的linux能力列表
三、DefaultAddCapabilities:設置默認爲容器添加的Linux能力列表,例如SYS_TIME等
(6)SELinux相關配置
seLinux:設置SELinux參數,能夠將規則字段(rule)的值設置爲MustRunAs或RunAsAny。
MustRunAs:要求設置seLinuxOptions,系統將對Pod的securityContext.seLinuxOptions設置的值進行校驗。
RunAsAny:不限制seLinuxOptions的設置
(7)其它Linux相關配置
一、AllowedProcMountType:設置容許的PropMountTypes類型列表,能夠設置allowedProcMountTypes或DefaultProcMount。
二、AppArmor:設置對容器可執行程序的訪問控制權限,
三、Seccomp:設置容許容器使用的系統調用(System Calls)的profile
四、Sysctl:設置容許調整的內核參數,
(8)列舉兩種經常使用的PodSecurityPolicy安全策略配置
一、基本沒有限制的安全策略,容許建立任意安全設置的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'
二、要求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或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,一個喜歡健身的程序員。
獲取更多幹貨以及最新消息,請關注公衆號:上古僞神
若是對您有幫助,點個關注就是對我最大的支持!!!