AI Infra 训练营
总览
  • 总览
  • 完整安装
  • 核心 K8s
  • Cilium 网络
  • Longhorn 存储
  • 监控日志
  • CI / GitOps
  • 安全准入
  • Day 0 · 新手接管 Runbook
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
命令手册
HiHuo 主站
GitHub
总览
  • 总览
  • 完整安装
  • 核心 K8s
  • Cilium 网络
  • Longhorn 存储
  • 监控日志
  • CI / GitOps
  • 安全准入
  • Day 0 · 新手接管 Runbook
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
命令手册
HiHuo 主站
GitHub
  • 实操 Runbook

    • Runbook 总览:从零部署、查看、调试
    • 完整安装总 Runbook:5 台 Ubuntu 到可用平台
    • 核心 K8s Runbook:apiserver / etcd / kubelet / containerd / HAProxy
    • Cilium 网络 Runbook:安装、查看、调试
    • Longhorn 存储 Runbook:安装、查看、调试
    • 监控日志 Runbook:Prometheus / Grafana / Loki / Alertmanager
    • CI / GitOps Runbook:Harbor / Gitea / Jenkins / Kaniko / ArgoCD
    • 安全准入 Runbook:RBAC / PSA / Kyverno / ResourceQuota

安全准入 Runbook:RBAC / PSA / Kyverno / ResourceQuota

这篇讲“为什么我的 Pod 明明 YAML 对了,却被集群拒绝或一直起不来”。当前集群里有安全和准入策略,常见事件是:

PolicyViolation: Container must set resources.requests.cpu / memory

这不是 K8s 坏了,是准入策略在拦截不合规资源。


1. 组件作用

组件 / 机制作用
RBAC控制谁能访问哪些 K8s API
ServiceAccountPod 访问 apiserver 时使用的身份
Pod Security AdmissionK8s 内置 Pod 安全级别,限制 privileged、hostPath 等
Kyverno准入策略引擎,用 YAML 写策略,拦不合规资源
ResourceQuota限制 namespace 总资源
LimitRange给容器默认 request/limit 或限制单 Pod 范围
NetworkPolicy限制 Pod 间网络访问,当前由 Cilium 实现

为什么要这些组件:没有准入策略时,任何人都能提交无 request 的 Pod、privileged Pod、任意来源镜像。学习集群可以放宽,生产必须有边界。


2. 安装 Kyverno

Kyverno 用 manifest 安装即可。必须用 server-side apply:

kubectl apply --server-side --force-conflicts \
  -f https://github.com/kyverno/kyverno/releases/download/v1.13.2/install.yaml

为什么必须 --server-side:Kyverno CRD 很大,普通 kubectl apply 会把整份 YAML 写进 last-applied-configuration annotation,可能超过 256KB 限制。Server-side apply 不写这个超大 annotation。

验收:

kubectl get pods -n kyverno
kubectl get crd | grep kyverno
kubectl get clusterpolicy

刚安装完 Kyverno Pod Running 后,webhook 还可能需要 30-60 秒初始化缓存。第一条策略如果 timeout,等一分钟重试。


3. 三条基础 ClusterPolicy

学习集群可以先用 Audit,确认不误伤后再改 Enforce。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-app-label
spec:
  validationFailureAction: Audit
  rules:
  - name: check-label
    match:
      any:
      - resources:
          kinds: [Deployment, StatefulSet]
    validate:
      message: "Resource must set label 'app.kubernetes.io/name'"
      pattern:
        metadata:
          labels:
            app.kubernetes.io/name: '?*'
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-latest-tag
spec:
  validationFailureAction: Audit
  rules:
  - name: require-image-tag
    match:
      any:
      - resources:
          kinds: [Pod]
    validate:
      message: "Image tag must not be 'latest' or empty"
      pattern:
        spec:
          containers:
          - image: "!*:latest & *:*"
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-resources
spec:
  validationFailureAction: Audit
  rules:
  - name: require-cpu-mem
    match:
      any:
      - resources:
          kinds: [Pod]
    validate:
      message: "Container must set resources.requests.cpu / memory"
      pattern:
        spec:
          containers:
          - resources:
              requests:
                cpu: '?*'
                memory: '?*'

保存成 kyverno-baseline.yaml 后执行:

kubectl apply -f kyverno-baseline.yaml
kubectl get clusterpolicy

切到强制拦截:

for p in require-resources disallow-latest-tag require-app-label; do
  kubectl patch clusterpolicy $p --type=merge \
    -p '{"spec":{"validationFailureAction":"Enforce"}}'
done

不要第一天就对全平台 Enforce。生产做法是先 Audit 1-2 周,修完 chart 后再 Enforce,并给系统 namespace 写例外。


4. 查看当前安全状态

kubectl get ns --show-labels
kubectl get serviceaccount -A
kubectl get role,rolebinding,clusterrole,clusterrolebinding -A | head -80

