当你的 Kubernetes 集群从开发环境走向生产环境,有两个话题再也无法回避——安全 与可观测性 。安全是底线,确保只有正确的主体才能访问正确的资源;可观测性是生命线,让你在问题发生时能快速定位、快速恢复。
本文将从 K8s 安全的 4C 模型出发,深入 RBAC 权限控制、Pod 安全标准与服务账户管理;随后转向可观测性的三大支柱——指标、日志与链路追踪,构建一套完整的监控与诊断体系。
一、K8s 安全架构概览
1.1 4C 安全模型
Kubernetes 社区提出了经典的 4C 安全模型 ,将安全分为四个层次,从外到内逐层收紧:
层次 名称 关注点 示例 第 1 层 Cloud (云)云平台自身的安全配置 IAM 策略、VPC、防火墙规则 第 2 层 Cluster (集群)集群组件的访问控制 RBAC、网络策略、审计日志 第 3 层 Container (容器)容器运行时安全 镜像签名、只读根文件系统、非 root 运行 第 4 层 Code (代码)应用代码自身的安全 输入校验、依赖漏洞、密钥管理
4C 模型的关键思想是纵深防御(Defense in Depth) ——任何单一层次的安全措施都不足以应对所有威胁,只有层层设防,才能构建真正可靠的安全体系。内层的安全措施不应依赖外层,每一层都应独立提供保护。
1.2 安全最佳实践总览
领域 最佳实践 认证 启用 TLS 双向认证,禁用匿名访问 授权 最小权限原则,使用 RBAC 精细控制 Pod 安全 强制非 root 运行,只读根文件系统 网络 默认拒绝,按需开放 NetworkPolicy 镜像 使用可信仓库,启用镜像签名验证 密钥 使用外部密钥管理(Vault/AWS KMS),避免明文存储 审计 启用 API Server 审计日志,记录所有变更
二、RBAC:基于角色的访问控制
2.1 核心概念
RBAC(Role-Based Access Control)是 K8s 授权机制中最常用、最推荐的方式。它通过四个核心对象实现权限管理:
对象 作用范围 说明 Role 命名空间级别 定义在某个命名空间内的权限规则 ClusterRole 集群级别 定义集群范围的权限规则 RoleBinding 命名空间级别 将 Role 绑定到用户/组/服务账户 ClusterRoleBinding 集群级别 将 ClusterRole 绑定到用户/组/服务账户
Role vs ClusterRole 的关键区别
Role 只能管理同一个命名空间 内的资源
ClusterRole 可以管理所有命名空间 以及非命名空间资源 (如 Node、PersistentVolume、Namespace)
2.2 RBAC 权限模型
2.3 完整 YAML 示例
Role —— 命名空间管理员
apiVersion : rbac.authorization.k8s.io/v1
kind : Role
metadata :
name : namespace - admin
namespace : production
rules :
- apiGroups : [ "" , "apps" , "batch" ]
resources :
- pods
- pods/log
- deployments
- services
- configmaps
- secrets
- jobs
- cronjobs
verbs : [ "get" , "list" , "watch" , "create" , "update" , "patch" , "delete" ]
ClusterRole —— 只读查看者
apiVersion : rbac.authorization.k8s.io/v1
kind : ClusterRole
metadata :
name : cluster - readonly
rules :
- apiGroups : [ "" , "apps" , "batch" , "extensions" ]
resources : [ "*" ]
verbs : [ "get" , "list" , "watch" ]
- nonResourceURLs : [ "/healthz" , "/version" , "/metrics" ]
verbs : [ "get" ]
RoleBinding —— 将角色绑定到用户
apiVersion : rbac.authorization.k8s.io/v1
kind : RoleBinding
metadata :
name : bind - namespace - admin
namespace : production
subjects :
- kind : User
name : alice@example.com
apiGroup : rbac.authorization.k8s.io
- kind : Group
name : dev - team
apiGroup : rbac.authorization.k8s.io
roleRef :
kind : Role
name : namespace - admin
apiGroup : rbac.authorization.k8s.io
ClusterRoleBinding —— 将只读角色绑定到服务账户
apiVersion : rbac.authorization.k8s.io/v1
kind : ClusterRoleBinding
metadata :
name : bind - readonly - to - monitor
subjects :
- kind : ServiceAccount
name : prometheus
namespace : monitoring
roleRef :
kind : ClusterRole
name : cluster - readonly
apiGroup : rbac.authorization.k8s.io
2.4 常见 RBAC 模式
模式 适用场景 实现方式 命名空间管理员 团队负责人管理自己的命名空间 Role + RoleBinding 只读查看者 开发/测试人员查看集群状态 ClusterRole + ClusterRoleBinding 开发人员 开发者在指定命名空间部署应用 Role(限制 verbs) + RoleBinding 运维人员 运维管理节点、PV 等集群级资源 ClusterRole(节点/PV 权限) + ClusterRoleBinding 聚合角色 将多个 ClusterRole 合并为一个统一角色 ClusterRole + aggregationRule
ClusterRole 聚合(Aggregated ClusterRoles)
Kubernetes 支持通过 aggregationRule 将多个 ClusterRole 聚合为一个组合角色。控制平面会自动监视匹配标签选择器的 ClusterRole,并将其规则合并到聚合角色的 rules 字段中。默认的用户角色(如 admin、edit、view)就是通过聚合机制实现的,允许集群管理员通过添加匹配标签的 ClusterRole 来扩展默认角色的权限。
apiVersion : rbac.authorization.k8s.io/v1
kind : ClusterRole
metadata :
name : monitoring
aggregationRule :
clusterRoleSelectors :
- matchLabels :
rbac.example.com/aggregate-to-monitoring : "true"
rules : [ ]
roleRef 一旦创建不可修改 ,如需变更必须删除重建 Binding
避免使用 verbs: ["*"] 和 resources: ["*"] 的通配符,遵循最小权限原则
定期审计集群中的 RoleBinding 和 ClusterRoleBinding,清理不再需要的权限
三、Pod 安全标准
3.1 从 PSP 到 PSS
Kubernetes 在 v1.21 中废弃了 PodSecurityPolicy(PSP) ,并在 v1.25 中完全移除 。取而代之的是 Pod Security Standards(PSS) + Pod Security Admission(PSA) 机制。
特性 PSP(已废弃) PSS + PSA(推荐) 实现方式 准入控制器(Admission Controller) 内置准入插件 配置粒度 每个 Pod 可绑定不同策略 按命名空间统一标签 策略继承 支持 不支持(需借助第三方 Gatekeeper) 状态 v1.25 已移除 v1.23+ 内置可用
3.2 三种策略级别
级别 说明 典型控制 Privileged 无限制,完全开放 无任何控制 Baseline 最低限度的安全防护 禁止特权容器、禁止挂载宿主机路径、限制 hostNetwork、限制 SELinux 类型、禁止探针/生命周期钩子中的 host 字段(v1.34+)、限制 AppArmor 配置文件、限制安全 sysctl Restricted 高度安全,生产推荐 强制非 root、只读根文件系统、限制 Capabilities(仅允许 NET_BIND_SERVICE)、禁止 seccomp profile=unconfined、要求显式设置 seccomp
Baseline 策略的完整控制列表(基于 v1.34 官方文档)
根据 Pod Security Standards 官方文档 ,Baseline 策略包含以下控制:
控制项 说明 HostProcess 禁止 Windows HostProcess 容器 Host Namespaces 禁止共享 hostNetwork/hostPID/hostIPC Privileged Containers 禁止特权容器 Capabilities 限制可添加的 Capabilities(如 AUDIT_WRITE、CHOWN、NET_BIND_SERVICE 等) HostPath Volumes 禁止 hostPath 卷 Host Ports 禁止或限制 hostPort Host Probes / Lifecycle Hooks (v1.34+)禁止探针和生命周期钩子中的 host 字段 AppArmor 限制 AppArmor 配置文件类型(RuntimeDefault/Localhost) SELinux 限制 SELinux 类型(container_t/container_init_t/container_kvm_t/container_engine_t),禁止自定义 user/role /proc Mount Type 要求使用默认 /proc 掩码 Seccomp 禁止显式设置为 Unconfined Sysctls 仅允许安全 sysctl 子集
3.3 Pod Security Admission 配置
PSA 通过在命名空间上打标签来生效,支持三种执行模式:
apiVersion : v1
kind : Namespace
metadata :
name : production
labels :
pod-security.kubernetes.io/enforce : restricted
pod-security.kubernetes.io/audit : restricted
pod-security.kubernetes.io/warn : restricted
pod-security.kubernetes.io/enforce-version : latest
3.4 v1.34 新增安全控制详解
Kubernetes v1.34 在 Pod Security Standards 中引入了多项重要安全控制更新:
3.4.1 Host Probes / Lifecycle Hooks(v1.34+)
这是 v1.34 中 Baseline 策略新增的控制项,禁止在探针和生命周期钩子中使用 host 字段,防止容器通过 HTTP/TCP 探针访问宿主机网络。
受限字段 包括:
livenessProbe.httpGet.host / readinessProbe.httpGet.host / startupProbe.httpGet.host
livenessProbe.tcpSocket.host / readinessProbe.tcpSocket.host / startupProbe.tcpSocket.host
lifecycle.postStart.httpGet.host / lifecycle.preStop.httpGet.host
lifecycle.postStart.tcpSocket.host / lifecycle.preStop.tcpSocket.host
允许值 :Undefined/nil 或空字符串 ""
这意味着在 Baseline 策略下,探针和生命周期钩子不能再指向宿主机的 IP 地址或主机名,有效防止了通过探针机制进行的 SSRF(服务端请求伪造)攻击。
3.4.2 SELinux 类型扩展
SELinux 控制在 Baseline 策略中进一步收紧:
允许的 SELinux 类型 :container_t、container_init_t、container_kvm_t、container_engine_t(自 Kubernetes 1.31起新增)
禁止 :自定义 SELinux user 和 role 选项(允许值仅为 Undefined/"")
container_engine_t 类型适用于需要与容器引擎交互的特殊工作负载场景。
3.4.3 安全 Sysctls 扩展
自 Kubernetes 1.29 起,Baseline 策略允许的安全 sysctl 列表新增了以下 TCP keepalive 相关参数:
Sysctl 名称 说明 新增版本 net.ipv4.tcp_keepalive_timeTCP keepalive 探测间隔 since 1.29 net.ipv4.tcp_fin_timeoutTCP FIN 超时时间 since 1.29 net.ipv4.tcp_keepalive_intvlTCP keepalive 探测间隔 since 1.29 net.ipv4.tcp_keepalive_probesTCP keepalive 探测次数 since 1.29
完整的安全 sysctl 列表还包括:kernel.shm_rmid_forced、net.ipv4.ip_local_port_range、net.ipv4.ip_unprivileged_port_start、net.ipv4.tcp_syncookies、net.ipv4.ping_group_range、net.ipv4.ip_local_reserved_ports(since 1.27)。
3.4.4 AppArmor 控制
Baseline 策略对 AppArmor 配置文件的控制:
允许的类型 :RuntimeDefault、Localhost,或通过注解 container.apparmor.security.beta.kubernetes.io/* 设置 runtime/default、localhost/*
目的 :防止禁用或绕过默认的 AppArmor 安全配置文件
3.5 SecurityContext 配置
SecurityContext 是 Pod 安全的核心配置点,可以在 Pod 级别和容器级别分别设置:
apiVersion : v1
kind : Pod
metadata :
name : secure - pod
namespace : production
spec :
securityContext :
runAsNonRoot : true
runAsUser : 1000
runAsGroup : 3000
fsGroup : 2000
seccompProfile :
type : RuntimeDefault
containers :
- name : app
image : nginx : 1.25
securityContext :
allowPrivilegeEscalation : false
readOnlyRootFilesystem : true
capabilities :
drop :
- ALL
add :
- NET_BIND_SERVICE
seccompProfile :
type : RuntimeDefault
volumeMounts :
- name : tmp
mountPath : /tmp
- name : cache
mountPath : /var/cache/nginx
volumes :
- name : tmp
emptyDir : { }
- name : cache
emptyDir : { }
当设置 readOnlyRootFilesystem: true 时,Nginx 等应用需要写入 /tmp 和缓存目录。通过 emptyDir 提供临时可写目录,既满足了应用需求,又保持了根文件系统的只读安全。
四、服务账户与 Token 管理
4.1 ServiceAccount 概念
Kubernetes 中每个 Pod 都关联一个服务账户(ServiceAccount) ,用于标识 Pod 的身份。当 Pod 需要访问 API Server 时,使用的就是 ServiceAccount 的凭证。
apiVersion : v1
kind : ServiceAccount
metadata :
name : app - service - account
namespace : production
automountServiceAccountToken : false
4.2 自动挂载 Token 的风险
默认情况下,K8s 会将 ServiceAccount Token 自动挂载到每个 Pod 的 /var/run/secrets/kubernetes.io/serviceaccount/ 目录。这意味着:
任何能进入容器的人都能获取 Token
如果容器被攻破,攻击者可以利用 Token 访问 API Server
对于不需要访问 API Server 的 Pod,这是不必要的安全暴露
apiVersion : v1
kind : Pod
metadata :
name : app - no - token
spec :
serviceAccountName : app - service - account
automountServiceAccountToken : false
containers :
- name : app
image : myapp : latest
apiVersion : v1
kind : ServiceAccount
metadata :
name : app - service - account
namespace : production
automountServiceAccountToken : false
4.3 外部 Token 供应
对于需要更精细控制 Token 生命周期(如短时效 Token、Token 轮换)的场景,可以使用 TokenRequest API 获取面向 Pod 的绑定 Token:
apiVersion : v1
kind : Pod
metadata :
name : app - with - projected - token
spec :
containers :
- name : app
image : myapp : latest
volumeMounts :
- name : token
mountPath : /var/run/secrets/tokens
volumes :
- name : token
projected :
sources :
- serviceAccountToken :
path : token
expirationSeconds : 3600
audience : api
不需要访问 API Server 的 Pod :设置 automountServiceAccountToken: false
需要访问 API Server 的 Pod :创建专用的 ServiceAccount,配合最小权限的 RBAC
高安全要求场景 :使用 projected volume + 短时效 Token,实现自动轮换
五、可观测性体系概览
5.1 三大支柱
可观测性(Observability)的三大支柱构成了完整的系统诊断能力:
支柱 回答的问题 典型工具 数据特征 Metrics(指标) 系统现在是什么状态? Prometheus、Thanos 结构化数值,适合聚合与告警 Logs(日志) 系统发生了什么? Fluent Bit、Loki、ELK 非结构化文本,适合问题排查 Traces(链路追踪) 请求经过了哪些路径? Jaeger、Zipkin、Tempo 结构化事件流,适合性能分析与故障定位
单一支柱无法回答所有问题。指标告诉你"CPU 使用率 90%",但不能告诉你"是哪个请求导致的";日志告诉你"请求超时了",但不能告诉你"请求在哪个服务卡住了"。只有三者结合,才能快速、准确地定位问题。
六、Prometheus + Grafana:指标监控
6.1 Prometheus 在 K8s 中的部署
在生产环境中,推荐使用 kube-prometheus-stack (基于 Prometheus Operator)一键部署完整的监控栈:
Prometheus Operator 引入了四个自定义资源(CRD)来声明式管理监控配置:
CRD 作用 Prometheus 管理 Prometheus 实例的生命周期 ServiceMonitor 基于 Service 选择器自动发现监控目标 PodMonitor 基于 Pod 标签直接发现监控目标 PrometheusRule 声明式定义告警规则和录制规则
6.2 核心监控指标
级别 关键指标 说明 容器级 container_cpu_usage_seconds_total容器 CPU 使用量 container_memory_working_set_bytes容器实际内存使用(含 Page Cache) container_fs_usage_bytes容器文件系统使用量 Pod 级 kube_pod_status_phasePod 当前阶段(Pending/Running/Succeeded/Failed) kube_pod_container_status_restarts_totalPod 重启次数 kube_pod_container_status_waiting_reason容器等待原因(ImagePullBackOff 等) Node 级 node_cpu_seconds_total节点 CPU 使用量 node_memory_MemAvailable_bytes节点可用内存 kube_node_status_condition节点状态(Ready/NotReady)
6.3 ServiceMonitor 示例
apiVersion : monitoring.coreos.com/v1
kind : ServiceMonitor
metadata :
name : app - service - monitor
namespace : monitoring
labels :
release : prometheus
spec :
selector :
matchLabels :
app : my - application
namespaceSelector :
names :
- production
endpoints :
- port : http
path : /metrics
interval : 30s
scrapeTimeout : 10s
6.4 告警规则示例
apiVersion : monitoring.coreos.com/v1
kind : PrometheusRule
metadata :
name : app - alerting - rules
namespace : monitoring
labels :
release : prometheus
spec :
groups :
- name : app - alerts
rules :
- alert : PodCrashLooping
expr : rate(kube_pod_container_status_restarts_total [ 15m ] ) * 60 * 5 > 0
for : 15m
labels :
severity : critical
annotations :
summary : "Pod {{ $labels.namespace }}/{{ $labels.pod }} 处于 CrashLoopBackOff"
description : "容器 {{ $labels.container }} 在过去 15 分钟内重启超过 5 次"
- alert : HighMemoryUsage
expr : |
(container_memory_working_set_bytes / container_spec_memory_limit_bytes) > 0.9
and container_spec_memory_limit_bytes > 0
for : 5m
labels :
severity : warning
annotations :
summary : "容器 {{ $labels.container }} 内存使用率超过 90%"
description : "当前使用 {{ $value | humanizePercentage }},限制 {{ $labels.container }}"
- alert : NodeNotReady
expr : kube_node_status_condition { condition="Ready" , status="true" } == 0
for : 5m
labels :
severity : critical
annotations :
summary : "节点 {{ $labels.node }} 处于 NotReady 状态"
Critical 告警 :需要立即响应(如节点宕机、Pod CrashLoop)
Warning 告警 :需要关注但不必立即处理(如磁盘使用率 > 80%)
设置合理的 for 持续时间,避免瞬时抖动触发误报
告警信息要包含足够的上下文,让值班人员无需额外查询即可判断影响范围
七、日志收集体系
7.1 日志收集模式对比
模式 原理 优点 缺点 Sidecar 每个 Pod 注入一个日志采集容器 隔离性好,可按应用定制 资源开销大,管理复杂 DaemonSet 每个 Node 运行一个采集 Agent 资源开销低,管理简单 需要共享日志卷 直连 应用直接推送日志到后端 无需额外组件 与后端强耦合,侵入应用
7.2 常见方案对比
方案 组合 特点 适用场景 PLG Stack Promtail + Loki + Grafana 轻量,与 Grafana 深度集成 已有 Grafana 的团队 EFK Stack Fluentd/Fluent Bit + Elasticsearch + Kibana 功能强大,全文搜索 大规模日志分析 Fluent Bit + Loki Fluent Bit + Loki + Grafana 极低资源消耗 资源敏感的环境
7.3 Fluent Bit DaemonSet 配置
apiVersion : apps/v1
kind : DaemonSet
metadata :
name : fluent - bit
namespace : logging
labels :
app : fluent - bit
spec :
selector :
matchLabels :
app : fluent - bit
template :
metadata :
labels :
app : fluent - bit
spec :
serviceAccountName : fluent - bit
tolerations :
- key : node - role.kubernetes.io/control - plane
effect : NoSchedule
containers :
- name : fluent - bit
image : fluent/fluent - bit : 3.0.0
volumeMounts :
- name : varlog
mountPath : /var/log
readOnly : true
- name : containers
mountPath : /var/lib/docker/containers
readOnly : true
- name : config
mountPath : /fluent - bit/etc/fluent - bit.conf
subPath : fluent - bit.conf
volumes :
- name : varlog
hostPath :
path : /var/log
- name : containers
hostPath :
path : /var/lib/docker/containers
- name : config
configMap :
name : fluent - bit - config
八、链路追踪
8.1 OpenTelemetry 在 K8s 中的集成
OpenTelemetry(OTel) 是 CNCF 的可观测性标准框架,统一了指标、日志和链路追踪的数据采集。在 K8s 中,通常部署 OpenTelemetry Collector 作为数据的统一入口:
apiVersion : apps/v1
kind : Deployment
metadata :
name : otel - collector
namespace : observability
spec :
replicas : 2
selector :
matchLabels :
app : otel - collector
template :
metadata :
labels :
app : otel - collector
spec :
containers :
- name : otel - collector
image : otel/opentelemetry - collector - contrib : 0.96.0
args :
- - - config=/etc/otelcol/config.yaml
ports :
- containerPort : 4317
- containerPort : 4318
- containerPort : 8889
volumeMounts :
- name : config
mountPath : /etc/otelcol
volumes :
- name : config
configMap :
name : otel - collector - config
8.2 分布式追踪最佳实践
实践 说明 统一 SDK 接入 所有服务使用 OpenTelemetry SDK,自动注入 Trace Context 合理的采样策略 生产环境使用尾部采样(Tail Sampling),基于错误率/延迟/状态码决定是否保留 上下文传播 确保跨服务调用时 TraceID 正确传播(HTTP Header、gRPC Metadata) 关联日志与追踪 在日志中注入 TraceID,实现日志与追踪的联动查询 设置合理的 Span 层级 避免过深的 Span 嵌套,关注关键路径和外部调用
在应用日志中添加 TraceID 字段,可以在 Grafana 中实现从告警到日志再到追踪的完整排查链路:
# 应用日志示例
2026-04-09 10:23:45 INFO [trace_id=abc123 span_id=def456] Processing order request from user_1234
2026-04-09 10:23:46 ERROR [trace_id=abc123 span_id=def456] Failed to call payment service: timeout
九、本章小结
本文从安全与可观测性两个维度,系统梳理了 Kubernetes 生产环境中的关键能力:
安全体系方面 ,我们覆盖了从 4C 安全模型到具体实践的完整链路:
RBAC 提供了精细的权限控制,通过 Role/ClusterRole 和 Binding 的组合,实现最小权限原则。ClusterRole 还支持 aggregationRule 聚合机制,便于扩展默认角色权限。
Pod Security Standards 替代了已废弃的 PSP,通过 PSA 标签为命名空间设置安全基线。v1.34 中 Baseline 策略新增了 Host Probes/Lifecycle Hooks 控制,SELinux 新增 container_engine_t 类型,安全 sysctl 列表也进一步扩展。
ServiceAccount Token 管理 教会我们如何控制 Pod 的 API Server 访问权限,避免不必要的凭证暴露。
可观测性体系方面 ,我们构建了三大支柱的完整图景:
Prometheus + Grafana 负责指标采集、可视化与告警,是监控体系的核心
Fluent Bit + Loki 提供轻量高效的日志收集与查询能力
OpenTelemetry + Jaeger 实现了分布式链路追踪,让跨服务调用路径一目了然
安全与可观测性不是孤立的话题——良好的可观测性是安全事件响应的基础,而安全策略本身也需要被持续监控。在下一篇文章中,我们将深入 Kubernetes 的调度策略与资源管理,探讨如何让集群的每一份资源都物尽其用。
十、官方文档参考
本文内容基于 Kubernetes v1.34 官方文档校验,以下是相关官方文档链接:
安全相关
可观测性相关
系列导航