一文讀懂k8s之Pod安全策略

導讀

Pod容器想要獲取集羣的資源信息,須要配置角色和ServiceAccount進行受權。爲了更精細地控制Pod對資源的使用方式,Kubernetes從1.4版本開始引入了PodSecurityPolicy資源對象對Pod的安全策略進行管理。linux

Pod特權模式

容器內的進程得到的特權幾乎與容器外的進程相同。使用特權模式,能夠更容易地將網絡和卷插件編寫爲獨立的pod,不須要編譯到kubelet中。nginx

PodSecurityPolicy

官網定義程序員

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配置詳解

在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和容器的安全策略能夠在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,一個喜歡健身的程序員。

獲取更多幹貨以及最新消息,請關注公衆號:上古僞神

若是對您有幫助,點個關注就是對我最大的支持!!!

相關文章
相關標籤/搜索