向 Kubernetes API 服务器证书添加名称

作者:API传播员 · 2025-12-11 · 阅读时间:5分钟

在本文中,我们将详细介绍如何向 Kubernetes API 服务器的 TLS 证书添加名称(特别是 Subject Alternative Name,简称 SAN)。更新证书以包含未包含的名称是一个常见需求,尤其是在以下场景中:在控制平面前添加负载均衡器,或使用新的 URL 或主机名访问 API 服务器。这些情况通常发生在集群启动之后。

本文假设您的 Kubernetes 集群是通过 kubeadm 引导的,并且使用了由 kubeadm 创建的默认证书颁发机构(CA)。此外,本文的操作基于非高可用性(单控制平面节点)配置。


背景

Kubernetes API 服务器通过数字证书加密流量并验证连接。如果您尝试使用命令行工具(如 kubectl连接到 API 服务器,而所用的主机名或 IP 地址未包含在证书的 SAN 列表中,则会收到错误提示,表明证书对指定的主机名或 IP 地址无效。为了解决这一问题,您需要更新证书,将所有可能用于访问 API 服务器的主机名或 IP 地址添加到 SAN 列表中。


更新 API 服务器的证书

由于集群是通过 kubeadm 引导的,因此可以使用 kubeadm 更新 API 服务器的证书,并在 SAN 列表中添加额外的名称。

提取 kubeadm 配置文件

如果您在引导集群时使用了配置文件,可以直接使用该文件作为起点。如果没有配置文件(例如通过快速执行 kubeadm init 创建的集群),可以从集群中提取 kubeadm 配置文件。kubeadm 会将配置存储在 kube-system 命名空间中的 ConfigMap 中,名为 kubeadm-config

运行以下命令将配置提取到外部文件:

kubectl -n kube-system get configmap kubeadm-config -o jsonpath="{.data.ClusterConfiguration}" > kubeadm.yaml

此命令会生成一个名为 kubeadm.[yaml](https://www.explinks.com/wiki/ymal/) 的文件,文件内容可能如下所示(具体值可能因集群而异):

apiServer:
  certSANs: []

添加 SAN

apiServer 部分下,添加一个 certSANs 列表。如果列表已存在,只需在其中添加新的条目。例如:

apiServer:
  certSANs:
    - "172.29.50.162"
    - "k8s.domain.com"
    - "other-k8s.domain.net"

除了自定义的 SAN,还包括一些默认的 SAN,如本地主机名、Kubernetes 服务的默认名称和 IP 地址,以及节点的主 IP 地址。

更新证书

完成配置文件的修改后,可以使用以下步骤更新证书:

  1. 移动现有的 API 服务器证书和密钥。如果 kubeadm 检测到指定位置已存在证书和密钥,将不会重新生成。

  2. 使用以下命令生成新证书:

    kubeadm init phase certs apiserver --config kubeadm.yaml

    此命令会根据配置文件生成新的证书和密钥,并自动将 certSANs 列表中的名称添加到证书中。

  3. 重启 API 服务器以加载新证书。可以通过以下命令终止运行中的 API 服务器容器:


   docker ps | grep kube-apiserver | grep -v pause   ```

   如果使用的是 containerd,命令略有不同:

```bash

   crictl pods | grep kube-apiserver | cut -d' ' -f1   ```

   Kubernetes 的 Kubelet 服务会自动重启容器,新证书将立即生效。

---

## 验证更改

验证证书更新是否成功,可以通过以下方法:

1. **使用 kubectl 测试连接**

   编辑 Kubeconfig 文件,将集群的 server 行修改为新添加的 IP 地址或主机名之一,然后运行 kubectl 测试连接。如果无法连接,可以从此处开始排查问题。

2. **查看证书的 SAN 列表**

   在控制平面节点上运行以下命令,解码证书并查看 SAN 列表:

   ```bash
   openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text

在输出中查找 X509v3 Subject Alternative Name 行,其中列出了证书包含的所有 DNS 名称和 IP 地址。如果未看到新添加的名称或 IP 地址,可能是以下原因导致的:

  • 忘记删除旧的证书和密钥。
  • 在运行 kubeadm init phase certs 命令时未指定配置文件。

更新集群内的配置

完成证书更新后,最后一步是更新集群中存储的 kubeadm ConfigMap。这一步很重要,以确保未来使用 kubeadm 升级集群时,新信息能够正确应用。

运行以下命令上传配置文件:

kubeadm init phase upload-config kubeadm --config kubeadm.yaml

验证配置是否成功更新:

kubectl -n kube-system get configmap kubeadm-config -o yaml

特殊场景:添加 127.0.0.1 到 SAN

在某些情况下,例如通过 SSH 隧道访问控制平面端点时,需要将 127.0.0.1 添加到 SAN 列表中。通过在证书中包含 127.0.0.1,可以在本地通过端口 6443(或其他端口)连接到控制平面节点。


通过以上步骤,您可以成功向 Kubernetes API 服务器的证书中添加名称,从而支持更多的访问方式。如果在操作过程中遇到问题,请仔细检查每一步的配置和命令是否正确。

原文链接: https://blog.scottlowe.org/2019/07/30/adding-a-name-to-kubernetes-api-server-certificate/