Skip to main content

第 8 章:Pod 安全策略

PodSecurityPolicy 類型的物件能夠控制,是否可以向 Pod 發送請求,該 Pod 能夠影響被應用到 Pod 和容器的 SecurityContext

什麼是 Pod 安全策略?

Pod 安全策略 是叢集層級的資源,它能夠控制 Pod 運作的行為,以及它具有存取什麼的能力。  PodSecurityPolicy物件定義了一組條件,指示 Pod 必須依照系統所能接受的順序運作。 它們允許管理員控制如下方面:

控制面欄位名稱
已授權容器的運作privileged
為容器新增預設的一組能力defaultAddCapabilities
為容器去掉某些能力requiredDropCapabilities
容器能夠要求新增某些能力allowedCapabilities
控製卷類型的使用https://kubernetes.io/docs/concepts/policy/pod-security-policy/#controlling-volumes
主機網路的使用https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-network
主機連接埠的使用hostPorts
主機 PID namespace 的使用hostPID
主機 IPC namespace 的使用hostIPC
主機路徑的使用https://kubernetes.io/docs/concepts/policy/pod-security-policy/#allowed-host-paths
容器的 SELinux 上下文https://kubernetes.io/docs/concepts/policy/pod-security-policy/#selinux
使用者 IDhttps://kubernetes.io/docs/concepts/policy/pod-security-policy/#runasuser
配置允許的補充群組https://kubernetes.io/docs/concepts/policy/pod-security-policy/#supplementalgroups
指派擁有 Pod 資料卷的 FSGrouphttps://kubernetes.io/docs/concepts/policy/pod-security-policy/#fsgroup
必須使用一個唯讀的 root 檔案系統readOnlyRootFilesystem

Pod 安全策略 由設定和策略組成,它們能夠控制 Pod 存取的安全特性。 這些設定分為如下三類:

  • 基於布林值控制:這種類型的欄位預設為最嚴格限制的值。
  • 基於被允許的值集合控制:這種類型的欄位會與這組值進行對比,以確認值被允許。
  • 基於策略控制:設定項透過一種策略提供的機制來產生該值,此機制能夠確保指定的值落在被允許的這組值中。

RunAsUser

  • MustRunAs - 必須設定一個 range。 使用該範圍內的第一個值作為預設值。 驗證是否不在配置的該範圍內。
  • MustRunAsNonRoot - 要求提交的 Pod 具有非零 runAsUser 值,或在鏡像中定義了 USER 環境變數。 不提供預設值。
  • RunAsAny - 沒有提供預設值。 允許指定任何 runAsUser 。

SELinux

  • MustRunAs - 如果沒有使用預先指派的值,必須設定 seLinuxOptions。 預設使用 seLinuxOptions。 驗證 seLinuxOptions
  • RunAsAny - 沒有提供預設值。 允許任意指定的 seLinuxOptions ID。

SupplementalGroups

  • MustRunAs - 至少需要指定一個範圍。 預設使用第一個範圍的最小值。 驗證所有範圍的值。
  • RunAsAny - 沒有提供預設值。 允許任意指定的 supplementalGroups ID。

FSGroup

  • MustRunAs - 至少需要指定一個範圍。 預設使用第一個範圍的最小值。 驗證在第一個範圍內的第一個 ID。
  • RunAsAny - 沒有提供預設值。 允許任意指定的 fsGroup ID。

控製磁碟區

透過設定 PSP 卷字段,能夠控制具體卷類型的使用。 當建立一個磁碟區的時候,與該欄位相關的已定義磁碟區可以允許設定如下值:

可允許磁碟區的值
1. azureFile
2. azureDisk
3. flocker
4. flexVolume
5. hostPath
6. emptyDir
7. gcePersistentDisk
8. awsElasticBlockStore
9. gitRepo
10. secret
11. nfs
12. iscsi
13. glusterfs
14. persistentVolumeClaim
15. rbd
16. cinder
17. cephFS
18. downwardAPI
19. fc
20. configMap
21. vsphereVolume
22. quobyte
23. photonPersistentDisk
24. projected
25. portworxVolume
26. scaleIO
27. storageos
28. (allow all volumes)

