本节介绍如何配置约束模板和约束,以便禁止在某些项目中创建特权容器,以拦截高风险操作,避免特权容器被滥用。

前提条件

  • 您需要加入一个集群并在集群中具有 cluster-admin 权限。有关更多信息,请参阅集群成员集群角色

  • KubeSphere 企业版平台需要安装并启用 Gatekeeper 扩展组件。

步骤 1:创建约束模板

登录集群节点,执行以下命令创建约束模板。

cat <<EOF | kubectl apply -f -
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8spspprivilegednamespace
spec:
  crd:
    spec:
      names:
        kind: K8sPSPPrivilegedNamespace
      validation:
        openAPIV3Schema:
          type: object
          properties:
            excludedNamespaces:
              type: array
              items:
                type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8spspprivilegednamespace

        violation[{"msg": msg}] {
          input.review.kind.kind == "Pod"
          not namespace_excluded
          container := input.review.object.spec.containers[_]
          container.securityContext.privileged == true
          msg := sprintf("Privileged container is not allowed in namespace %v", [input.review.object.metadata.namespace])
        }

        namespace_excluded {
          input.parameters.excludedNamespaces[_] == input.review.object.metadata.namespace
        }
EOF

步骤 2:创建约束

继续执行以下命令创建约束。

excludedNamespaces 字段用于指定允许特权容器的命名空间,即被豁免的项目,您可以添加更多命名空间。

cat <<EOF | kubectl apply -f -
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPPrivilegedNamespace
metadata:
  name: disallow-privileged-containers
spec:
  parameters:
    excludedNamespaces:
      - kube-system
      - extension-gatekeeper
      - extension-openpitrix
      - kube-node-lease
      - kube-public
      - kubesphere-controls-system
      - kubesphere-logging-system
      - kubesphere-monitoring-federated
      - kubesphere-monitoring-system
      - kubesphere-system
EOF

步骤 3: 验证结果

通过以上配置,当用户创建使用特权容器的 Pod 且所属项目不在 excludedNamespaces 中时,Gatekeeper 会拦截请求。

可通过以下步骤,分别在非豁免项目(系统项目 default)和豁免项目(系统项目 kube-system)中创建特权 Pod 进行验证。

  1. 在集群节点上,为非豁免项目 default 创建一个特权 Pod。

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: privileged-pod
      namespace: default
    spec:
      containers:
        - name: nginx
          image: nginx
          securityContext:
            privileged: true
    EOF

    预期结果如下,无法在该项目中创建特权容器。

    Error from server (Forbidden): error when creating "STDIN": admission webhook "validation.gatekeeper.sh" denied the request: [disallow-privileged-containers] Privileged container is not allowed in namespace default
  2. 在集群节点上,为豁免项目 kube-system 创建一个特权 Pod。

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: privileged-pod
      namespace: kubesphere-system
    spec:
      containers:
        - name: nginx
          image: nginx
          securityContext:
            privileged: true
    EOF

    预期结果如下,成功在该项目中创建特权容器。

    pod/privileged-pod created