Kubernetes集群上线前如何加固:API端口、身份认证、RBAC与审计检查
面向具备基础操作能力的运维人员,梳理Kubernetes集群上线前的API端口与防火墙、身份认证、RBAC最小权限、审计日志及补丁检查,并提供正常与异常判定、配置留证、故障排查和回滚方法。

Kubernetes集群达到“可以访问”并不代表达到“可以上线”。正式接入业务流量前,应确认API入口仅对批准来源开放、匿名请求无法读取资源、用户与ServiceAccount遵循最小权限、关键操作能够写入审计日志,同时完成控制面、节点组件和操作系统的补丁核验。
以下步骤适用于具备控制面管理权限的自建集群。托管Kubernetes通常不能直接修改kube-apiserver静态Pod,应改用云平台提供的API访问控制、身份认证、审计日志和升级功能,并将平台侧配置与测试结果作为验收证据。
先确定验收边界并保存基线
变更前至少保留一个已验证可用的管理员会话,并准备节点控制台或带外登录方式。多控制面集群必须逐台变更,每台恢复就绪后才能处理下一台;不要同时修改所有API Server。
还需确认集群采用kubeadm、二进制部署还是托管控制面。下文中的/etc/kubernetes/manifests/是kubeadm常见路径,其他部署方式应先核对实际清单位置。静态Pod清单的备份不能放在该目录内,否则kubelet可能将备份文件也识别为清单。
在Linux控制面节点建立只允许当前用户访问的留证目录:
umask 077
EVIDENCE="$HOME/k8s-hardening-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$EVIDENCE"
kubectl version -o yaml > "$EVIDENCE/kubernetes-version.yaml"
kubectl get nodes -o wide > "$EVIDENCE/nodes.txt"
kubectl get --raw='/readyz?verbose' > "$EVIDENCE/apiserver-readyz.txt"
kubectl cluster-info > "$EVIDENCE/cluster-info.txt"
sudo ss -lntp > "$EVIDENCE/listening-ports.txt"
kubeadm部署还应备份API Server清单。文件中可能包含敏感路径和启动参数,备份目录应限制为root访问:
BACKUP="/root/k8s-hardening-backup-$(date +%Y%m%d-%H%M%S)"
sudo install -d -m 0700 "$BACKUP"
sudo cp -a /etc/kubernetes/manifests/kube-apiserver.yaml "$BACKUP/"
sudo chmod -R go-rwx "$BACKUP"
readyz中的关键检查项应为ok,节点应处于预期状态。如果加固前就存在就绪检查失败或节点失联,应先处理原有故障,避免将故障修复与安全变更混在同一窗口。
检查API端口和防火墙访问范围
“端口正在监听”不等于“端口已经安全”。Kubernetes集群的网络验收需要同时检查监听地址、主机防火墙、上游安全策略、负载均衡入口,以及从不同来源发起的实际连通测试。
先在控制面查看常见管理端口:
sudo ss -lntp | grep -E ':(6443|2379|2380|10250|10257|10259)\b'
| 端口 | 常见组件 | 正常访问范围 | 异常判定 |
|---|---|---|---|
| 6443 | kube-apiserver | 管理终端、工作节点、控制面及必要的负载均衡检查源 | 未经批准的公网或普通办公终端可连接 |
| 2379 | etcd客户端接口 | API Server及指定控制面地址 | 工作节点、业务网段或公网可访问 |
| 2380 | etcd成员通信 | etcd成员之间 | 非etcd成员可访问 |
| 10250 | kubelet API | 控制面及明确授权的监控、运维组件 | 公网或普通业务主机可访问 |
| 10257 | controller-manager安全端口 | 本机或授权控制面范围 | 对非必要网段开放 |
| 10259 | scheduler安全端口 | 本机或授权控制面范围 | 对非必要网段开放 |
NodePort、Ingress和CNI插件可能需要其他端口,不能仅凭通用表格直接关闭。应结合实际Pod、Service和节点地址形成集群自己的放行表:
kubectl -n kube-system get pods -o wide
kubectl get services -A
kubectl get nodes -o wide
随后分别从授权管理终端和未授权测试终端验证API入口:
nc -vz api.example.internal 6443
验收通过的分界是:授权终端和节点能够连接6443,未授权来源超时或被明确拒绝;2379和2380只能在预定控制面地址间通信。若6443确需提供公网访问,应限制固定来源,或通过兼容Kubernetes API访问方式的VPN、认证入口进行控制,并保留入口访问日志。
不要直接复制来源不明的iptables、nftables或firewalld规则,更不能清空现有规则。CNI和Service转发可能依赖特定链与接口,错误操作会同时影响Pod网络和节点通信。防火墙应先在上游访问控制层或单个控制面节点调整,验证API、etcd连接和节点心跳后再逐步推广;回滚时恢复变更前导出的规则或平台策略。
验证身份认证与高权限凭据
对于kubeadm常见静态Pod部署,可先检查API Server认证和授权参数:
sudo grep -nE -- \
'--anonymous-auth|--authorization-mode|--client-ca-file|--service-account-issuer|--service-account-key-file|--service-account-signing-key-file|--token-auth-file|--basic-auth-file' \
/etc/kubernetes/manifests/kube-apiserver.yaml
验收时不能只看参数是否存在,还要结合实际请求判断:
- 匿名认证应关闭。若未显式配置
--anonymous-auth=false,应按当前版本默认行为进行匿名请求测试。 --authorization-mode应包含Node和RBAC,不能使用AlwaysAllow。--client-ca-file应指向受保护的客户端CA文件。- ServiceAccount签发、验证参数应完整,相关私钥仅允许特权用户读取。
- 不应继续使用
--token-auth-file或基础认证文件。旧集群存在静态令牌时,应先迁移调用方,再关闭旧入口。
使用不携带客户端证书和Bearer Token的请求验证匿名访问。正式验收不能使用-k跳过TLS证书校验:
API_SERVER="$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')"
curl --silent --show-error \
--output /tmp/k8s-anonymous-response.txt \
--write-out '%{http_code}\n' \
--cacert /etc/kubernetes/pki/ca.crt \
"${API_SERVER}/api"
关闭匿名认证时通常应返回HTTP 401,也可能被前置访问控制直接拒绝。若返回200并包含API版本信息,说明匿名请求能够读取资源,应立即检查API Server和前置代理配置。若在非控制面终端测试,应从可信渠道取得CA证书。
高权限kubeconfig和私钥也属于上线验收范围:
sudo stat -c '%a %U:%G %n' \
/etc/kubernetes/admin.conf \
/etc/kubernetes/pki/ca.key \
/etc/kubernetes/pki/sa.key
这些文件不应被普通用户读取,也不应出现在共享目录、容器镜像或代码仓库。kubeadm集群还可检查由其管理的证书有效期:
sudo kubeadm certs check-expiration
其他部署方式应使用相应证书管理系统或openssl x509核验,不能假设所有证书均由kubeadm签发。
用实际授权结果验收RBAC最小权限
启用RBAC只是基础条件,真正需要排查的是过宽绑定、遗留主体和不必要的集群级权限。先导出当前配置,以便审查和回滚:
kubectl get clusterrolebindings -o yaml > "$EVIDENCE/clusterrolebindings.yaml"
kubectl get rolebindings -A -o yaml > "$EVIDENCE/rolebindings.yaml"
kubectl get clusterroles -o yaml > "$EVIDENCE/clusterroles.yaml"
kubectl get roles -A -o yaml > "$EVIDENCE/roles.yaml"
应优先确认:cluster-admin是否绑定给普通用户或业务ServiceAccount;高权限角色是否授权给system:authenticated或system:unauthenticated;业务主体是否拥有通配动词、通配资源、跨命名空间读取Secret或修改ClusterRoleBinding的能力;离职人员、旧流水线和废弃命名空间的绑定是否仍然存在。
具备身份模拟权限的管理员可以直接验证某个ServiceAccount的实际能力:
kubectl auth can-i --list \
--as=system:serviceaccount:app-prod:release-bot \
-n app-prod
kubectl auth can-i get secrets \
--as=system:serviceaccount:app-prod:release-bot \
--all-namespaces
kubectl auth can-i create clusterrolebindings \
--as=system:serviceaccount:app-prod:release-bot
普通发布账号对后两项通常应返回no,但最终标准必须以书面职责为准。控制器、备份系统和安全组件可能确实需要集群级权限,不能因权限较高就直接删除。
调整RBAC前,先单独导出准备删除或修改的绑定:
kubectl get clusterrolebinding OLD_BINDING_NAME -o yaml \
> "$EVIDENCE/old-clusterrolebinding.yaml"
新配置应先执行服务端校验:
kubectl apply --dry-run=server -f workload-reader.yaml
正式应用后重新运行kubectl auth can-i,既要确认危险权限已收回,也要确认业务所需的get、list、watch等操作仍然可用。若出现403,应根据审计日志中的主体、动词和资源补充精确权限,不要为了快速恢复而将整个用户组绑定到cluster-admin。
启用审计并验证日志确实写入
组件运行日志不能替代Kubernetes审计日志。有效的审计事件应能够说明谁在什么时间、从哪个来源、对哪个资源执行了什么操作,以及API Server返回的状态。
检查API Server是否配置审计策略和后端:
sudo grep -nE -- \
'--audit-policy-file|--audit-log-path|--audit-log-maxage|--audit-log-maxbackup|--audit-log-maxsize|--audit-webhook-config-file' \
/etc/kubernetes/manifests/kube-apiserver.yaml
如果日志后端和Webhook后端均不存在,API审计通常尚未启用。基础策略可以对Secret和令牌仅记录元数据,对RBAC变更和交互式Pod操作记录请求信息:
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
- RequestReceived
rules:
- level: Metadata
resources:
- group: ""
resources:
- secrets
- serviceaccounts/token
- level: Request
resources:
- group: rbac.authorization.k8s.io
resources:
- roles
- rolebindings
- clusterroles
- clusterrolebindings
- level: Request
resources:
- group: ""
resources:
- pods/exec
- pods/attach
- pods/portforward
- level: Metadata
启用审计会触发API Server静态Pod重建。操作前必须保留清单备份,多控制面环境逐台执行:
sudo install -d -m 0700 /var/log/kubernetes/audit
sudo install -o root -g root -m 0600 \
audit-policy.yaml \
/etc/kubernetes/audit-policy.yaml
在现有kube-apiserver容器参数中加入:
- --audit-policy-file=/etc/kubernetes/audit-policy.yaml
- --audit-log-path=/var/log/kubernetes/audit/audit.log
- --audit-log-maxage=14
- --audit-log-maxbackup=10
- --audit-log-maxsize=100
以上保留天数、备份数量和文件大小仅为配置示例,应按磁盘容量和合规要求确定。还需为容器增加挂载:
- mountPath: /etc/kubernetes/audit-policy.yaml
name: audit-policy
readOnly: true
- mountPath: /var/log/kubernetes/audit
name: audit-log
readOnly: false
并在静态Pod的volumes中加入:
- hostPath:
path: /etc/kubernetes/audit-policy.yaml
type: File
name: audit-policy
- hostPath:
path: /var/log/kubernetes/audit
type: Directory
name: audit-log
这些都是插入现有清单的片段,不能覆盖完整静态Pod文件。修改后立即验证:
kubectl get --raw='/readyz?verbose'
kubectl -n kube-system get pods -l component=kube-apiserver -o wide
kubectl get namespace default >/dev/null
sudo tail -n 20 /var/log/kubernetes/audit/audit.log
正常事件应包含auditID、stage、requestURI、verb、user、sourceIPs和responseStatus等字段。还应验证日志轮转、文件权限和磁盘监控;审计日志可能含有用户名、来源地址和请求内容,不应作为普通应用日志公开。
核对补丁状态并处理失败分支
端口、认证、RBAC和审计配置正确,并不能消除组件自身的漏洞风险。上线前至少记录API Server、kubelet、容器运行时和操作系统版本:
kubectl version -o yaml
kubectl get nodes \
-o custom-columns='NAME:.metadata.name,KUBELET:.status.nodeInfo.kubeletVersion,RUNTIME:.status.nodeInfo.containerRuntimeVersion,OS:.status.nodeInfo.osImage'
版本应处于组织批准的支持范围,并已核对相应安全公告和补丁;控制面与节点版本差异应符合该版本的官方偏差策略。操作系统安全更新如未完成,必须有延期审批和明确窗口。升级前还要验证etcd备份、控制面恢复流程和工作负载中断影响。
不同发行版的软件源、包锁定和升级顺序不同,不能在未核对环境时直接执行apt upgrade、dnf update或解除Kubernetes软件包锁定。
出现异常时按由外到内的顺序判断:
nc -vz api.example.internal 6443
curl --cacert /etc/kubernetes/pki/ca.crt "${API_SERVER}/readyz"
- TCP不通:检查DNS、负载均衡、上游策略和主机防火墙。
- TLS失败:检查证书域名、CA链和系统时间。
- 返回
401:网络和TLS通常正常,认证凭据未通过。 - 返回
403:身份已认证,但RBAC拒绝操作。 - 返回
5xx:检查API Server及其与etcd的连接。
修改静态Pod后API Server未恢复,可在对应节点查看kubelet和容器日志:
sudo journalctl -u kubelet --since "15 minutes ago" --no-pager
sudo crictl ps -a --name kube-apiserver
sudo crictl logs KUBE_APISERVER_CONTAINER_ID
常见原因包括YAML缩进错误、审计路径不存在、主机目录未挂载、文件权限不足或参数拼写错误。无法快速修复时,从控制台恢复原清单:
sudo cp -a \
/root/k8s-hardening-backup-时间戳/kube-apiserver.yaml \
/etc/kubernetes/manifests/kube-apiserver.yaml
等待kubelet重建静态Pod后,再检查readyz。RBAC变更导致业务出现403时,应重新应用变更前导出的RoleBinding或ClusterRoleBinding,并依据审计记录补充最小必要权限。
Kubernetes集群上线验收清单
- 6443仅对批准来源开放,未授权终端无法连接或被入口策略拒绝。
- 2379、2380、10250、10257、10259不存在非必要暴露。
- 匿名请求不能读取API资源,验收过程未跳过TLS验证。
- API Server启用RBAC授权,未使用
AlwaysAllow。 - 高权限kubeconfig、CA私钥和ServiceAccount私钥权限已核对。
- 所有
cluster-admin绑定均有明确责任人和使用理由。 - 业务ServiceAccount已通过
kubectl auth can-i验证最小权限。 - 审计策略已加载,关键API操作能够产生可检索事件。
- 审计日志已配置轮转、读取权限和磁盘监控。
- Kubernetes组件、容器运行时和操作系统版本已留证并核对补丁。
- 多控制面节点已逐台验证
readyz,工作节点保持Ready。 - 防火墙策略、API Server清单和RBAC对象均保留回滚副本。
- 上线后设置观察窗口,持续检查API
401、403、5xx、审计写入失败、节点失联和控制面重启。