Pod 安全策略
Kubernetes v1.21 [deprecated]
PodSecurityPolicy 在 Kubernetes v1.21 版本中被弃用,将在 v1.25 中删除。 我们建议迁移到 Pod 安全性准入, 或者第三方的准入插件。 若需了解迁移指南,可参阅从 PodSecurityPolicy 迁移到内置的 PodSecurity 准入控制器。 关于弃用的更多信息,请查阅 PodSecurityPolicy Deprecation: Past, Present, and Future。
Pod 安全策略使得对 Pod 创建和更新进行细粒度的权限控制成为可能。
什么是 Pod 安全策略?
**Pod 安全策略(Pod Security Policy)**是集群级别的资源,它能够控制 Pod 规约中与安全性相关的各个方面。 PodSecurityPolicy 对象定义了一组 Pod 运行时必须遵循的条件及相关字段的默认值,只有 Pod 满足这些条件才会被系统接受。 Pod 安全策略允许管理员控制如下操作:
控制的角度 | 字段名称 |
---|---|
运行特权容器 | privileged |
使用宿主名字空间 | hostPID 、hostIPC |
使用宿主的网络和端口 | hostNetwork 、hostPorts |
控制卷类型的使用 | volumes |
使用宿主文件系统 | allowedHostPaths |
允许使用特定的 FlexVolume 驱动 | allowedFlexVolumes |
分配拥有 Pod 卷的 FSGroup 账号 | fsGroup |
以只读方式访问根文件系统 | readOnlyRootFilesystem |
设置容器的用户和组 ID | runAsUser 、runAsGroup 、supplementalGroups |
限制 root 账号特权级提升 | allowPrivilegeEscalation 、defaultAllowPrivilegeEscalation |
Linux 权能字(Capabilities) | defaultAddCapabilities 、requiredDropCapabilities 、allowedCapabilities |
设置容器的 SELinux 上下文 | seLinux |
指定容器可以挂载的 proc 类型 | allowedProcMountTypes |
指定容器使用的 AppArmor 模板 | annotations |
指定容器使用的 seccomp 模板 | annotations |
指定容器使用的 sysctl 模板 | forbiddenSysctls 、allowedUnsafeSysctls |
启用 Pod 安全策略
Pod 安全策略实现为一种可选的准入控制器。 启用了准入控制器即可强制实施 Pod 安全策略,不过如果没有授权认可策略之前即启用准入控制器将导致集群中无法创建任何 Pod。
由于 Pod 安全策略 API(policy/v1beta1/podsecuritypolicy
)是独立于准入控制器来启用的,
对于现有集群而言,建议在启用准入控制器之前先添加策略并对其授权。
授权策略
PodSecurityPolicy 资源被创建时,并不执行任何操作。为了使用该资源,
需要对发出请求的用户或者目标 Pod
的服务账号授权,
通过允许其对策略执行 use
动作,以允许其使用该策略。
大多数 Kubernetes Pod 不是由用户直接创建的。相反,这些 Pod 是由 Deployment、 ReplicaSet 或者经由控制器管理器模板化的控制器创建。 赋予控制器访问策略的权限意味着对应控制器所创建的所有 Pod 都可访问策略。 因此,对策略进行授权的优先方案是为 Pod 的服务账号授予访问权限 (参见示例)。
通过 RBAC 授权
RBAC 是一种标准的 Kubernetes 鉴权模式,可以很容易地用来授权策略访问。
首先,某 Role
或 ClusterRole
需要获得使用 use
访问目标策略的权限。
访问授权的规则看起来像这样:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: <Role 名称>
rules:
- apiGroups: ['policy']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames:
- <要授权的策略列表>
接下来将该 Role
(或 ClusterRole
)绑定到授权的用户:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: <绑定名称>
roleRef:
kind: ClusterRole
name: <角色名称>
apiGroup: rbac.authorization.k8s.io
subjects:
# 授权命名空间下的所有服务账号(推荐):
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:serviceaccounts:<authorized namespace>
# 授权特定的服务账号(不建议这样操作):
- kind: ServiceAccount
name: <被授权的服务账号名称>
namespace: <被授权的 Pod 名字空间>
# 授权特定的用户(不建议这样操作):
- kind: User
apiGroup: rbac.authorization.k8s.io
name: <被授权的用户名>
如果使用的是 RoleBinding
(而不是 ClusterRoleBinding
),授权仅限于与该
RoleBinding
处于同一名字空间中的 Pod。
可以考虑将这种授权模式和系统组结合,对名字空间中的所有 Pod 授予访问权限。
# 授权某名字空间中所有服务账号
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:serviceaccounts
# 或者与此等价,授权给某名字空间中所有被认证过的用户
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:authenticated
参阅角色绑定示例查看 RBAC 绑定的更多实例。 参阅下文,查看对 PodSecurityPolicy 进行授权的完整示例。
推荐实践
PodSecurityPolicy 正在被一个新的、简化的 PodSecurity
准入控制器替代。
有关此变更的更多详细信息,请参阅
PodSecurityPolicy Deprecation: Past, Present, and Future。
参照下述指导,简化从 PodSecurityPolicy 迁移到新的准入控制器步骤:
将 PodSecurityPolicies 限制为 Pod 安全性标准所定义的策略:
通过配置
system:serviceaccounts:<namespace>
组(<namespace>
是目标名字空间), 仅将 PSP 绑定到整个命名空间。示例:apiVersion: rbac.authorization.k8s.io/v1 # 此集群角色绑定允许 "development" 名字空间中的所有 Pod 使用 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
故障排查
控制器管理器组件 必须运行在安全的 API 端口之上,并且不能拥有超级用户的访问权限。 参阅控制 Kubernetes API 的访问以了解 API 服务器的访问控制。
如果控制器管理器通过可信的 API 端口连接(也称作
localhost
监听组件), 其请求会绕过身份认证和鉴权模块控制,从而导致所有 PodSecurityPolicy 对象都被允许, 用户亦能授予自身创建特权容器的特权。关于配置控制器管理器鉴权的进一步细节, 请参阅控制器角色。
策略顺序
除了限制 Pod 创建与更新,Pod 安全策略也可用来为其所控制的很多字段设置默认值。 当存在多个策略对象时,Pod 安全策略控制器依据以下条件选择策略:
- 优先考虑允许 Pod 保持原样,不会更改 Pod 字段默认值或其他配置的 PodSecurityPolicy。 这类非更改性质的 PodSecurityPolicy 对象之间的顺序无关紧要。
- 如果必须要为 Pod 设置默认值或者其他配置,(按名称顺序)选择第一个允许 Pod 操作的 PodSecurityPolicy 对象。
当根据 PodSecurityPolicy 对一个 Pod 进行验证时,会为 Pod 添加
一个 kubernetes.io/psp
注释会被添加到 Pod 中,
注解的值为 PodSecurityPolicy 的名称。
在更新操作期间(这时不允许更改 Pod 规约),仅使用非更改性质的 PodSecurityPolicy 来对 Pod 执行验证操作。
示例
本示例假定你已经有一个启动了 PodSecurityPolicy 准入控制器的集群并且你拥有集群管理员特权。
配置
为运行此示例,配置一个名字空间和一个服务账号。我们将用这个服务账号来模拟一个非管理员账号的用户。
kubectl create namespace psp-example
kubectl create serviceaccount -n psp-example fake-user
kubectl create rolebinding -n psp-example fake-editor --clusterrole=edit --serviceaccount=psp-example:fake-user
创建两个别名,以更清晰地展示我们所使用的用户账号,同时减少一些键盘输入:
alias kubectl-admin='kubectl -n psp-example'
alias kubectl-user='kubectl --as=system:serviceaccount:psp-example:fake-user -n psp-example'
创建一个策略和一个 Pod
下面是一个防止创建特权 Pod 的策略。
PodSecurityPolicy 对象的名称必须是合法的 DNS 子域名。
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: example
spec:
privileged: false # 不允许提权的 Pod!
# 以下内容负责填充一些必需字段。
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
runAsUser:
rule: RunAsAny
fsGroup:
rule: RunAsAny
volumes:
- '*'
使用 kubectl 执行创建操作:
kubectl-admin create -f https://k8s.io/examples/policy/example-psp.yaml
现在,作为一个非特权用户,尝试创建一个简单的 Pod:
kubectl-user create -f- <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pause
spec:
containers:
- name: pause
image: k8s.gcr.io/pause
EOF
输出类似于:
Error from server (Forbidden): error when creating "STDIN": pods "pause" is forbidden: unable to validate against any pod security policy: []
发生了什么? 尽管 PodSecurityPolicy 被创建,Pod 的服务账号或者
fake-user
用户都没有使用该策略的权限。
kubectl-user auth can-i use podsecuritypolicy/example
输出类似于:
no
创建角色绑定,赋予 fake-user
use
(使用)示例策略的权限:
不建议使用这种方法! 欲了解优先考虑的方法,请参见下节。
kubectl-admin create role psp:unprivileged \
--verb=use \
--resource=podsecuritypolicy \
--resource-name=example
输出:
role "psp:unprivileged" created
kubectl-admin create rolebinding fake-user:psp:unprivileged \
--role=psp:unprivileged \
--serviceaccount=psp-example:fake-user
输出:
rolebinding "fake-user:psp:unprivileged" created
kubectl-user auth can-i use podsecuritypolicy/example
输出:
yes
现在重试创建 Pod:
kubectl-user create -f- <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pause
spec:
containers:
- name: pause
image: k8s.gcr.io/pause
EOF
输出类似于:
pod "pause" created
此次尝试不出所料地成功了! 你可以验证 Pod 是根据新创建的 PodSecurityPolicy 验证的。
kubectl-user get pod pause -o yaml | grep kubernetes.io/psp
输出类似于:
kubernetes.io/psp: example
但任何试图创建特权 Pod 的请求仍然会被拒绝。
kubectl-user create -f- <<EOF
apiVersion: v1
kind: Pod
metadata:
name: privileged
spec:
containers:
- name: pause
image: k8s.gcr.io/pause
securityContext:
privileged: true
EOF
输出类似于:
Error from server (Forbidden): error when creating "STDIN": pods "privileged" is forbidden: unable to validate against any pod security policy: [spec.containers[0].securityContext.privileged: Invalid value: true: Privileged containers are not allowed]
继续此例之前先删除该 Pod:
kubectl-user delete pod pause
运行另一个 Pod
我们再试一次,稍微有些不同:
kubectl-user create deployment pause --image=k8s.gcr.io/pause
输出为:
deployment "pause" created
kubectl-user get pods
输出为:
No resources found.
kubectl-user get events | head -n 2
输出为:
LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON SOURCE MESSAGE
1m 2m 15 pause-7774d79b5 ReplicaSet Warning FailedCreate replicaset-controller Error creating: pods "pause-7774d79b5-" is forbidden: no providers available to validate pod request
发生了什么? 我们已经为用户 fake-user
绑定了 psp:unprivileged
角色,
为什么还会收到错误 Error creating: pods "pause-7774d79b5-" is forbidden: no providers available to validate pod request (创建错误:pods "pause-7774d79b5" 被禁止:没有可用来验证 pod 请求的驱动)
?
答案在于源文件 - replicaset-controller
。
fake-user
用户成功地创建了 Deployment,而后者也成功地创建了 ReplicaSet,
不过当 ReplicaSet 创建 Pod 时,发现未被授权使用示例 PodSecurityPolicy 资源。
为了修复这一问题,将 psp:unprivileged
角色绑定到 Pod 的服务账号。
在这里,因为我们没有给出服务账号名称,默认的服务账号是 default
。
kubectl-admin create rolebinding default:psp:unprivileged \
--role=psp:unprivileged \
--serviceaccount=psp-example:default
输出为:
rolebinding "default:psp:unprivileged" created
现在如果你给 ReplicaSet 控制器一分钟的时间来重试,该控制器最终将能够成功地创建 Pod:
kubectl-user get pods --watch
输出类似于:
NAME READY STATUS RESTARTS AGE
pause-7774d79b5-qrgcb 0/1 Pending 0 1s
pause-7774d79b5-qrgcb 0/1 Pending 0 1s
pause-7774d79b5-qrgcb 0/1 ContainerCreating 0 1s
pause-7774d79b5-qrgcb 1/1 Running 0 2s
清理
删除名字空间即可清理大部分示例资源:
kubectl-admin delete ns psp-example
输出类似于:
namespace "psp-example" deleted
注意 PodSecurityPolicy
资源不是名字空间域的资源,必须单独清理:
kubectl-admin delete psp example
输出类似于:
podsecuritypolicy "example" deleted
示例策略
下面是一个你可以创建的约束性非常弱的策略,其效果等价于没有使用 Pod 安全策略准入控制器:
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: privileged
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*'
spec:
privileged: true
allowPrivilegeEscalation: true
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'
下面是一个具有约束性的策略,要求用户以非特权账号运行,禁止可能的向 root 权限的升级, 同时要求使用若干安全机制。
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: restricted
annotations:
# docker/default 标识 seccomp 的配置文件,但它与 Docker 运行时没有特别关联
seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default,runtime/default'
apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default'
apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'
spec:
privileged: false
# 防止权限升级到 root
allowPrivilegeEscalation: false
requiredDropCapabilities:
- ALL
# 允许的核心卷类型.
volumes:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
# 假设集群管理员设置的临时 CSI 驱动程序和持久卷可以安全使用
- 'csi'
- 'persistentVolumeClaim'
- 'ephemeral'
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
# 要求容器在没有 root 权限的情况下运行
rule: 'MustRunAsNonRoot'
seLinux:
# 此策略假定节点使用 AppArmor 而不是 SELinux
rule: 'RunAsAny'
supplementalGroups:
rule: 'MustRunAs'
ranges:
# 禁止添加 root 组
- min: 1
max: 65535
fsGroup:
rule: 'MustRunAs'
ranges:
# 禁止添加 root 组
- min: 1
max: 65535
readOnlyRootFilesystem: false
更多的示例可参考 Pod 安全标准。
策略参考
Privileged
Privileged - 决定是否 Pod 中的某容器可以启用特权模式。 默认情况下,容器是不可以访问宿主上的任何设备的,不过一个“privileged(特权的)” 容器则被授权访问宿主上所有设备。 这种容器几乎享有宿主上运行的进程的所有访问权限。 对于需要使用 Linux 权能字(如操控网络堆栈和访问设备)的容器而言是有用的。
宿主名字空间
HostPID - 控制 Pod 中容器是否可以共享宿主上的进程 ID 空间。
注意,如果与 ptrace
相结合,这种授权可能被利用,导致向容器外的特权逃逸
(默认情况下 ptrace
是被禁止的)。
HostIPC - 控制 Pod 容器是否可共享宿主上的 IPC 名字空间。
HostNetwork - 控制是否 Pod 可以使用节点的网络名字空间。 此类授权将允许 Pod 访问本地回路(loopback)设备、在本地主机(localhost) 上监听的服务、还可能用来监听同一节点上其他 Pod 的网络活动。
HostPorts - 提供可以在宿主网络名字空间中可使用的端口范围列表。
该属性定义为一组 HostPortRange
对象的列表,每个对象中包含
min
(含)与 max
(含)值的设置。
默认不允许访问宿主端口。
卷和文件系统
Volumes - 提供一组被允许的卷类型列表。可被允许的值对应于创建卷时可以设置的卷来源。
卷类型的完整列表可参见卷类型。
此外,*
可以用来允许所有卷类型。
对于新的 Pod 安全策略设置而言,建议设置的卷类型的最小列表包含:
configMap
downwardAPI
emptyDir
persistentVolumeClaim
secret
projected
PodSecurityPolicy 并不限制可以被 PersistentVolumeClaim
所引用的
PersistentVolume
对象的类型。
此外 hostPath
类型的 PersistentVolume
不支持只读访问模式。
应该仅赋予受信用户创建 PersistentVolume
对象的访问权限。
FSGroup - 控制应用到某些卷上的附加用户组。
- MustRunAs - 要求至少指定一个
range
。 使用范围中的最小值作为默认值。所有 range 值都会被用来执行验证。 - MayRunAs - 要求至少指定一个
range
。 允许不设置FSGroups
,且无默认值。 如果FSGroup
被设置,则所有 range 值都会被用来执行验证检查。 - RunAsAny - 不提供默认值。允许设置任意
fsGroup
ID 值。
AllowedHostPaths - 设置一组宿主文件目录,这些目录项可以在 hostPath
卷中使用。
列表为空意味着对所使用的宿主目录没有限制。
此选项定义包含一个对象列表,表中对象包含 pathPrefix
字段,用来表示允许
hostPath
卷挂载以所指定前缀开头的路径。
对象中还包含一个 readOnly
字段,用来表示对应的卷必须以只读方式挂载。
例如:
allowedHostPaths:
# 下面的设置允许 "/foo"、"/foo/"、"/foo/bar" 等路径,但禁止
# "/fool"、"/etc/foo" 这些路径。
# "/foo/../" 总会被当作非法路径。
- pathPrefix: "/foo"
readOnly: true # 仅允许只读模式挂载
容器如果对宿主文件系统拥有不受限制的访问权限,就可以有很多种方式提升自己的特权,
包括读取其他容器中的数据、滥用系统服务(如 kubelet
)的凭据信息等。
由可写入的目录所构造的 hostPath
卷能够允许容器写入数据到宿主文件系统,
并且在写入时避开 pathPrefix
所设置的目录限制。
readOnly: true
这一设置在 Kubernetes 1.11 版本之后可用。
必须针对 allowedHostPaths
中的 所有 条目设置此属性才能有效地限制容器只能访问
pathPrefix
所指定的目录。
ReadOnlyRootFilesystem - 要求容器必须以只读方式挂载根文件系统来运行 (即不允许存在可写入层)。
FlexVolume 驱动
此配置指定一个可以被 FlexVolume 卷使用的驱动程序的列表。
空的列表或者 nil 值意味着对驱动没有任何限制。
请确保volumes
字段包含了 flexVolume
卷类型,
否则所有 FlexVolume 驱动都被禁止。
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: allow-flex-volumes
spec:
# spec 的其他字段
volumes:
- flexVolume
allowedFlexVolumes:
- driver: example/lvm
- driver: example/cifs
用户和组
RunAsUser - 控制使用哪个用户 ID 来运行容器。
MustRunAs - 必须至少设置一个
range
。使用该范围内的第一个值作为默认值。 所有范围值都会被验证检查。MustRunAsNonRoot - 要求提交的 Pod 具有非零
runAsUser
值,或在镜像中 (使用 UID 数值)定义了USER
环境变量。 如果 Pod 既没有设置runAsNonRoot
,也没有设置runAsUser
,则该 Pod 会被修改以设置runAsNonRoot=true
,从而要求容器通过USER
指令给出非零的数值形式的用户 ID。 此配置没有默认值。采用此配置时,强烈建议设置allowPrivilegeEscalation=false
。RunAsAny - 没有提供默认值。允许指定任何
runAsUser
配置。
RunAsGroup - 控制运行容器时使用的主用户组 ID。
- MustRunAs - 要求至少指定一个
range
值。第一个范围中的最小值作为默认值。 所有范围值都被用来执行验证检查。 - MayRunAs - 不要求设置
RunAsGroup
。 不过,如果指定了RunAsGroup
被设置,所设置值必须处于所定义的范围内。 - RunAsAny - 未指定默认值。允许
runAsGroup
设置任何值。
SupplementalGroups - 控制容器可以添加的组 ID。
- MustRunAs - 要求至少指定一个
range
值。第一个范围中的最小值用作默认值。 所有范围值都被用来执行验证检查。 - MayRunAs - 要求至少指定一个
range
值。 允许不指定supplementalGroups
且不设置默认值。 如果supplementalGroups
被设置,则所有 range 值都被用来执行验证检查。 - RunAsAny - 未指定默认值。允许为
supplementalGroups
设置任何值。
特权提升
这一组选项控制容器的 allowPrivilegeEscalation
属性。该属性直接决定是否为容器进程设置
no_new_privs
参数。此参数会禁止 setuid
属性的可执行文件更改有效用户 ID(EUID),
并且禁止启用额外权能的文件。例如,no_new_privs
会禁止使用 ping
工具。
如果想有效地实施 MustRunAsNonRoot
控制,需要配置这一选项。
AllowPrivilegeEscalation - 决定是否用户可以将容器的安全上下文设置为
allowPrivilegeEscalation=true
。默认设置下,这样做是允许的,
目的是避免造成现有的 setuid
应用无法运行。将此选项设置为 false
可以确保容器的所有子进程都无法获得比父进程更多的特权。
DefaultAllowPrivilegeEscalation - 为 allowPrivilegeEscalation
选项设置默认值。
不设置此选项时的默认行为是允许特权提升,以便运行 setuid 程序。
如果不希望运行 setuid 程序,可以使用此字段将选项的默认值设置为禁止,
同时仍然允许 Pod 显式地请求 allowPrivilegeEscalation
。
权能字
Linux 权能字(Capabilities)将传统上与超级用户相关联的特权作了细粒度的分解。 其中某些权能字可以用来提升特权,打破容器边界,可以通过 PodSecurityPolicy 来限制。 关于 Linux 权能字的更多细节,可参阅 capabilities(7)。
下列字段都可以配置为权能字的列表。表中的每一项都是 ALL_CAPS
中的一个权能字名称,
只是需要去掉 CAP_
前缀。
AllowedCapabilities - 给出可以被添加到容器的权能字列表。
默认的权能字集合是被隐式允许的那些。空集合意味着只能使用默认权能字集合,
不允许添加额外的权能字。*
可以用来设置允许所有权能字。
RequiredDropCapabilities - 必须从容器中去除的权能字。
所给的权能字会从默认权能字集合中去除,并且一定不可以添加。
RequiredDropCapabilities
中列举的权能字不能出现在
AllowedCapabilities
或 DefaultAddCapabilities
所给的列表中。
DefaultAddCapabilities - 默认添加到容器的权能字集合。 这一集合是作为容器运行时所设值的补充。 关于使用 Docker 容器运行引擎时默认的权能字列表, 可参阅你的容器运行时的文档来了解使用 Linux 权能字的信息。
SELinux
- MustRunAs - 要求必须配置
seLinuxOptions
。默认使用seLinuxOptions
。 针对seLinuxOptions
所给值执行验证检查。 - RunAsAny - 没有提供默认值。允许任意指定的
seLinuxOptions
选项。
AllowedProcMountTypes
allowedProcMountTypes
是一组可以允许的 proc 挂载类型列表。
空表或者 nil 值表示只能使用 DefaultProcMountType
。
DefaultProcMount
使用容器运行时的默认值设置来决定 /proc
的只读挂载模式和路径屏蔽。
大多数容器运行时都会屏蔽 /proc
下面的某些路径以避免特殊设备或信息被不小心暴露给容器。
这一配置使所有 Default
字符串值来表示。
此外唯一的ProcMountType 是 UnmaskedProcMount
,意味着即将绕过容器运行时的路径屏蔽行为,
确保新创建的 /proc
不会被容器修改。此配置用字符串 Unmasked
来表示。
AppArmor
通过 PodSecurityPolicy 上的注解来控制。 详情请参阅 AppArmor 文档。
Seccomp
从 Kubernetes v1.19 开始,你可以使用 Pod 或容器的 securityContext
中的 seccompProfile
字段来控制 seccomp 配置的使用。
在更早的版本中,seccomp 是通过为 Pod 添加注解来控制的。
相同的 PodSecurityPolicy 可以用于不同版本,进而控制如何应用对应的字段或注解。
seccomp.security.alpha.kubernetes.io/defaultProfileName - 注解用来指定为容器配置默认的 seccomp 模板。可选值为:
unconfined
- 如果没有指定其他替代方案,Seccomp 不会被应用到容器进程上 (Kubernets 中的默认设置)。runtime/default
- 使用默认的容器运行时模板。docker/default
- 使用 Docker 的默认 seccomp 模板。自 1.11 版本废弃。 应改为使用runtime/default
。localhost/<路径名>
- 指定节点上路径<seccomp_root>/<路径名>
下的一个文件作为其模板。 其中<seccomp_root>
是通过kubelet
的标志--seccomp-profile-root
来指定的。 如果未定义--seccomp-profile-root
标志,则使用默认的路径<root-dir>/seccomp
, 其中<root-dir>
是通过--root-dir
标志来设置的。说明:从 Kubernetes v1.19 开始,
--seccomp-profile-root
标志已被启用。 用户应尝试使用默认路径。
seccomp.security.alpha.kubernetes.io/allowedProfileNames - 指定可以为
Pod seccomp 注解配置的值的注解。取值为一个可用值的列表。
表中每项可以是上述各值之一,还可以是 *
,用来表示允许所有的模板。
如果没有设置此注解,意味着默认的 seccomp 模板是不可更改的。
Sysctl
默认情况下,所有的安全的 sysctl 都是被允许的。
forbiddenSysctls
- 用来排除某些特定的 sysctl。 你可以在此列表中禁止一些安全的或者不安全的 sysctl。 此选项设置为*
意味着禁止设置所有 sysctl。allowedUnsafeSysctls
- 用来启用那些被默认列表所禁用的 sysctl, 前提是所启用的 sysctl 没有被列在forbiddenSysctls
中。
参阅 Sysctl 文档。
接下来
参阅 PodSecurityPolicy Deprecation: Past, Present, and Future, 了解 Pod 安全策略的未来。
参阅 Pod 安全标准, 了解策略建议。
阅读 PodSecurityPolicy 参考, 了解 API 细节。