本文边界:本文聚焦 API Server 的 TLS 连接、证书链、kubeconfig 与 SAN 匹配;认证后的权限判定和 RBAC 配置请阅读授权专题。
说明:本文由 Codex 根据作者提供的主题、素材与公开资料辅助生成,属于 AI 生成/整理内容,非作者原创。请读者自行甄别并交叉验证。
先说结论#
在 Kubernetes 里,证书、kubeconfig 和 API Server 的关系可以这样理解:
API Server 是 HTTPS 服务端;
证书负责证明“谁在和谁通信”;
kubeconfig 是客户端连接 API Server 时使用的一组配置。更具体一点:
- API Server 暴露 Kubernetes API,默认监听
6443。 - API Server 的服务端证书证明“这个地址上的服务确实是目标 API Server”。
- 客户端证书、Token 或其他认证方式证明“发起请求的用户或组件是谁”。
kubeconfig记录集群地址、CA 证书、用户凭据和当前上下文。
所以,当 kubectl 报 TLS、证书、x509、certificate is valid for ... not ... 这类错误时,本质上是在说:
客户端想连接的 server 地址,
和 API Server 证书里声明可信的名字或 IP,
没有匹配上。API Server 是什么角色#
API Server 是 Kubernetes 控制平面的入口。
所有集群操作最终都会变成对 API Server 的请求:
kubectl get pods是读 API Server。kubectl apply -f app.yaml是写 API Server。- kubelet 上报 Node 和 Pod 状态,也是调用 API Server。
- scheduler、controller-manager 监听资源变化,也通过 API Server。
从客户端视角看,API Server 就是一个 HTTPS API:
https://<api-server-address>:6443因此它和普通 HTTPS 服务一样,需要 TLS 证书来保证通信安全。
Kubernetes 为什么需要证书#
Kubernetes 集群内部存在大量组件间通信:
kubectl到 API Server。- kubelet 到 API Server。
- controller-manager 到 API Server。
- scheduler 到 API Server。
- API Server 到 kubelet。
- API Server 聚合层到 extension API Server。
这些通信通常都基于 TLS。
TLS 在这里解决两个问题:
- 加密:网络中的第三方不能直接读取通信内容。
- 身份:通信双方能确认对方是谁。
Kubernetes 官方文档也强调,Kubernetes 需要 PKI 证书来完成 TLS 认证;使用 kubeadm 安装时,所需证书默认会自动生成。
CA、服务端证书和客户端证书#
Kubernetes 证书体系里最关键的是 CA。
CA 可以理解为集群内部的“信任根”。只要某个证书是由可信 CA 签发的,客户端或服务端就可以通过 CA 验证它。
常见证书可以粗略分成三类。
CA 证书#
CA 证书用于签发其他证书。
在 kubeadm 集群里,常见路径是:
/etc/kubernetes/pki/ca.crt
/etc/kubernetes/pki/ca.key其中:
ca.crt是公开证书,可以放到客户端用于验证。ca.key是私钥,必须严格保护。
如果 CA 私钥泄露,攻击者就可能签发看似可信的组件证书。
API Server 服务端证书#
API Server 服务端证书通常包括:
/etc/kubernetes/pki/apiserver.crt
/etc/kubernetes/pki/apiserver.key这个证书用于证明:
客户端正在访问的 HTTPS 服务,
确实是由集群 CA 签发的 API Server。客户端连接 API Server 时,会检查:
- 证书是否由可信 CA 签发。
- 证书是否过期。
- 证书里的 DNS 名称或 IP 是否包含当前访问的地址。
第三点就是很多 x509 错误的来源。
客户端证书#
客户端证书用于证明请求方身份。
例如管理员 kubeconfig 里通常会包含:
users:
- name: kubernetes-admin
user:
client-certificate-data: ...
client-key-data: ...API Server 收到请求后,会先完成 TLS 层的客户端认证,再结合 Kubernetes 的认证、授权链路判断这个身份能做什么。
SAN 为什么重要#
SAN 是 Subject Alternative Name,即证书里声明的可用 DNS 名称或 IP 地址。
现代 TLS 客户端主要看 SAN,而不是只看证书的 Common Name。
假设 API Server 证书只包含:
10.0.0.10
kubernetes
kubernetes.default
kubernetes.default.svc这时如果 kubeconfig 里的 server 写成:
server: https://api.example.com:6443客户端就会报错,因为证书没有声明 api.example.com 是可信名称。
典型错误类似:
x509: certificate is valid for 10.0.0.10, kubernetes, kubernetes.default,
not api.example.com这不是 API Server 没启动,也不一定是网络不通,而是 TLS 身份校验失败。
kubeconfig 到底是什么#
kubeconfig 不是一个固定文件名,而是一类用于配置 Kubernetes 访问方式的文件。
默认情况下,kubectl 会读取:
$HOME/.kube/config也可以通过环境变量或命令行参数指定:
KUBECONFIG=/path/to/config kubectl get nodes
kubectl --kubeconfig=/path/to/config get nodes一个 kubeconfig 主要包含三部分:
clusters:
- name: demo
cluster:
server: https://api.example.com:6443
certificate-authority-data: ...
users:
- name: admin
user:
client-certificate-data: ...
client-key-data: ...
contexts:
- name: demo-admin
context:
cluster: demo
user: admin
namespace: default
current-context: demo-admin可以这样理解:
| 字段 | 作用 |
|---|---|
clusters[].cluster.server | API Server 地址 |
certificate-authority-data | 用于验证 API Server 服务端证书的 CA |
users[].user | 客户端认证凭据,如证书、Token、exec 插件 |
contexts[] | 把集群、用户、命名空间组合成一个使用场景 |
current-context | 默认使用哪个上下文 |
所以 kubeconfig 本身不是证书,但它通常内嵌或引用证书。
kubeconfig 里的 server 可以随便改吗#
不能随便改。
server 字段必须同时满足两个条件:
- 网络上能连到 API Server。
- 这个地址出现在 API Server 服务端证书的 SAN 里,或者被客户端信任。
例如把:
server: https://10.0.0.10:6443改成:
server: https://api.example.com:6443如果 api.example.com 指向同一个 API Server,但 API Server 证书没有包含这个 DNS 名称,仍然会失败。
如果只是为了临时验证,可以使用不安全参数跳过 TLS 校验,但这不应该作为正式方案。
正式方案应该是:
- 在初始化集群时把稳定入口写入 API Server 证书 SAN。
- 或者重新签发包含新地址的 API Server 证书。
- 并确保
kubeconfig的server使用同一个稳定入口。
kubeadm 里几个关键参数#
使用 kubeadm 初始化集群时,和证书/API Server 地址关系最密切的是这些参数。
--control-plane-endpoint#
这个参数指定控制平面的稳定访问入口。
它通常应该是:
- 负载均衡器地址。
- 稳定 DNS 名称。
- 高可用控制平面的虚拟 IP。
示例:
kubeadm init \
--control-plane-endpoint api.example.com:6443它解决的问题是:
客户端和新加入的节点应该通过哪个稳定地址找控制平面?--apiserver-advertise-address#
这个参数指定 API Server 对外声明自己监听在哪个本机地址上。
它通常是当前控制平面节点的内网 IP。
示例:
kubeadm init \
--apiserver-advertise-address 10.0.0.10它更偏节点本地视角,不等同于集群外部访问入口。
--apiserver-cert-extra-sans#
这个参数给 API Server 服务端证书增加额外 SAN。
如果希望通过某个额外 DNS 或 IP 访问 API Server,就应该把它放进来:
kubeadm init \
--control-plane-endpoint api.example.com:6443 \
--apiserver-cert-extra-sans api.example.com \
--apiserver-cert-extra-sans 203.0.113.10它解决的问题是:
TLS 客户端校验证书时,哪些地址可以被认为是这个 API Server?三个地址不要混淆#
Kubernetes 集群里经常同时出现多个 API Server 相关地址:
| 地址类型 | 常见位置 | 含义 |
|---|---|---|
| 本机监听地址 | --apiserver-advertise-address | 控制平面节点本身的 API Server 地址 |
| 稳定控制平面入口 | --control-plane-endpoint | 客户端和节点加入集群时使用的稳定入口 |
| kubeconfig server | clusters[].cluster.server | 当前客户端实际访问的 API Server 地址 |
理想情况下:
kubeconfig server 使用稳定入口;
稳定入口能路由到 API Server;
API Server 证书 SAN 包含这个稳定入口。这样集群后续扩容、迁移、负载均衡调整时,客户端配置才不容易散掉。
kubeadm 生成了哪些配置#
kubeadm init 会生成一批 kubeconfig 文件,通常位于:
/etc/kubernetes/admin.conf
/etc/kubernetes/controller-manager.conf
/etc/kubernetes/scheduler.conf
/etc/kubernetes/kubelet.conf这些文件服务于不同身份:
| 文件 | 主要用途 |
|---|---|
admin.conf | 管理员访问集群 |
controller-manager.conf | controller-manager 访问 API Server |
scheduler.conf | scheduler 访问 API Server |
kubelet.conf | kubelet 访问 API Server |
它们都属于 kubeconfig,只是使用者不同。
证书过期和续期#
kubeadm 支持查看和续期证书。
查看证书过期时间:
kubeadm certs check-expiration手动续期:
kubeadm certs renew all需要注意:
- 续期通常需要在每个控制平面节点上处理。
- 证书续期后,相关静态 Pod 或组件需要重新加载证书。
kubeadm certs renew会以现有证书属性作为权威来源,包括 CN、组织和 SAN。
因此,如果一开始证书 SAN 就缺少某个外部访问域名,单纯续期不一定能自动补上这个域名。
常见排查思路#
1. 先看 kubeconfig server#
kubectl config view --minify重点看:
clusters:
- cluster:
server: https://...确认它到底在连哪个地址。
2. 再看网络是否可达#
curl -vk https://api.example.com:6443/readyz如果完全连不上,先查网络、负载均衡、安全组、防火墙、端口监听。
如果能连上但 TLS 报错,再看证书。
3. 检查 API Server 证书 SAN#
在控制平面节点上:
openssl x509 \
-in /etc/kubernetes/pki/apiserver.crt \
-noout \
-text | grep -A1 "Subject Alternative Name"确认 kubeconfig 里的 server 地址是否出现在 SAN 中。
4. 确认 CA 是否匹配#
如果 kubeconfig 里的 CA 不是签发 API Server 证书的 CA,也会失败。
可以用 openssl 或 kubectl config view --raw 检查内嵌证书内容。
一个稳定的实践模型#
生产或长期使用的集群,建议一开始就确定稳定控制平面入口。
例如:
api.example.com -> LB/VIP -> control-plane nodes:6443初始化时:
kubeadm init \
--control-plane-endpoint api.example.com:6443 \
--apiserver-cert-extra-sans api.example.com然后对外分发的 kubeconfig 使用:
server: https://api.example.com:6443这样三件事对齐:
- DNS 或 VIP 是稳定入口。
- API Server 证书信任这个入口。
- 客户端通过这个入口访问。
常见误解#
误解一:能 ping 通就说明 API Server 可以访问#
不是。
API Server 是 HTTPS 服务,关键是 TCP 6443 和 TLS 校验。
很多负载均衡器或云服务域名本身也不一定响应 ICMP,所以 ping 不通不代表 API Server 不可用。
误解二:改 kubeconfig server 就能切换到新入口#
不一定。
新入口必须在网络上可达,并且 API Server 证书 SAN 覆盖这个地址。
误解三:证书只是加密,和地址没关系#
不对。
服务端证书不仅用于加密,还用于证明当前访问的 DNS 或 IP 属于这个服务。
误解四:证书续期一定会修复 SAN 问题#
不一定。
续期通常沿用现有证书属性。如果要新增 SAN,需要按 kubeadm 证书管理方式重新生成或调整配置后处理。
小结#
可以把这条链路记成一句话:
kubeconfig 选择地址和身份;
API Server 证书证明这个地址可信;
CA 决定客户端是否信任这张证书;
API Server 再根据认证和授权决定请求能做什么。排查 API Server 连接问题时,先分层:
- 地址是否正确。
- 网络是否可达。
- 证书 SAN 是否匹配。
- CA 是否匹配。
- 用户身份是否有权限。
这样就不会把网络问题、TLS 问题和 RBAC 问题混在一起。