Pod安全策略
特性状态: Kubernetes v1.21 [deprecated]
PodSecurityPolicy在Kubernetes v1.21中已弃用,将在v1.25中被删除。有关弃用的更多信息,移步PodSecurityPolicy Deprecation: Past, Present, and Future
Pod安全策略支持对Pod创建和更新的细粒度授权。
Pod安全策略是用来做什么的?
Pod安全策略是一个集群级资源,它控制Pod规范的安全方面。
PodSecurityPolicy(PSP)对象定义了pod要进入系统必须运行的一组条件,以及相关字段的默认值。它们允许管理员控制以下内容:
| 控制面 | 字段名称 |
|---|---|
| 运行特权容器 | privileged |
| 主机命名空间的使用 | hostPID, hostIPC |
| 主机网络和端口的使用 | hostNetwork, hostPorts |
| 卷类型的使用 | volumes |
| 主机文件系统的使用 | allowedHostPaths |
| 允许特定的FlexVolume驱动程序 | allowedFlexVolumes |
| 分配一个拥有pod卷的FSGroup | fsGroup |
| 需要使用只读的根文件系统 | readOnlyRootFilesystem |
| 容器的用户和组id | runAsUser, runAsGroup, supplementalGroups |
| 限制升级到根权限 | allowPrivilegeEscalation, defaultAllowPrivilegeEscalation |
| Linux capabilities | defaultAddCapabilities, requiredDropCapabilities, allowedCapabilities |
| 容器的SELinux上下文 | seLinux |
| 容器允许的Proc挂载类型 | allowedProcMountTypes |
| 容器使用的AppArmor配置文件 | annotations |
| 容器使用的seccomp配置文件 | annotations |
| 容器使用的sysctl配置文件 | forbiddenSysctls,allowedUnsafeSysctls |
策略解析
Privileged
Privileged决定pod中的任何容器是否可以启用特权模式。默认情况下,容器不允许访问主机上的任何设备,但特权容器被授予访问主机上的所有设备的权限。
这允许容器与主机上运行的进程进行几乎相同的访问。这对于希望使用linux cap(如操作网络堆栈和访问设备)的容器(比如CSI容器)很有用
共享主机命名空间
HostPID: 控制pod是否可以共享主机Pid进程命名空间HostIPC: 控制pod是否可以共享主机IPC命名空间HostNetwork: 控制pod是否可以使用节点网络名称空间。这样做可以让pod访问环回设备、在本地主机上监听的服务,并且可以用来窥探同一节点上其他pod的网络活动。HostPorts: 结合HostNetwork提供主机网络名称空间中允许的端口范围的列表。定义为HostPortRange列表,包含min(包括)和max(包括)。默认为不允许主机端口。
卷与文件系统
Volumes: 提供允许的卷类型列表。允许值对应于创建卷时定义的卷源。有关卷类型的完整列表,请参见卷类型 。 此外,*可用于允许所有卷类型。 推荐的最小允许卷集:configMapdownwardAPIemptyDirpersistentVolumeClaimsecretprojected
注意: PodSecurityPolicy不会限制可被persistentvolumecclaim引用的PersistentVolume对象类型,
hostPath类型的PersistentVolumes不支持只读访问模式。
应该只向受信任的用户授予创建PersistentVolume对象的权限。
FSGroup: 控制应用于某些卷的补充组
MustRunAs: 要求至少指定一个范围。使用第一个范围的最小值作为默认值。针对所有范围进行验证。MayRunAs: 要求至少指定一个范围。允许不设置FSGroups而不提供默认值。如果设置了FSGroups,则对所有范围进行验证。RunAsAny: 没有提供默认。允许指定任意fsGroup ID。
AllowedHostPaths
指定hostPath卷允许使用的主机路径列表。空列表意味着对所使用的主机路径没有限制。
它被定义为一个带有单个pathPrefix字段的对象列表,该字段允许hostPath卷挂载以允许前缀开头的路径,并且readOnly字段指示它必须以只读方式挂载。
例如:
allowedHostPaths:
# This allows "/foo", "/foo/", "/foo/bar" etc., but
# disallows "/fool", "/etc/foo" etc.
# "/foo/../" is never valid.
- pathPrefix: "/foo"
readOnly: true # only allow read-only mounts
注意: 对主机文件系统具有无限制访问权限的容器可以通过多种方式升级特权,包括从其他容器读取数据,以及滥用系统服务(如Kubelet)的凭证。
可写hostPath目录卷允许容器以在pathPrefix之外遍历主机文件系统的方式写入文件系统。readOnly: true,在Kubernetes 1.11+中可用,必须在所有allowedHostPaths上使用,以有效地限制对指定pathPrefix的访问。
ReadOnlyRootFilesystem
要求容器必须在只读的根文件系统中运行(即没有可写层)。
用户和组
RunAsUser: 控制运行容器的用户IDMustRunAs: 要求至少指定一个范围。使用第一个范围的最小值作为默认值。针对所有范围进行验证MustRunAsNonRoot:- ``:
开启PSP
Pod安全策略控制是作为可选的允许控制器实现的,PodSecurityPolicies是通过启用允许控制器来执行的 ,但是在不授权任何策略的情况下执行将会阻止在集群中创建任何pod。
由于pod安全策略API (policy/v1beta1/podsecuritypolicy)是独立于许可控制器启用的,
因此对于现有集群,建议在启用许可控制器之前添加并授权策略。
授权策略
PodSecurityPolicy通过以下两个步骤使用:
- 创建
PodSecurityPolicy - 授权请求用户或目标
pod的服务帐户使用策略
大多数Kubernetes pod不是由用户直接创建的。
相反,它们通常是通过ControllerManager间接创建的,作为Deployment、ReplicaSet或其他模板化控制器的一部分。
授予控制器对策略的访问权将授予该控制器创建的所有pod的访问权,因此授权策略的首选方法是授予对pod服务帐户的访问权。
通过RBAC
RBAC是一种标准的Kubernetes授权模式,可以方便地对策略的使用进行授权。
首先,Role或ClusterRole需要授予使用所需策略的访问权限。授予访问权限的规则如下:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: <role name>
rules:
- apiGroups: ['policy']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames:
- <list of policies to authorize>
然后(Cluster)角色绑定到授权用户:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: <binding name>
roleRef:
kind: ClusterRole
name: <role name>
apiGroup: rbac.authorization.k8s.io
subjects:
# Authorize all service accounts in a namespace (recommended):
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:serviceaccounts:<authorized namespace>
# Authorize specific service accounts (not recommended):
- kind: ServiceAccount
name: <authorized service account name>
namespace: <authorized pod namespace>
# Authorize specific users (not recommended):
- kind: User
apiGroup: rbac.authorization.k8s.io
name: <authorized user name>
如果使用了RoleBinding(不是ClusterRoleBinding),它将只允许在与绑定相同的名称空间中运行pod。
这可以与系统组配对,以授予对名称空间中运行的所有pod的访问权限:
# Authorize all service accounts in a namespace:
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:serviceaccounts
# Or equivalently, all authenticated users in a namespace:
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:authenticated
最佳实践
PodSecurityPolicy正在被一个新的、简化的PodSecurity允许控制器所取代。遵循以下指导方针来简化从PodSecurityPolicy到新的允许控制器的迁移:
- 将
Pod安全策略限制为Pod安全标准定义的策略: - Privileged
- Baseline
通过
system:serviceaccounts:<namespace>将psp绑定到整个命名空间。例如:
apiVersion: rbac.authorization.k8s.io/v1
# This cluster role binding allows all pods in the "development" namespace to use the baseline PSP.
kind: ClusterRoleBinding
metadata:
name: psp-baseline-namespaces
roleRef:
kind: ClusterRole
name: psp-baseline
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: Group
name: system:serviceaccounts:development
apiGroup: rbac.authorization.k8s.io
- kind: Group
name: system:serviceaccounts:canary
apiGroup: rbac.authorization.k8s.io