我按完成时间倒着把流程捋了一遍,谁什么时候做了什么、遇到啥坑、用了哪些命令都写清楚,方便你按着步骤实操一遍。先从审计和运行时检测开始讲起,这是我们把事情看见、追溯问题的最后一环,也是出事后能不能把责任和过程查清的关键。

在 API Server 上我们打开了审计功能,把记录等级按操作敏感度区分开。对 pods、secrets 这种重点资源,把请求头信息和元数据都记录下来;读操作只记元数据,写操作和高风险行为把请求体也记进来。审计策略文件放在
/etc/kubernetes/audit-policy.yaml,给 kube-apiserver 加两个启动参数:
–audit-policy-file=/etc/kubernetes/audit-policy.yaml
–audit-log-path=/var/log/kubernetes/audit.log
同时配置日志轮转,按团队合规设定保留期和大小限制。审计日志不能只放在控制平面节点上那样孤零零地躺着,必须推到聚焦化平台,跟 SIEM 组合起来做告警规则。举例:大量失败的 secret 创建、异常的权限提升、短时间内大量失败的登录都能触发告警。为了把实时异常和历史痕迹串起来,我们还部署了运行时检测工具 Falco,规则针对 exec、容器以 root 运行、可疑网络行为等。部署命令直接用:
kubectl apply -f https://download.falco.org/charts/falco-latest.yaml
把 Falco 的告警接入到告警平台后,出问题时能立刻拉事件单,查日志、看告警、回溯事件链条,这套组合比单靠审计日志要快得多。
往前倒,就是网络隔离了。把服务像分房间一样隔开,每个小网段只能进出被允许的流量。我们选了支持 NetworkPolicy 的 CNI,列如 Calico 或 Cilium,然后针对每个应用写准确策略。举个简单的例子,只允许前端访问后端的 8080 端口,后端不主动连外网:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: front-to-back-8080
namespace: prod
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
– Ingress
ingress:
– from:
– podSelector:
matchLabels:
app: frontend
ports:
– protocol: TCP
port: 8080
这些策略先在测试环境里验证,确认不会阻断正常流量再往生产推。对外暴露的服务放在边界层(ingress/外部负载均衡),再配合 WAF 或云厂商的网络策略做二次防护。写 NetworkPolicy 时要有白名单思维,不要写成“放行全部”,能封就封。
说到 Pod 运行时的安全,细节不少。我们明确要求镜像不能以 root 用户运行,容器的特权能力尽量去掉,文件系统能只读就只读,禁止特权容器。具体在 Pod spec 里写了安全上下文,列如:
securityContext:
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
同时启用 seccomp 和把能力削减掉:
securityContext:
seccompProfile:
type: RuntimeDefault
capabilities:
drop: [“ALL”]
privileged 一律设为 false。对那些的确 需要 hostPath 或 HostNetwork 的工作负载,只在必要的 namespace 并且经过严格审批后放行。为了把这些规则统一起来,我们启用了 Kubernetes 的 Pod Security Admission,把重大命名空间标为强制级别:
kubectl label namespace prod pod-security.kubernetes.io/enforce=restricted
restricted 模式会自动拦掉许多不安全配置,实测能过滤掉许多“看不见的风险”。
镜像和仓库的把控也必须到位。禁止直接在生产上拉公有镜像,所有镜像先进 CI 做构建和扫描,合格后推到内部私有仓库(如 Harbor 或 Artifact Registry)。CI 阶段用 Trivy 扫描高危和严重漏洞,命令示例:
trivy image –severity HIGH,CRITICAL your-registry.example.com/project/app:latest
只有扫描通过的镜像才允许进入私有仓库。除此之外,我们用镜像签名把镜像和构建内容绑定,运行时通过 Admission Controller 拒绝未签名或未通过扫描的镜像。常见做法是把 Image Policy 加进 Admission chain,用 Cosign 做签名,或者结合 OPA/Gatekeeper 写策略:只允许来自白名单仓库并且通过扫描的镜像入场。这样能避免有人随手从外面拉来不受信任的镜像跑到生产。
身份和权限管理是另一条红线。把“不给普通人超级权限”当作第一条原则。不要把 kube-admin 当成日常账号,管理用账号和日常用账号分开。按最小权限原则给权限,举个只读 pods 的 Role 示例:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: prod
name: pods-viewer
rules:
– apiGroups: [“”]
resources: [“pods”]
verbs: [“get”,”list”,”watch”]
绑定时只把具体用户绑到这个角色:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods-alice
namespace: prod
subjects:
– kind: User
name: “alice@company.com”
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pods-viewer
apiGroup: rbac.authorization.k8s.io
上线后跑一次全量检查,看看谁有 cluster-admin 权限,列出来逐一确认:
kubectl get clusterrolebinding -o yaml | grep -E “cluster-admin|system:masters” -n
把不该有的绑定收回,替换成最小权限角色。权限管理容易出错,记得把角色和绑定写成代码放版本控制里,变更走审批流程。
控制面和节点的加固也做了。API Server 强制 TLS,客户端证书只发给受信任的运维机或管理网络,管理端口只在内网可达,外网不直通控制平面。Kubelet 的认证和授权打开,禁止匿名访问,启用客户端证书机制并接入 RBAC 授权。节点上禁止开放不必要端口,把 kubelet 的只读端口关掉。凭证和证书实现自动化轮换,轮换流程写成脚本或用工具调度,减少手工失误导致的过期风险。etcd 的访问限制在控制平面网络里,etcd 数据也做了加密。
备份与灾备不能偷懒。我们定了定期的 etcd 快照,快照存到异地,并把恢复流程写成文档和自动化脚本,定期做恢复演练。备份策略里包括快照频率、保留天数、完整性校验和恢复演练窗口。除了 etcd,还把关键配置和 manifest(CRD、RBAC、NetworkPolicy 等)都版本化,遇到集群被破坏时能更快重建环境。
为方便日常检查,把可重复跑的清单放运维仓库里。关键命令示例都写清楚:
– 检查集群高权限绑定:
kubectl get clusterrolebinding -o yaml | grep -E “cluster-admin|system:masters” -n
– 查看命名空间的 Pod Security 标签:
kubectl get namespace prod -o jsonpath=”{.metadata.labels}”
– 验证 NetworkPolicy 生效(在测试 Pod 间做流量试验)
– 扫描镜像:
trivy image –severity HIGH,CRITICAL registry/app:tag
– 审计配置检查:
ps aux | grep kube-apiserver (确认审计参数是否被加载)
– 检查 Falco 是否在监控:
kubectl get pods -n falco
把这些命令放到 CI 或巡检脚本里,定期跑并把结果上报到运维面板,发现异常就触发工单。
做这套工作时也踩了不少坑,记录下来给大家参考。常见误区有几条:把 kube-admin 当日常账号;只扫描镜像但不管来源;以为 NetworkPolicy 一次写好就万无一失;不做恢复演练;审计日志只存在本地。对应的补救办法:查出高权限绑定并替换成最小角色,把私有仓库和 Admission 策略捆绑,定期把 NetworkPolicy 纳入变更管理并做流量验证,把恢复演练写进季度计划,把审计日志推到聚焦平台并设置告警。
过程中有两次小插曲值得一提:把 PodSecurityAdmission 强制到 restricted 时,有个老旧作业被拦截,临时把它移到隔离 namespace 跑旧流程,开发改好镜像后才迁回;启用 NetworkPolicy 后发现监控 agent 没被允许访问后端,补了白名单后恢复。这些都写进变更单,作为后续改善材料。
最后把所有检查表和自动化脚本放到版本控制里:权限、镜像策略、Pod 安全规则、NetworkPolicy、审计配置、备份脚本都以代码形式管理,变更有审批、有记录,能回滚也能追溯。保留好这些痕迹,出事时才好查。