# Pod 安全策略
`PodSecurityPolicy` 類型的對象能夠控制,是否可以向 Pod 發送請求,該 Pod 能夠影響被應用到 Pod 和容器的 `SecurityContext`。 查看 [Pod 安全策略建議](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/auth/pod-security-policy.md) 獲取更多信息。
## 什么是 Pod 安全策略?
*Pod 安全策略* 是集群級別的資源,它能夠控制 Pod 運行的行為,以及它具有訪問什么的能力。 `PodSecurityPolicy`對象定義了一組條件,指示 Pod 必須按系統所能接受的順序運行。 它們允許管理員控制如下方面:
| 控制面 | 字段名稱 |
| --------------------- | ---------------------------------------- |
| 已授權容器的運行 | `privileged` |
| 為容器添加默認的一組能力 | `defaultAddCapabilities` |
| 為容器去掉某些能力 | `requiredDropCapabilities` |
| 容器能夠請求添加某些能力 | `allowedCapabilities` |
| 控制卷類型的使用 | [`volumes`](https://kubernetes.io/docs/concepts/policy/pod-security-policy/#controlling-volumes) |
| 主機網絡的使用 | [`hostNetwork`](https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-network) |
| 主機端口的使用 | `hostPorts` |
| 主機 PID namespace 的使用 | `hostPID` |
| 主機 IPC namespace 的使用 | `hostIPC` |
| 主機路徑的使用 | [`allowedHostPaths`](https://kubernetes.io/docs/concepts/policy/pod-security-policy/#allowed-host-paths) |
| 容器的 SELinux 上下文 | [`seLinux`](https://kubernetes.io/docs/concepts/policy/pod-security-policy/#selinux) |
| 用戶 ID | [`runAsUser`](https://kubernetes.io/docs/concepts/policy/pod-security-policy/#runasuser) |
| 配置允許的補充組 | [`supplementalGroups`](https://kubernetes.io/docs/concepts/policy/pod-security-policy/#supplementalgroups) |
| 分配擁有 Pod 數據卷的 FSGroup | [`fsGroup`](https://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*, 默認為 `empty`。`HostPortRange` 列表通過 `min`(包含) and `max`(包含) 來定義,指定了被允許的主機端口。
### 允許的主機路徑
- *AllowedHostPaths* 是一個被允許的主機路徑前綴的白名單。空值表示所有的主機路徑都可以使用。
## 許可
包含 `PodSecurityPolicy` 的 *許可控制*,允許控制集群資源的創建和修改,基于這些資源在集群范圍內被許可的能力。
許可使用如下的方式為 Pod 創建最終的安全上下文:
1. 檢索所有可用的 PSP。
2. 生成在請求中沒有指定的安全上下文設置的字段值。
3. 基于可用的策略,驗證最終的設置。
如果某個策略能夠匹配上,該 Pod 就被接受。如果請求與 PSP 不匹配,則 Pod 被拒絕。
Pod 必須基于 PSP 驗證每個字段。
## 創建 Pod 安全策略
下面是一個 Pod 安全策略的例子,所有字段的設置都被允許:
```yaml
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:
- '*'
```
下載示例文件可以創建該策略,然后執行如下命令:
```bash
$ kubectl create -f ./psp.yaml
podsecuritypolicy "permissive" created
```
## 獲取 Pod 安全策略列表
獲取已存在策略列表,使用 `kubectl get`:
```bash
$ 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`:
```bash
$ kubectl edit psp permissive
```
該命令將打開一個默認文本編輯器,在這里能夠修改策略。
## 刪除 Pod 安全策略
一旦不再需要一個策略,很容易通過 `kubectl` 刪除它:
```bash
$ 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](https://kubernetes.io/docs/admin/kube-controller-manager/) 必須基于安全 API 端口運行,并且不能夠具有超級用戶權限。
PodSecurityPolicy 認證使用所有可用的策略,包括創建 Pod 的用戶,Pod 上指定的服務賬戶(service acount)。當 Pod 基于 Deployment、ReplicaSet 創建時,它是創建 Pod 的 Controller Manager,所以如果基于非安全 API 端口運行,允許所有的 PodSecurityPolicy 對象,并且不能夠有效地實現細分權限。用戶訪問給定的 PSP 策略有效,僅當是直接部署 Pod 的情況。當直接部署 Pod 時,應用 PodSecurityPolicy 控制基于角色和組的已授權容器的訪問 。
原文地址:https://k8smeetup.github.io/docs/concepts/policy/pod-security-policy/
譯者:[shirdrn](https://github.com/shirdrn)
- 序言
- 云原生
- 云原生(Cloud Native)的定義
- CNCF - 云原生計算基金會簡介
- CNCF章程
- 云原生的設計哲學
- Play with Kubernetes
- 快速部署一個云原生本地實驗環境
- Kubernetes與云原生應用概覽
- 云原生應用之路——從Kubernetes到Cloud Native
- 云原生編程語言
- 云原生編程語言Ballerina
- 云原生編程語言Pulumi
- 云原生的未來
- Kubernetes架構
- 設計理念
- Etcd解析
- 開放接口
- CRI - Container Runtime Interface(容器運行時接口)
- CNI - Container Network Interface(容器網絡接口)
- CSI - Container Storage Interface(容器存儲接口)
- Kubernetes中的網絡
- Kubernetes中的網絡解析——以flannel為例
- Kubernetes中的網絡解析——以calico為例
- 具備API感知的網絡和安全性管理開源軟件Cilium
- Cilium架構設計與概念解析
- 資源對象與基本概念解析
- Pod狀態與生命周期管理
- Pod概覽
- Pod解析
- Init容器
- Pause容器
- Pod安全策略
- Pod的生命周期
- Pod Hook
- Pod Preset
- Pod中斷與PDB(Pod中斷預算)
- 集群資源管理
- Node
- Namespace
- Label
- Annotation
- Taint和Toleration(污點和容忍)
- 垃圾收集
- 控制器
- Deployment
- StatefulSet
- DaemonSet
- ReplicationController和ReplicaSet
- Job
- CronJob
- Horizontal Pod Autoscaling
- 自定義指標HPA
- 準入控制器(Admission Controller)
- 服務發現
- Service
- Ingress
- Traefik Ingress Controller
- 身份與權限控制
- ServiceAccount
- RBAC——基于角色的訪問控制
- NetworkPolicy
- 存儲
- Secret
- ConfigMap
- ConfigMap的熱更新
- Volume
- Persistent Volume(持久化卷)
- Storage Class
- 本地持久化存儲
- 集群擴展
- 使用自定義資源擴展API
- 使用CRD擴展Kubernetes API
- Aggregated API Server
- APIService
- Service Catalog
- 資源調度
- QoS(服務質量等級)
- 用戶指南
- 資源對象配置
- 配置Pod的liveness和readiness探針
- 配置Pod的Service Account
- Secret配置
- 管理namespace中的資源配額
- 命令使用
- Docker用戶過度到kubectl命令行指南
- kubectl命令概覽
- kubectl命令技巧大全
- 使用etcdctl訪問kubernetes數據
- 集群安全性管理
- 管理集群中的TLS
- kubelet的認證授權
- TLS bootstrap
- 創建用戶認證授權的kubeconfig文件
- IP偽裝代理
- 使用kubeconfig或token進行用戶身份認證
- Kubernetes中的用戶與身份認證授權
- Kubernetes集群安全性配置最佳實踐
- 訪問Kubernetes集群
- 訪問集群
- 使用kubeconfig文件配置跨集群認證
- 通過端口轉發訪問集群中的應用程序
- 使用service訪問群集中的應用程序
- 從外部訪問Kubernetes中的Pod
- Cabin - Kubernetes手機客戶端
- Kubernetic - Kubernetes桌面客戶端
- Kubernator - 更底層的Kubernetes UI
- 在Kubernetes中開發部署應用
- 適用于kubernetes的應用開發部署流程
- 遷移傳統應用到Kubernetes中——以Hadoop YARN為例
- 最佳實踐概覽
- 在CentOS上部署Kubernetes集群
- 創建TLS證書和秘鑰
- 創建kubeconfig文件
- 創建高可用etcd集群
- 安裝kubectl命令行工具
- 部署master節點
- 安裝flannel網絡插件
- 部署node節點
- 安裝kubedns插件
- 安裝dashboard插件
- 安裝heapster插件
- 安裝EFK插件
- 生產級的Kubernetes簡化管理工具kubeadm
- 使用kubeadm在Ubuntu Server 16.04上快速構建測試集群
- 服務發現與負載均衡
- 安裝Traefik ingress
- 分布式負載測試
- 網絡和集群性能測試
- 邊緣節點配置
- 安裝Nginx ingress
- 安裝配置DNS
- 安裝配置Kube-dns
- 安裝配置CoreDNS
- 運維管理
- Master節點高可用
- 服務滾動升級
- 應用日志收集
- 配置最佳實踐
- 集群及應用監控
- 數據持久化問題
- 管理容器的計算資源
- 集群聯邦
- 存儲管理
- GlusterFS
- 使用GlusterFS做持久化存儲
- 使用Heketi作為Kubernetes的持久存儲GlusterFS的external provisioner
- 在OpenShift中使用GlusterFS做持久化存儲
- GlusterD-2.0
- Ceph
- 用Helm托管安裝Ceph集群并提供后端存儲
- 使用Ceph做持久化存儲
- 使用rbd-provisioner提供rbd持久化存儲
- OpenEBS
- 使用OpenEBS做持久化存儲
- Rook
- NFS
- 利用NFS動態提供Kubernetes后端存儲卷
- 集群與應用監控
- Heapster
- 使用Heapster獲取集群和對象的metric數據
- Prometheus
- 使用Prometheus監控kubernetes集群
- Prometheus查詢語言PromQL使用說明
- 使用Vistio監控Istio服務網格中的流量
- 分布式跟蹤
- OpenTracing
- 服務編排管理
- 使用Helm管理Kubernetes應用
- 構建私有Chart倉庫
- 持續集成與發布
- 使用Jenkins進行持續集成與發布
- 使用Drone進行持續集成與發布
- 更新與升級
- 手動升級Kubernetes集群
- 升級dashboard
- 領域應用概覽
- 微服務架構
- 微服務中的服務發現
- 使用Java構建微服務并發布到Kubernetes平臺
- Spring Boot快速開始指南
- Service Mesh 服務網格
- 企業級服務網格架構
- Service Mesh基礎
- Service Mesh技術對比
- 采納和演進
- 定制和集成
- 總結
- Istio
- 安裝并試用Istio service mesh
- 配置請求的路由規則
- 安裝和拓展Istio service mesh
- 集成虛擬機
- Istio中sidecar的注入規范及示例
- 如何參與Istio社區及注意事項
- Istio教程
- Istio免費學習資源匯總
- 深入理解Istio Service Mesh中的Envoy Sidecar注入與流量劫持
- 深入理解Istio Service Mesh中的Envoy Sidecar代理的路由轉發
- Linkerd
- Linkerd 使用指南
- Conduit
- Condiut概覽
- 安裝Conduit
- Envoy
- Envoy的架構與基本術語
- Envoy作為前端代理
- Envoy mesh教程
- SOFAMesh
- SOFAMesh中的Dubbo on x-protocol
- SOFAMosn
- 使用 SOFAMosn 構建 SOFAMesh
- 大數據
- Spark standalone on Kubernetes
- 運行支持Kubernetes原生調度的Spark程序
- Serverless架構
- 理解Serverless
- FaaS-函數即服務
- OpenFaaS快速入門指南
- 邊緣計算
- 人工智能