對於新的 PSP,建議允許的磁碟區的最小集合包括:configMap、downwardAPI、emptyDir、persistentVolumeClaim、secret 和 projected。

主機網路

  • HostPorts,預設為 emptyHostPortRange 清單透過 min(包含) and max(包含) 來定義,指定了被允許的主機連接埠。

允許的主機路徑

  • AllowedHostPaths 是一個被允許的主機路徑前綴的白名單。 空值表示所有的主機路徑都可以使用。

許可

包含 PodSecurityPolicy 的 授權控制,允許控制叢集資源的建立和修改,基於這些資源在叢集範圍內被授權的能力。

許可使用如下的方式為 Pod 建立最終的安全上下文:

  1. 檢索所有可用的 PSP。
  2. 產生在請求中沒有指定的安全上下文設定的欄位值。
  3. 基於可用的策略,驗證最終的設定。

如果某個策略能夠配對上,該 Pod 就被接受。 如果要求與 PSP 不匹配,則 Pod 被拒絕。

Pod 必須基於 PSP 驗證每個欄位。

建立 Pod 安全策略

以下是一個 Pod 安全策略的例子,所有欄位的設定都被允許:

apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
name: permissive
spec:
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
runAsUser:
rule: RunAsAny
fsGroup:
rule: RunAsAny
hostPorts:
- min: 8000
max: 8080
volumes:
- '*'

下載範例檔案可以建立該策略,然後執行以下命令:

kubectl create -f ./psp.yaml podsecuritypolicy "permissive" created

取得 Pod 安全性原則列表

取得已存在策略列表,使用 kubectl get

kubectl get psp NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP READONLYROOTFS VOLUMES permissive false [] RunAsAny RunAsAny RunAsAny RunAsAny false [*] privileged true [] RunAsAny RunAsAny RunAsAny RunAsAny false [*] restricted false [] RunAsAny MustRunAsNonRoot RunAsAny RunAsAny false [emptyDir secret downwardAPI configMap persistentVolumeClaim projected]

修改 Pod 安全策略

透過互動方式修改策略,使用 kubectl edit

$ kubectl edit psp permissive

該命令將開啟一個預設文字編輯器,在這裡能夠修改策略。

刪除 Pod 安全性策略

一旦不再需要一個策略,很容易透過 kubectl 刪除它:

$ kubectl delete psp permissive podsecuritypolicy "permissive" deleted

啟用 Pod 安全性策略

為了能夠在叢集中使用 Pod 安全策略,必須確保如下:

  1. 啟用 API 類型 extensions/v1beta1/podsecuritypolicy(僅限 1.6 之前的版本)
  2. 啟用授權控制器 PodSecurityPolicy
  3. 定義自己的策略

使用 RBAC

在 Kubernetes 1.5 或更新版本,可以使用 PodSecurityPolicy 來控制,對基於使用者角色和群組的已授權容器的存取。 存取不同的 PodSecurityPolicy 對象,可以基於認證來控制。 基於Deployment、ReplicaSet 等創建的Pod,限制訪問PodSecurityPolicy 對象,Controller Manager 必須基於安全API 連接埠運行,並且無法具有超級 使用者權限。

PodSecurityPolicy 認證使用所有可用的策略,包括建立 Pod 的用戶,Pod 上指定的服務帳戶(service acount)。 當 Pod 是基於 Deployment、ReplicaSet 創建時,它是創建 Pod 的 Controller Manager,所以如果基於非安全 API 連接埠運行,允許所有的 PodSecurityPolicy 對象,並且不能夠有效地實現細分權限。 使用者存取給定的 PSP 策略有效,僅當是直接部署 Pod 的情況。 當直接部署 Pod 時,應用 PodSecurityPolicy 控制基於角色和群組的已授權容器的存取。