kubectl get resourcequota,limitrange -A
kubectl get networkpolicy -A

kubectl get pods -A | grep kyverno || true
kubectl get clusterpolicy,policy -A 2>/dev/null || true
kubectl get policyreport,clusterpolicyreport -A 2>/dev/null || true

如果 kubectl get clusterpolicy 能返回资源,说明 Kyverno CRD 已安装。


5. RBAC:看一个账号有没有权限

查看当前 kubeconfig 身份:

kubectl auth whoami

测试权限:

kubectl auth can-i get pods -A
kubectl auth can-i create pods -n default
kubectl auth can-i get secrets -n jenkins --as=system:serviceaccount:jenkins:jenkins

Jenkins agent 常见错误:

MountVolume.SetUp failed ... secrets "harbor-auth" is forbidden

含义:Jenkins agent 的 ServiceAccount 没权限读 Secret,或者 Secret 不在同 namespace。

排查:

kubectl get pod -n jenkins
kubectl describe pod -n jenkins <agent-pod>
kubectl get sa,role,rolebinding -n jenkins
kubectl auth can-i get secrets -n jenkins --as=system:serviceaccount:jenkins:jenkins

6. PSA:Pod 安全级别

查看 namespace 的 Pod Security 标签:

kubectl get ns --show-labels | grep pod-security

常见级别:

级别含义
privileged基本不限制,适合系统组件
baseline禁止明显危险权限,适合大多数业务
restricted更严格,生产多租户常用

设置 namespace:

kubectl label ns app \
  pod-security.kubernetes.io/enforce=baseline \
  pod-security.kubernetes.io/audit=restricted \
  pod-security.kubernetes.io/warn=restricted \
  --overwrite

如果业务 Pod 需要 hostNetwork、privileged、hostPath,不要直接给全 namespace 放开。先确认是否真的需要,再单独设计安全边界。


7. Kyverno:看策略为什么拦截

查看策略:

kubectl get clusterpolicy
kubectl describe clusterpolicy require-resources 2>/dev/null || true

查看策略报告:

kubectl get policyreport -A
kubectl get clusterpolicyreport -A

看最近事件:

kubectl get events -A --sort-by=.lastTimestamp | grep -i policy | tail -50

如果看到:

Container must set resources.requests.cpu / memory

Pod 或 Deployment 需要加:

resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 500m
    memory: 512Mi

为什么要求 request:调度器根据 request 放置 Pod。没有 request 的 Pod 会让节点容量规划失真,容易把节点挤爆。


8. ResourceQuota 和 LimitRange

给业务 namespace 设置资源边界:

kubectl create ns app

cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: ResourceQuota
metadata:
  name: app-quota
  namespace: app
spec:
  hard:
    requests.cpu: "2"
    requests.memory: 4Gi
    limits.cpu: "4"
    limits.memory: 8Gi
    pods: "20"
---
apiVersion: v1
kind: LimitRange
metadata:
  name: app-defaults
  namespace: app
spec:
  limits:
  - type: Container
    defaultRequest:
      cpu: 100m
      memory: 128Mi
    default:
      cpu: 500m
      memory: 512Mi
EOF

查看:

kubectl describe quota -n app
kubectl describe limitrange -n app

常见事件:

事件含义
exceeded quotanamespace 配额不够
must specify requests.cpuLimitRange/Policy 要求 request
maximum cpu usage per Container is ...单容器 limit 超过限制

9. NetworkPolicy

NetworkPolicy 是网络层准入。当前由 Cilium 执行。

查看:

kubectl get networkpolicy -A
kubectl get cnp,ccnp -A 2>/dev/null || true

排查被网络策略挡住:

hubble observe --verdict DROPPED --last 100
kubectl describe networkpolicy -n <ns> <policy>

最小 default-deny 示例:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: app
spec:
  podSelector: {}
  policyTypes:
  - Ingress

加 default-deny 前必须先写允许规则,否则业务会被全部断开。


10. 准入失败排查顺序

kubectl apply 失败
  -> 看错误消息
  -> kubectl get events -A | tail
  -> 查 Kyverno policyreport
  -> 查 namespace PSA label
  -> 查 RBAC can-i

Pod 创建成功但起不来
  -> kubectl describe pod 看 Events
  -> 查 ResourceQuota / LimitRange
  -> 查 PVC / ImagePull / NetworkPolicy

常用命令:

kubectl describe pod -n <ns> <pod>
kubectl get events -n <ns> --sort-by=.lastTimestamp | tail -50
kubectl get policyreport -n <ns> -o yaml
kubectl auth can-i --list -n <ns>
在 GitHub 上编辑此页
Prev
CI / GitOps Runbook:Harbor / Gitea / Jenkins / Kaniko / ArgoCD