2. Kubernetes集群安全基线:架构安全要点、API Server认证与授权(RBAC基础)、etcd加密与访问控制
2.1 Kubernetes架构安全要点
Kubernetes集群的安全基线建立在对其控制平面与工作节点之间通信、组件权限和敏感数据存储的深刻理解之上。任何安全策略的设计都应从架构层面识别攻击面,并逐层加固。
下表总结了Kubernetes主要组件的安全风险与基线加固措施:
| 组件 | 主要风险 | 基线加固措施 |
|---|---|---|
| API Server (kube-apiserver) | 未授权访问、暴力破解、匿名请求 | 启用TLS、关闭匿名认证、集成OIDC/LDAP、启用审计日志 |
| etcd | 数据泄露、中间人攻击、未授权读写 | 启用TLS双向认证、静态加密、防火墙限制访问来源 |
| Kubelet | 节点接管、容器逃逸、匿名API调用 | 启用kubelet证书轮换、关闭匿名访问、启用NodeRestriction准入控制器 |
| Controller Manager & Scheduler | 权限滥用、配置篡改 | 使用独立ServiceAccount、绑定最小RBAC权限、启用TLS |
| kube-proxy & CNI | 网络策略绕过、流量劫持 | 启用NetworkPolicy、限制iptables/ebpf规则修改权限 |
下图展示了Kubernetes控制平面与工作节点之间的安全通信架构,重点标注了TLS加密和认证边界:
2.2 API Server认证与授权(RBAC基础)
API Server的安全模型分为三个阶段:认证(Authentication) → 授权(Authorization) → 准入控制(Admission Control)。本节重点讲解认证与RBAC授权。
2.2.1 认证机制
Kubernetes支持多种认证策略,生产环境建议同时启用多个认证模块:
- X.509客户端证书: 最常用,通过kubeconfig中的client-certificate和client-key进行身份验证。
- ServiceAccount令牌: Pod内应用访问API Server的标准方式,使用JWT令牌。
- OpenID Connect (OIDC): 集成企业身份提供商(如Keycloak、Azure AD、Okta)。
- Webhook令牌认证: 将令牌验证委托给外部认证服务。
- 匿名请求: 默认启用但生产环境应关闭,或仅限健康检查等特定端点。
--anonymous-auth=false,并禁用 --insecure-port(该参数已在1.24+版本移除)。所有管理用户必须使用客户端证书或OIDC进行身份认证。
2.2.2 RBAC授权基础
RBAC(基于角色的访问控制)是Kubernetes推荐的授权模式。它通过四个核心API资源实现权限管理:
| API资源 | 作用域 | 说明 |
|---|---|---|
| Role | 命名空间 | 定义对特定命名空间内资源的操作权限(如get、list、create、delete) |
| ClusterRole | 集群级别 | 定义集群范围资源(Node、PV、ClusterRole)或跨命名空间资源的权限 |
| RoleBinding | 命名空间 | 将Role或ClusterRole绑定到User、Group或ServiceAccount(命名空间内生效) |
| ClusterRoleBinding | 集群级别 | 将ClusterRole绑定到User、Group或ServiceAccount(全局生效) |
以下是一个标准的RBAC配置示例,创建一个只读角色并绑定到开发人员:
# 1. 创建只读Role(命名空间:development)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: development
name: pod-reader
rules:
- apiGroups: [""] # 核心API组
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
---
# 2. 创建RoleBinding,将Role绑定到用户
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: development
name: read-pods-binding
subjects:
- kind: User
name: "dev-user@example.com"
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
kubectl auth can-i --as=dev-user@example.com get pods -n development 验证权限是否生效。
下图展示了API Server的认证与授权流程,以及RBAC资源之间的关系:
2.3 etcd加密与访问控制
etcd存储了集群的所有配置、状态和Secret。如果etcd被攻破,整个集群的安全将不复存在。因此,etcd的加密与访问控制是Kubernetes安全基线的重中之重。
2.3.1 传输层加密(TLS)
etcd支持TLS双向认证,确保只有持有合法证书的客户端(主要是API Server)才能建立连接:
- --cert-file 和 --key-file:etcd服务端证书,用于向客户端证明身份。
- --client-cert-auth:启用客户端证书认证,etcd会验证API Server提供的客户端证书。
- --trusted-ca-file:CA根证书,用于验证客户端证书的签发者。
- --peer-cert-file 和 --peer-key-file:etcd集群节点间通信的证书。
2.3.2 静态数据加密(Encryption at Rest)
Kubernetes从1.7版本开始支持对etcd中的资源进行静态加密。通过配置EncryptionConfiguration对象,可以指定哪些资源需要加密以及使用哪种加密算法:
# encryption-config.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
- configmaps
- serviceaccounts
providers:
- aescbc:
keys:
- name: key1
secret: c2VjdXJlLWVuY3J5cHRpb24ta2V5LTE=
- identity: {} # 回退到明文存储(用于未加密的旧数据)
API Server启动参数中引用该配置文件:
--encryption-provider-config=/etc/kubernetes/encryption-config.yaml
secrets 资源启用静态加密。建议同时加密 configmaps 和 serviceaccounts,因为ConfigMap可能包含配置密码,ServiceAccount令牌也是敏感凭证。加密密钥应定期轮换,并存储在安全的密钥管理服务(KMS)中,而非直接写在配置文件中。
2.3.3 访问控制
除了TLS和加密,还需要从网络和操作系统层面限制对etcd的访问:
| 控制层面 | 措施 | 说明 |
|---|---|---|
| 网络层 | 防火墙/安全组 | 仅允许API Server的IP地址访问etcd端口(默认2379/tcp) |
| 网络层 | 独立网络命名空间 | 将etcd部署在独立的网络平面或VPC子网中 |
| 主机层 | 文件权限 | etcd数据目录(/var/lib/etcd)权限设置为700,仅etcd用户可读写 |
| 主机层 | 审计日志 | 启用etcd的审计日志,记录所有读写操作 |
| 集群层 | 最小化API Server权限 | API Server仅使用必要的etcd权限(读/写特定前缀) |
etcdctl 工具测试访问控制是否生效。例如,从非API Server的节点尝试访问etcd应被拒绝:ETCDCTL_API=3 etcdctl --endpoints=https://etcd-server:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key get / --prefix --keys-only。如果网络策略正确,该命令应超时或返回连接拒绝。
下图展示了etcd的加密与访问控制分层防御模型:
2.4 基线检查清单
完成本章学习后,请对照以下清单检查你的Kubernetes集群安全基线状态:
| 检查项 | 标准 | 验证命令/方法 |
|---|---|---|
| API Server匿名访问 | 已关闭 | kubectl get --raw /api/v1 | grep anonymous |
| API Server TLS | 启用TLS 1.2+ | openssl s_client -connect <apiserver>:6443 -tls1_2 |
| RBAC启用 | --authorization-mode=RBAC | kubectl get pod -n kube-system kube-apiserver -o yaml | grep authorization-mode |
| 最小权限ServiceAccount | 每个命名空间有独立SA | kubectl get sa --all-namespaces |
| etcd TLS双向认证 | 启用client-cert-auth | 检查etcd Pod启动参数 |
| etcd静态加密 | Secret已加密 | kubectl get secret -o yaml | grep -i aescbc |
| etcd网络隔离 | 仅API Server可访问 | 从非控制平面节点telnet etcd端口 |