16.9.10 安全基线与合规审计

在生产环境中,Kubernetes安全基线应覆盖身份鉴别、授权、网络隔离、镜像供应链、运行时防护与审计可追溯性。建议以“最小权限、默认拒绝、可审计”为核心原则,并与等保/ISO27001/SOC2等合规要求对齐。

原理草图(安全控制面与数据面联动)

文章图片

安全基线要点与示例

  • 身份与访问控制(RBAC最小权限)
    ```yaml
    # 文件: rbac-readonly.yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
    name: ns-readonly
    namespace: prod
    rules:
  • apiGroups: [""]
    resources: ["pods","services","configmaps"]
    verbs: ["get","list","watch"]

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: bind-readonly
namespace: prod
subjects:
- kind: User
name: dev1
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: ns-readonly
apiGroup: rbac.authorization.k8s.io
bash
kubectl apply -f rbac-readonly.yaml
# 验证权限:预计只能查看,不能创建
kubectl auth can-i create pods -n prod --as=dev1 # 预期: no
kubectl auth can-i list pods -n prod --as=dev1 # 预期: yes
```

  • 网络隔离(默认拒绝 + 白名单放行)
    yaml # 文件: np-deny-all.yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all namespace: prod spec: podSelector: {} policyTypes: ["Ingress","Egress"]
    ```yaml
    # 文件: np-allow-web.yaml
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
    name: allow-web
    namespace: prod
    spec:
    podSelector:
    matchLabels:
    app: web
    ingress:

    • from:
    • namespaceSelector:
      matchLabels:
      name: prod
      ports:
    • protocol: TCP
      port: 80
      bash
      kubectl apply -f np-deny-all.yaml
      kubectl apply -f np-allow-web.yaml
      # 验证:仅允许同命名空间访问 web 80 端口
      ```
  • API安全与审计(审计策略)
    ```yaml
    # 文件: /etc/kubernetes/audit-policy.yaml
    apiVersion: audit.k8s.io/v1
    kind: Policy
    rules:

  • level: Metadata
    resources:
    • group: ""
      resources: ["pods","secrets","configmaps"]
  • level: RequestResponse
    resources:

    • group: "rbac.authorization.k8s.io"
      resources: ["clusterroles","clusterrolebindings","roles","rolebindings"]
      bash
      # kube-apiserver 增加参数(示例)
      --audit-policy-file=/etc/kubernetes/audit-policy.yaml
      --audit-log-path=/var/log/kubernetes/audit.log
      --audit-log-maxage=30 --audit-log-maxsize=100 --audit-log-maxbackup=10
      # 验证:
      sudo tail -f /var/log/kubernetes/audit.log
      ```
  • 镜像与供应链安全(Trivy 扫描 + 准入)
    ```bash
    # 安装 Trivy(示例)
    sudo apt-get update && sudo apt-get install -y wget
    wget https://github.com/aquasecurity/trivy/releases/download/v0.50.1/trivy_0.50.1_Linux-64bit.deb
    sudo dpkg -i trivy_0.50.1_Linux-64bit.deb

# 扫描镜像
trivy image --severity HIGH,CRITICAL nginx:1.25
# 预期:输出漏洞列表与修复建议
```

  • 运行时安全(Pod安全标准 + Seccomp)
    yaml # 文件: pss-restricted-ns.yaml apiVersion: v1 kind: Namespace metadata: name: prod labels: pod-security.kubernetes.io/enforce: "restricted" pod-security.kubernetes.io/enforce-version: "latest"
    ```yaml
    # 文件: pod-seccomp.yaml
    apiVersion: v1
    kind: Pod
    metadata:
    name: safe-nginx
    namespace: prod
    spec:
    securityContext:
    seccompProfile:
    type: RuntimeDefault
    containers:

    • name: nginx
      image: nginx:1.25
      securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      bash
      kubectl apply -f pss-restricted-ns.yaml
      kubectl apply -f pod-seccomp.yaml
      # 预期:PSS限制生效,特权容器将被拒绝
      ```
  • 密钥与敏感信息(Secret 加密 at-rest)
    ```yaml
    # 文件: /etc/kubernetes/encryption-config.yaml
    apiVersion: apiserver.config.k8s.io/v1
    kind: EncryptionConfiguration
    resources:

  • resources:

    • secrets
      providers:
    • aescbc:
      keys:
      • name: key1
        secret: WmF0dGxvY2tLZXlCYXNlNjQ=
    • identity: {}
      bash
      # kube-apiserver 参数
      --encryption-provider-config=/etc/kubernetes/encryption-config.yaml
      # 验证:创建 secret 后在 etcd 中应为加密内容
      kubectl create secret generic test --from-literal=pass=123 -n prod
      ```
  • 节点安全(基线加固)
    ```bash
    # 关闭不必要服务、限制SSH
    sudo systemctl disable --now rpcbind
    sudo sed -i 's/^#PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
    sudo systemctl restart ssh

# 检查开放端口(仅示例)
sudo ss -lntp
```

合规审计流程(工具化落地)

  • 基线扫描工具安装(kube-bench)
    bash # 使用容器运行 kube-bench(不污染主机) docker run --rm -v /etc:/etc -v /var:/var \ --net=host aquasec/kube-bench:0.7.2 # 预期:输出 CIS 基线评分与失败项

  • 持续合规检测(OPA Gatekeeper 安装示例)
    bash kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/deploy/gatekeeper.yaml kubectl get pods -n gatekeeper-system
    ```yaml
    # 文件: constraint-template.yaml
    apiVersion: templates.gatekeeper.sh/v1beta1
    kind: ConstraintTemplate
    metadata:
    name: k8srequiredlabels
    spec:
    crd:
    spec:
    names:
    kind: K8sRequiredLabels
    targets:

    • target: admission.k8s.gatekeeper.sh
      rego: |
      package k8srequiredlabels
      violation[{"msg": msg}] {
      required := {"owner"}
      provided := {label | input.review.object.metadata.labels[label]}
      missing := required - provided
      count(missing) > 0
      msg := sprintf("missing labels: %v", [missing])
      }

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: ns-must-have-owner
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Namespace"]
bash
kubectl apply -f constraint-template.yaml
# 预期:创建无 owner 标签的 Namespace 会被拒绝
```

常见排错清单(含命令)
- RBAC 拒绝:
bash kubectl auth can-i get pods -n prod --as=dev1 kubectl get rolebinding,clusterrolebinding -A | grep dev1
- NetworkPolicy 误拦截:
bash kubectl describe networkpolicy -n prod kubectl exec -n prod -it pod-a -- curl -m 2 http://pod-b:80
- 准入控制拒绝:
bash kubectl describe pod safe-nginx -n prod kubectl get events -n prod --sort-by=.lastTimestamp | tail
- 审计日志无输出:
bash ps -ef | grep kube-apiserver | grep audit ls -l /var/log/kubernetes/audit.log

练习与验收
1. 建立 prod 命名空间,启用 PSS restricted,创建一个特权容器并观察被拒绝原因。
2. 配置默认拒绝的 NetworkPolicy,验证同命名空间与跨命名空间访问的差异。
3. 运行 kube-bench,列出前三个失败项并给出修复命令。
4. 在 CI 中使用 Trivy 扫描镜像,设置严重级别 HIGH/CRITICAL 失败即阻断。
5. 开启审计日志,进行一次 RoleBinding 变更,查看 audit.log 中的记录。