文中的安全演示和示例均在 v1.18.17 集群中通过验证。
Pod Security Policies (下文简称 psp 或 pod 安全策略)是策略一种集群级别的全局资源,能够对 pod 的何优创建和更新进行细粒度的授权控制。具体来说,启用一个 psp 对象定义了一组安全性条件,安全一个 pod 的策略 spec 字段必须满足这些条件以及适用相关字段的默认值,其创建或更新请求才会被 apiserver 所接受。何优
具体的启用 pod 字段和安全条件可见文档 what-is-a-pod-security-policy[1] 。
Kubernetes 默认不开启 pod 安全策略功能,安全在集群中启用 pod 安全策略的策略步骤大体上分为三步:
注意步骤 1、2 的顺序不重要,因为它们不会产生实际影响。
但步骤 3 推荐在最后一步执行,否则一旦启用 admission-controller 插件,如果集群中没有可用的 pod 安全策略或者未对安全策略资源预先授权,所有 pod 的创建都会被拒绝,包括 kube-system 命名空间下的系统管理组件如 apiserver(但由于是受 kubelet 管理的静态 pod 实际上容器依然会运行)。
RBAC 身份认证
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: all-psp
rules:
- apiGroups: ['policy']
resources: ['podsecuritypolicies']
verbs: ['use']
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-psp-bind
roleRef:
kind: ClusterRole
name: all-psp
apiGroup: rbac.authorization.k8s.io
subjects:
# 授权给指定命名空间下的所有 service account(推荐做法):
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:nodes
namespace: kube-system
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:serviceaccounts:kube-system
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:serviceaccounts:security-test
# 也可授权给指定的 service account 或者用户(不推荐):
- kind: ServiceAccount
name: <authorized service account name>
namespace: <authorized pod namespace>
- kind: User
apiGroup: rbac.authorization.k8s.io
name: <authorized user name>
# 授权给所有的 service accounts:
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:serviceaccounts
# 授权给所有已认证的用户:
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:authenticated
创建安全策略资源
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'
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: restricted
annotations:
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
# Required to prevent escalations to root.
allowPrivilegeEscalation: false
requiredDropCapabilities:
- ALL
# Allow core volume types.
volumes:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
# Assume that ephemeral CSI drivers & persistentVolumes set up by the cluster admin are safe to use.
- 'csi'
- 'persistentVolumeClaim'
- 'ephemeral'
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
# Require the container to run without root privileges.
rule: 'MustRunAsNonRoot'
seLinux:
# This policy assumes the nodes are using AppArmor rather than SELinux.
rule: 'RunAsAny'
supplementalGroups:
rule: 'MustRunAs'
ranges:
# Forbid adding the root group.
- min: 1
max: 65535
fsGroup:
rule: 'MustRunAs'
ranges:
# Forbid adding the root group.
- min: 1
max: 65535
readOnlyRootFilesystem: false
启用 admission controller 插件
启用 admission controller 的 psp 插件有两种方式:
$ sed -i 's/enable-admission-plugins=NodeRestriction/enable-admission-plugins=NodeRestriction,PodSecurityPolicy/' /etc/kubernetes/manifests/kube-apiserver.yaml
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
apiServer:
extraArgs:
enable-admission-plugins: "PodSecurityPolicy"
我们在上文授权过的 security-test 命名空间进行测试,验证 psp 对 pod 的限制条件。
首先确保在集群中应用了严格版本的 psp 资源,然后尝试通过 deployment 创建一个需要使用 hostNetwork 的 pod:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-hostnetwork
spec:
selector:
matchLabels:
run: nginx
template:
metadata:
labels:
run: nginx
spec:
hostNetwork: true
containers:
- image: nginx
imagePullPolicy: Always
name: nginx-privileged
创建并查看结果:
$ kubectl create -f hostnetwork-pod.yaml -n security-test
deployment.apps/nginx-hostnetwork created
$ kubectl get deploy -n security-test nginx-hostnetwork
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-hostnetwork 0/1 0 0 17s
$ kubectl -n security-test get event | grep "pod security policy"
103s Warning FailedCreate deployment/nginx-hostnetwork Error creating: pods "nginx-hostnetwork-" is forbidden: unable to validate against any pod security policy: [spec.securityContext.hostNetwork: Invalid value: true: Host network is not allowed to be used]
如果有 pod 违反了安全策略,解决方案是要么调整 pod 的规格,要么修改 pod 安全策略资源。psp 资源是全局生效的,不能针对不同的命名空间设置不同的安全策略级别,这是一个很明显的局限性。
另外对 psp 的授权机制也比较复杂。如果没有授权或者未创建安全策略,结果是所有 pod 被拒绝,这也导致在集群中默认开启该功能的操作难度很大。
从 Kubernetes v1.21 开始,Pod Security Policy 将被弃用,并将在 v1.25 中删除。Kubernetes 引入了 Pod Security Admission 作为其替代者,我们将在下文中详细解析。
KEP-2579[2] 详细阐述了使用 Pod Security Admission 替代 Pod Security Policy 的三点主要理由:
新的 Pod Security Admission 机制在易用性和灵活性上都有了很大提升,从使用角度有以下四点显着不同:
Pod Security Admission 将原来 Pod Security Policy 的安全条件划分成三种预设的安全等级:
三种等级从宽松到严格递增,各自包含了不同限度的安全条件[3],适用于不同的 pod 工作场景。此外还可以将安全等级设置为固定的 Kubernetes 版本,这样即使集群升级到了新的版本且新版本的安全等级定义发生变化,依然可以按旧版本的安全条件对 pod 进行约束。
当 pod 与安全等级冲突时,我们可通过三种模式来选择不同的处理方式:
audit 和 warn 模式是独立的,如果同时需要两者的功能必须分别设置两种模式。
应用安全策略不再需要创建单独的集群资源,只需要为命名空间设置控制标签:
pod-security.kubernetes.io/<mode>: <level>
pod-security.kubernetes.io/<mode>-version: <version>
下文会有更完整的示例。
虽然 Pod Security Admission 是一个在 Kubernetes v1.22 引入的功能,但旧版本可以通过安装 PodSecurity admission webhook 来启用该功能,具体步骤如下:
$ git clone https://github.com/kubernetes/pod-security-admission.git
$ cd pod-security-admission/webhook
$ make certs
$ kubectl apply -k .
以上来自官方文档的步骤在 v1.18.17 会有两个兼容性问题,具体问题和解决方案如下:
$ kubectl apply -k .
error: json: unknown field "replacements"
解决方案:安装最新版本的 kusomize 然后在同一目录执行
$ kustomize build . | kubectl apply -f -
error: error validating "STDIN": error validating data: ValidationError(Deployment.spec.template.spec.containers[0].securityContext): unknown field "seccompProfile" in io.k8s.api.core.v1.SecurityContext; if you choose to ignore these errors, turn validation off with --validate=false
首先创建一个新的命名空间 psa-test 用于测试,并将其定义强制应用 baseline 安全等级,并对 restricted 等级进行警告和审计:
apiVersion: v1
kind: Namespace
metadata:
name: psa-test
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/enforce-version: v1.18
# We are setting these to our _desired_ `enforce` level.
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/audit-version: v1.18
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: v1.18
接着在该命名空间中创建上文示例中用过的 deployment:
$ kubectl create -f hostnetwork-pod.yaml -n psa-test
deployment.apps/nginx-hostnetwork created
$ kubectl get deploy -n psa-test nginx-hostnetwork
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-hostnetwork 0/1 0 0 17s
$ kubectl -n psa-test get event | grep PodSecurity
104s Warning FailedCreate replicaset/nginx-hostnetwork-644cdd6598 Error creating:
(责任编辑:娱乐)
iOS15.1.1正式版发布:修复重大Bug,通话掉线信号问题彻底解决
ThreadLocal全攻略:使用实战,源码分析,内存泄露分析
帅丰电器(605336.SH)拟推176.25万股限制性股票激励计划 授予价格为13.62元/股