本页面介绍将 Pod 级层安全控制应用到 Google Kubernetes Engine (GKE) 集群的建议方法。
概览
Gatekeeper 是一个准入控制器,使用开放政策代理 (OPA) 验证在 Kubernetes 集群上创建和更新 Pod 的请求。
借助 Gatekeeper,管理员可以使用限制条件来定义政策,限制条件是允许或拒绝 Kubernetes 中部署行为的一组条件。然后,您可以使用 ConstraintTemplate
在集群上强制执行这些政策。本文档提供了相关示例,说明如何限制工作负载的安全功能,以确保使用 Gatekeeper 强制执行、测试和审核安全政策。
除了实施与 Kubernetes PodSecurityPolicy 相同的功能之外,Gatekeeper 还可以执行以下操作:
- 发布政策:以循序渐进的方式逐步执行政策,以限制中断工作负载的风险。
- 运行阶段政策更改:提供在执行政策之前测试政策影响和范围的机制。
- 审核现有政策:确保新工作负载和现有工作负载的安全控制措施(审核控制)。
Kubernetes 开源软件 (OSS) 正在弃用 Kubernetes PodSecurityPolicy,并且不再推荐使用 Kubernetes Pod。
概念
Gatekeeper 引入了两个概念,以便为管理员提供强大、灵活控制其集群的控制方法:限制条件和约束模板,它们都是从开放式政策代理限制条件框架继承的概念。
限制条件是安全政策的表示形式,它们定义要求和强制执行范围。限制条件模板是可重复使用的语句(使用 Rego 编写),可根据限制条件中定义的要求应用逻辑以评估 Kubernetes 对象中的特定字段。
例如,您可能有一个限制条件,用于声明可应用于特定命名空间中 Pod 的允许 seccomp 配置文件,以及一个提供限制条件以提取这些值和处理强制执行情况的逻辑模板。
以下限制条件模板来自 Gatekeeper 代码库,用于检查 Pod 规范中是否存在 securityContext.privileged
:
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8spspprivilegedcontainer
spec:
crd:
spec:
names:
kind: K8sPSPPrivilegedContainer
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8spspprivileged
violation[{"msg": msg, "details": {}}] {
c := input_containers[_]
c.securityContext.privileged
msg := sprintf("Privileged container is not allowed: %v, securityContext: %v", [c.name, c.securityContext])
}
input_containers[c] {
c := input.review.object.spec.containers[_]
}
input_containers[c] {
c := input.review.object.spec.initContainers[_]
}
为扩展上述限制条件模板,以下限制定义了此 dryrun
模式下此限制条件模板的具体执行范围 (kinds
):
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPPrivilegedContainer
metadata:
name: psp-privileged-container
spec:
enforcementAction: dryrun
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
借助 Gatekeeper,您可以创建自己的限制条件和限制条件模板以满足您的特定需求。您还可以在 Gatekeeper 代码库中使用一组标准的限制条件和限制条件模板,定义这些模板是为了实现快速采用和安全强制执行。每个限制条件还带有示例 Pod 配置。
准备工作
在开始之前,请确保您已执行以下任务:
- 确保您已启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 确保您已安装 Cloud SDK。
使用以下任一方法设定默认的 gcloud
设置:
- 使用
gcloud init
(如果您想要在系统引导下完成默认设置)。 - 使用
gcloud config
(如果您想单独设置项目 ID、区域和地区)。
使用 gcloud init
如果您收到 One of [--zone, --region] must be supplied: Please specify
location
错误,请完成本部分。
-
运行
gcloud init
并按照说明操作:gcloud init
如果您要在远程服务器上使用 SSH,请使用
--console-only
标志来防止命令启动浏览器:gcloud init --console-only
-
按照说明授权
gcloud
使用您的 Google Cloud 帐号。 - 创建新配置或选择现有配置。
- 选择 Google Cloud 项目。
- 为可用区级集群选择默认 Compute Engine 可用区,或为区域级集群或 Autopilot 集群选择区域。
使用 gcloud config
在集群上启用 Gatekeeper
您可以使用以下某种方法在 GKE 集群上启用 Gatekeeper。这些方法不能在同一个集群上共存,因此请确保仅选择一个方法。
使用 Anthos Config Management(推荐)
Anthos Config Management 提供了政策控制器,它是在 Gatekeeper 开源项目中构建的政策引擎。Google 建议使用 Anthos Config Management,因为它可以解决与大规模强制执行政策相关的常见问题,包括政策即代码、多集群支持、与 Cloud Logging 的集成以及同步配置功能。
如需在集群上启用政策控制器,请按照 Anthos Config Management 安装指南操作。
使用 Google Cloud Marketplace
Gatekeeper 作为 Google Cloud Marketplace 中的 Kubernetes 应用提供。Gatekeeper 可以安装到现有集群上,也可以安装到新创建的集群上。
如需从 Cloud Marketplace 部署 Gatekeeper,请参阅从 Google Cloud Marketplace 部署应用。
启用限制条件和限制条件模板
与 PodSecurityPolicy 不同,您可以安装和启用 Gatekeeper 及其限制条件模板,而不会对现有或新的工作负载产生负面影响。因此,建议将所有适用的 Pod 安全限制条件模板应用于集群。
此外,还可以实现 Gatekeeper 限制条件,以强制对特定对象(例如命名空间和 Pod)的控制。
请观看下面的示例,该示例范围限制为位于生产命名空间中的 Pod,方法是在限制条件匹配语句中定一它们:
...
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
namespaces:
- "production"
测试政策
为现有集群引入新政策可能会有负面行为,例如限制现有工作负载。使用 Gatekeeper 确保 Pod 安全性的其中一项好处是,您可以使用试运行模式来测试政策的有效性和影响,而无需进行实际更改。这样,就可以在不强制执行政策的情况下对正在运行的集群进行测试政策配置。系统会记录并发现违反政策的行为,而不会造成干扰。
以下步骤演示了开发者、运营商或管理员如何应用限制条件模板和限制条件来确定其有效性或潜在影响:
应用 Gatekeeper 配置以复制数据,进行审核和试运行功能:
kubectl create -f- <<EOF apiVersion: config.gatekeeper.sh/v1alpha1 kind: Config metadata: name: config namespace: "gatekeeper-system" spec: sync: syncOnly: - group: "" version: "v1" kind: "Namespace" - group: "" version: "v1" kind: "Pod" EOF
在未应用任何限制条件的情况下,我们运行具有提升权限的工作负载:
kubectl create -f- <<EOF apiVersion: v1 kind: Pod metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx securityContext: privileged: true EOF
加载上述
k8spspprivilegedcontainer
限制条件模板:kubectl create -f- <<EOF apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8spspprivilegedcontainer spec: crd: spec: names: kind: K8sPSPPrivilegedContainer targets: - target: admission.k8s.gatekeeper.sh rego: | package k8spspprivileged violation[{"msg": msg, "details": {}}] { c := input_containers[_] c.securityContext.privileged msg := sprintf("Privileged container is not allowed: %v, securityContext: %v", [c.name, c.securityContext]) } input_containers[c] { c := input.review.object.spec.containers[_] } input_containers[c] { c := input.review.object.spec.initContainers[_] } EOF
现在,我们来创建一个新的限制条件以扩展此限制条件模板。这次,我们将
enforcementAction
设置为dryrun
:kubectl create -f- <<EOF apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sPSPPrivilegedContainer metadata: name: psp-privileged-container spec: enforcementAction: dryrun match: kinds: - apiGroups: [""] kinds: ["Pod"] EOF
通过 Gatekeeper 同步运行的对象数据并被动地检查是否存在违规,我们可以检查限制的
status
,确认是否有任何违规行为:kubectl get k8spspprivilegedcontainer.constraints.gatekeeper.sh/psp-privileged-container -o yaml
apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sPSPPrivilegedContainer metadata: ... name: psp-privileged-container ... spec: enforcementAction: dryrun match: kinds: - apiGroups: - "" kinds: - Pod status: auditTimestamp: "2019-12-15T22:19:54Z" byPod: - enforced: true id: gatekeeper-controller-manager-0 violations: - enforcementAction: dryrun kind: Pod message: 'Privileged container is not allowed: nginx, securityContext: {"privileged": true}' name: nginx namespace: default
让我们运行另一个特权 Pod,以确认该政策不会干扰部署:
kubectl create -f- <<EOF apiVersion: v1 kind: Pod metadata: name: privpod labels: app: privpod spec: containers: - name: nginx image: nginx securityContext: privileged: true EOF
此新 Pod 将成功部署。
如需清理本部分中创建的资源,请运行以下命令:
kubectl delete k8spspprivilegedcontainer.constraints.gatekeeper.sh/psp-privileged-container kubectl delete constrainttemplate k8spspprivilegedcontainer kubectl delete pod/nginx kubectl delete pod/privpod
强制执行政策
现在,我们可以在不影响现有工作负载或新工作负载的情况下确认政策的有效性和影响,下面我们实施全面强制执行的政策。
基于用于验证上述政策的示例,以下步骤演示了开发者、运营商或管理员如何应用限制条件模板和限制条件来实施政策:
加载前面提到的
k8spspprivilegedcontainer
限制条件模板:kubectl create -f- <<EOF apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8spspprivilegedcontainer spec: crd: spec: names: kind: K8sPSPPrivilegedContainer targets: - target: admission.k8s.gatekeeper.sh rego: | package k8spspprivileged violation[{"msg": msg, "details": {}}] { c := input_containers[_] c.securityContext.privileged msg := sprintf("Privileged container is not allowed: %v, securityContext: %v", [c.name, c.securityContext]) } input_containers[c] { c := input.review.object.spec.containers[_] } input_containers[c] { c := input.review.object.spec.initContainers[_] } EOF
现在,我们来创建一个新的限制条件以扩展此限制条件模板。这次不会设置
enforcementAction
键。默认情况下,enforcementAction
键设置为deny
。kubectl create -f- <<EOF apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sPSPPrivilegedContainer metadata: name: psp-privileged-container spec: match: kinds: - apiGroups: [""] kinds: ["Pod"] EOF
尝试部署用于声明特许权限的容器:
kubectl create -f- <<EOF apiVersion: v1 kind: Pod metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx securityContext: privileged: true EOF
应收到以下错误消息:
Error from server ([denied by psp-privileged-container] Privileged container is not allowed: nginx, securityContext: {"privileged": true}): error when creating "STDIN": admission webhook "validation.gatekeeper.sh" denied the request: [denied by psp-privileged-container] Privileged container is not allowed: nginx, securityContext: {"privileged": true}
如需清理,请运行以下命令:
kubectl delete k8spspprivilegedcontainer.constraints.gatekeeper.sh/psp-privileged-container kubectl delete constrainttemplate k8spspprivilegedcontainer
后续步骤
Gatekeeper 提供了一种使用声明性政策在 GKE 群集上强制实施和验证安全性的强大方法。但是,Gatekeeper 的使用不仅仅是安全性,并且可用于管理和运营的其他方面。