
Kubernetes 已成为现代云原生应用的事实标准,但随着其广泛采用,集群面临的安全挑战也日益严峻。一个配置不当的集群可能成为攻击者的温床。本文将深入探讨10个关键的 Kubernetes 安全防护技巧,并提供具体的配置示例,帮助您系统性地加固集群,防范潜在威胁。
1. 实施最小权限RBAC原则
场景:开发团队经常为了方便而为服务账户授予过多权限,导致安全风险陡增。
案例:某电商平台因开发人员为 default 命名空间的服务账户授予 cluster-admin 权限,导致攻击者通过被入侵的 Pod 获取了集群的完全控制权。
反面示例:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: open-all
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: can-do-anything
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
解决方案:
遵循最小权限原则,只为应用创建其运行所必需的精确权限。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: read-only-configmaps
namespace: prod
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-only-configmaps
namespace: prod
subjects:
- kind: ServiceAccount
name: my-app
namespace: prod
roleRef:
kind: Role
name: read-only-configmaps
apiGroup: rbac.authorization.k8s.io
最佳实践:
- 定期审计 RBAC 配置,清理无用绑定。
- 避免在生产环境中使用
cluster-admin 角色。
- 为每个应用或服务账户创建特定的、范围明确的角色。
- 考虑禁用默认服务账户的自动挂载,或严格限制其权限。
2. 禁止容器以Root身份运行
场景:默认配置下,容器可能以 root 用户身份运行,一旦容器被突破,攻击者将获得较高的权限。
案例:某金融机构因容器以 root 运行,攻击者利用应用漏洞成功实施权限提升,获取节点 root 权限并窃取了敏感数据。
反面示例:
apiVersion: v1
kind: Pod
metadata:
name: insecure-app
spec:
containers:
- name: app
image: myapp:v1
# 未指定安全上下文,容器将以镜像定义的用户(常为root)运行
解决方案:
在 Pod 和容器级别配置安全上下文,强制以非 root 用户运行,并丢弃所有非必要的内核能力。
apiVersion: v1
kind: Pod
metadata:
name: secure-app
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
containers:
- name: app
image: secure-app:v1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"] # 丢弃所有特权能力
readOnlyRootFilesystem: true # 可选:根文件系统只读
3. 保护Kubernetes Dashboard和API端点
场景:管理界面(如 Dashboard)或 API Server 端点若暴露在公网且缺乏强认证,极易成为攻击入口。
案例:攻击者通过搜索引擎发现一个暴露在互联网且未配置认证的 Kubernetes Dashboard,直接获取管理员权限并删除了整个生产环境。
反面做法:通过 LoadBalancer 或 NodePort 类型的 Service 将 Dashboard 直接暴露至互联网。
解决方案:
- 使用端口转发进行安全访问:
kubectl port-forward -n kubernetes-dashboard service/kubernetes-dashboard 8080:443
然后通过 https://localhost:8080 在本地浏览器访问。
- 严格限制网络访问:通过云服务商的安全组、防火墙规则或 Kubernetes 的
NetworkPolicy,仅允许受信任的 IP 地址范围访问 API Server(默认端口 6443)和管理界面。
- 启用并强化认证:为 Dashboard 配置安全的认证方式,如令牌或集成 OIDC。
4. 加密存储Kubernetes Secrets
场景:Secrets 对象默认仅以 Base64 编码存储于 etcd 中,编码并非加密,任何有权访问 etcd 存储或 API 的人均可轻易解码获取明文。
案例:开发人员误以为 Base64 是加密算法,将数据库密码等敏感信息直接存入 Secret,导致在一次备份数据泄露事件中,生产凭证全部暴露。
解决方案:
配置 Kubernetes API Server 使用加密提供商(如 aescbc)对 Secret 数据进行静态加密。
- 创建加密配置文件 (
encryption-config.yaml):
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-32-byte-random-key> # 生成一个安全的随机密钥
- identity: {} # 保留identity提供程序以确保新secret被加密
- 配置 API Server:在 API Server 的启动参数中引用此配置文件:
--encryption-provider-config=/etc/kubernetes/encryption-config.yaml
- 重启 API Server 并更新所有现有 Secrets 以应用加密。
5. 实施容器镜像扫描与来源管控
场景:集群中可能运行着包含已知漏洞的旧版容器镜像,或从不可信的仓库拉取镜像。
案例:某零售商因持续使用一个包含高危漏洞的旧版 Nginx 镜像,被攻击者利用漏洞入侵,导致网站被篡改。
反面示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
template:
spec:
containers:
- name: app
image: someuser/random-image:latest # 从不可信源拉取“latest”标签
解决方案:
- 使用私有可信仓库:部署企业级私有镜像仓库(如 Harbor),并强制所有镜像必须从此仓库拉取。
- 集成镜像扫描:在 CI/CD 流水线或仓库中集成漏洞扫描工具(如 Trivy, Clair),阻断含高危漏洞的镜像部署。
- 使用准入控制:通过
ValidatingAdmissionPolicy 或 OPA/Gatekeeper 等策略控制器,强制实施镜像策略。
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: image-source-policy
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["pods"]
validations:
- expression: “object.spec.containers.all(c, c.image.startsWith(‘harbor.company.com/’))”
message: “只允许使用公司内部 Harbor 仓库的镜像”
6. 启用网络策略(Network Policy)
场景:默认情况下,Kubernetes 集群内的 Pod 之间可以任意通信(所有流量被允许),这为攻击者实施横向移动提供了便利。
案例:攻击者通过入侵一个前端 Pod,利用集群内无限制的网络访问,直接连接并攻击了后端的数据库 Pod。
解决方案:
通过定义 NetworkPolicy 来实现网络微隔离,控制 Pod 之间的流量。这就像为 Pod 设置了防火墙规则。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-restrict-traffic
spec:
podSelector:
matchLabels:
app: postgres-db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend-service
ports:
- protocol: TCP
port: 5432
此策略规定:只有带有 app: frontend-service 标签的 Pod 才能访问带有 app: postgres-db 标签的 Pod 的 5432 端口。注意:NetworkPolicy 需要集群网络插件(如 Calico, Cilium, Weave Net)的支持才能生效。
7. 定期轮换凭证与密钥
场景:长期有效的静态凭证(如 ServiceAccount token、数据库密码)一旦泄露,风险将持续存在。
案例:离职员工或第三方服务商仍持有未及时撤销的访问凭证,在外部恶意访问集群资源。
解决方案:
- 自动轮换 ServiceAccount Token:Kubernetes 1.24+ 开始,倾向于使用 TokenRequest API 获取短期有效的 token,而非挂载长期的
secret token。确保应用使用支持此机制的客户端库。
- 管理 Secrets 生命周期:对于存储在 Secret 中的凭证(如数据库密码),建立定期手动或自动轮换的流程。可以使用 外部 Secret 管理工具(如 External Secrets Operator)与 Vault 等系统集成,实现动态凭证管理。
- 使用加密配置:结合第4点的加密存储,为 Secrets 增加一层防护。
8. 使用Pod安全准入控制
场景:用户可能创建不安全的 Pod 配置(如特权模式、挂载宿主机目录),极大增加攻击面。
案例:攻击者利用一个配置了 privileged: true 的 Pod,成功实现容器逃逸,获得了宿主节点的完全控制权。
解决方案:
在 Kubernetes 1.23+ 中,原 PodSecurityPolicy (PSP) 已被弃用,取而代之的是内置的 Pod Security Admission。它通过为命名空间设置安全标准级别来工作。
- 为命名空间设置安全标准(例如
restricted 级别):
apiVersion: v1
kind: Namespace
metadata:
name: my-app
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: latest
restricted 级别策略的核心要求包括:
privileged: false (禁止特权容器)
allowPrivilegeEscalation: false (禁止权限提升)
runAsNonRoot: true (必须非 root 运行)
- 必须丢弃所有
CAP_SYS_ADMIN 等危险能力
- 限制使用主机名字空间、端口等
任何尝试在该命名空间创建违反此标准的 Pod 将被 API Server 拒绝。这为 Pod安全配置 提供了强制的基线保障。
9. 启用并监控集群审计日志
场景:缺乏详细的审计日志,使得异常行为和安全事件无法被追溯和分析。
案例:攻击者通过泄露的凭证在集群内进行隐秘的探测和资源创建,由于未开启审计日志,此活动数月后才被发现。
解决方案:
配置 Kubernetes API Server 的审计策略,记录关键操作。
- 创建审计策略文件 (
audit-policy.yaml):
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata # 记录请求的元数据(用户、时间、资源等)
resources:
- group: "" # 核心资源组
resources: ["secrets", "configmaps"] # 重点审计敏感资源
- group: "rbac.authorization.k8s.io"
resources: ["rolebindings", "clusterrolebindings"]
- level: RequestResponse # 对 Pod 的创建/删除等操作,记录请求和响应体
resources:
- group: ""
resources: ["pods"]
- 配置 API Server:在启动参数中指定审计策略和日志路径:
--audit-policy-file=/etc/kubernetes/audit-policy.yaml --audit-log-path=/var/log/kubernetes/audit.log
- 集中收集与分析:将审计日志导出到安全的日志平台(如 ELK Stack, Loki),并设置告警规则(如:短时间内多次
forbidden 请求可能为暴力破解)。
10. 定期更新Kubernetes版本与节点系统
场景:运行旧版本的 Kubernetes 或节点操作系统,意味着已知的安全漏洞未被修补。
案例:攻击者利用一个在 Kubernetes 新版本中已修复的 API Server 漏洞(如 CVE-2018-1002105),直接接管了未及时升级的集群。
解决方案:
总结
Kubernetes 安全是一个涉及多层次、多组件的系统性工程,绝非一劳永逸。上述10个技巧涵盖了从身份认证、权限管理、工作负载安全、网络安全到运维监控的关键方面。通过持续实施这些安全最佳实践,并定期进行审计、漏洞扫描和策略复审,才能为您的云原生应用构建起一道坚固的动态防御体系,确保集群在复杂威胁环境下的稳定与安全。