自诞生以来,Kubernetes 一直是需要在微服务架构上实现可扩展容器化应用程序的企业的首选容器编排解决方案。它本质上将 Pod 作为最基本的单元来处理,它可以容纳一个或多个容器。由于 Kubernetes 中部署的任何应用程序都是通过一个或多个 Pod 执行的,因此用户必须确保它们免受错误配置和安全漏洞的影响。因此,Pod 安全性不仅是 Kubernetes 集群的主要问题,而且是关键业务应用程序的必要条件。
PodSecurityPolicy (PSP) 是一个内置于 Kubernetes 中的准入控制器。它的目的是控制 Kubernetes Pods 规范的安全敏感方面。例如,如果您的用例要求必须限制 Pod 访问主机系统的资源、设备和内核功能,您可能希望避免在集群中以特权模式运行 Pod。为此,相应的 PSP 定义如下所示:
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: restrict-privileged-pods
spec:
privileged: false
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
runAsUser:
rule: RunAsAny
fsGroup:
rule: RunAsAny
volumes:
- '*'
但在 Kubernetes v1.25 版本中移除 PSP 并不意味着 Pod 安全性的终结。它将被 Pod 安全准入 (PSA) 控制器所取代,该控制器利用 Kubernetes 准入控制 webhook。然而,PSA 控制器有一些严重的缺点,例如无法改变传入资源、无法强制执行 Pod 控制器以及无法配置的消息,仅举几例。您可以在 Kyverno 维护者 Shuting Zhao(Nirmata 员工工程师)和 Chip Zoller(Nirmata 技术产品经理)主持的本次会议中找到 PSA 的所有优缺点列表及其详细说明。
由 Nirmata 创建,后来捐赠给云原生计算基金会 (CNCF),目前是 CNCF 孵化项目——Kyverno 是专为 Kubernetes 设计的策略引擎。虽然与 PSA 控制器相比具有显着优势,但它利用 Kubernetes 准入控制 webhook 来检查试图进入集群的新创建或修改的资源。它通过根据集群中安装的 Kyverno 策略检查相关资源的定义来实现这一点。可以使用自定义资源将策略范围限定为整个集群ClusterPolicy
或使用自定义资源的集群中的特定命名空间Policy
。
下面显示了一个示例 Kyverno 策略,其中包含block-ephemeral-containers
严格阻止ephemeralContainers
Pod 内使用的规则定义:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: block-ephemeral-containers
spec:
validationFailureAction: enforce
rules:
- name: block-ephemeral-containers
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Ephemeral containers are not permitted."
pattern:
spec:
X(ephemeralContainers): "null"
然而,资源验证只是 Kyverno 的四个功能之一。其他三个包括资源变异(修改传入资源)、资源生成(根据传入资源生成或创建新资源)和供应链安全保证。
片段 1 中定义的 PSP 的等效 Kyverno ClusterPolicy 如下所示。
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-privileged-pods
spec:
validationFailureAction: enforce
rules:
- name: restrict-privileged-pods
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Rejected by restrict-privileged-pods rule."
pattern:
spec:
=(initContainers):
- =(securityContext):
=(privileged): false
=(ephemeralContainers):
- =(securityContext):
=(privileged): false
containers:
- =(securityContext):
=(privileged): false