前言

本章节主要完成两件事情:

  1. 为 Kubernetes 各个组件生成并配置 kubeconfig 文件,用于 基于 TLS 证书的身份认证与安全通信
  2. 为 apiserver 生成并配置数据加密密钥,用于 对 etcd 中的敏感数据进行静态加密(Encryption at Rest)

一、生成 kubeconfig 配置文件

1. kubeconfig 基本说明

在 Kubernetes 中,几乎所有组件都是“客户端”:

  • kubelet
  • kube-proxy
  • controller-manager
  • scheduler
  • admin

它们都会以 客户端身份 访问 apiserver,而不是通过匿名 HTTP。
因此,每个组件都需要一个 kubeconfig 文件,用于:

  1. 指定 apiserver 地址
  2. 指定信任的 CA(ca.crt)
  3. 指定自身的身份(客户端证书 + 私钥)

kubeconfig 本质上是一个 连接 apiserver 的配置文件,包含三类信息:

类别 作用
cluster 你要连哪个 apiserver?它的地址是什么?你信任哪个 CA?
user 你是谁?用哪个证书和私钥证明身份?
context 把 cluster 和 user 绑定起来,形成“我用这个身份访问这个集群”

下面所有的命令,本质上都在构建这三块信息。

均在 jumpbox 上操作。

2. The kubelet Kubernetes Configuration File

for host in node-0 node-1; do
  kubectl config set-cluster kubernetes-the-hard-way \
    --certificate-authority=ca.crt \
    --embed-certs=true \
    --server=https://server.kubernetes.local:6443 \
    --kubeconfig=${host}.kubeconfig

  kubectl config set-credentials system:node:${host} \
    --client-certificate=${host}.crt \
    --client-key=${host}.key \
    --embed-certs=true \
    --kubeconfig=${host}.kubeconfig

  kubectl config set-context default \
    --cluster=kubernetes-the-hard-way \
    --user=system:node:${host} \
    --kubeconfig=${host}.kubeconfig

  kubectl config use-context default \
    --kubeconfig=${host}.kubeconfig
done

生成

node-0.kubeconfig
node-1.kubeconfig

set-cluster 定义:

参数 含义
kubernetes-the-hard-way 这是一个“逻辑集群名”,只是 kubeconfig 内部引用用
–server apiserver 地址
–certificate-authority 用哪个 CA 来验证 apiserver 的证书
–embed-certs 把证书内容直接写进 kubeconfig,而不是只写路径

也就是说,这一步是在告诉 kubelet:

“你要连接的是这个 apiserver,而且你要信任这个 CA 签发的证书。”

set-credentials 定义:

kubelet 以什么身份访问 apiserver?

也就是:

  • 我是谁?→ system:node:node-0
  • 我的身份证 → node-0.crt
  • 我的身份证私钥 → node-0.key

set-context 定义:

我是谁(set-credentials) + 我要访问哪个集群(set-cluster) 绑定在一起。

这是 kubeconfig 的真正入口。

后续 kubeconfig 生成逻辑是完全一样。
只是每个组件都有独立的证书、独立的 kubeconfig、独立的 RBAC 权限。
并且 每个组件都拥有最小必要权限(Least Privilege) (Kubernetes 安全模型的核心原则之一)

3. The kube-proxy Kubernetes Configuration File

  kubectl config set-cluster kubernetes-the-hard-way \
    --certificate-authority=ca.crt \
    --embed-certs=true \
    --server=https://server.kubernetes.local:6443 \
    --kubeconfig=kube-proxy.kubeconfig

  kubectl config set-credentials system:kube-proxy \
    --client-certificate=kube-proxy.crt \
    --client-key=kube-proxy.key \
    --embed-certs=true \
    --kubeconfig=kube-proxy.kubeconfig

  kubectl config set-context default \
    --cluster=kubernetes-the-hard-way \
    --user=system:kube-proxy \
    --kubeconfig=kube-proxy.kubeconfig

  kubectl config use-context default \
    --kubeconfig=kube-proxy.kubeconfig

生成

kube-proxy.kubeconfig

kube-proxy 负责把访问 Service 的流量,转发到真正的 Pod 上。

4. The kube-controller-manager Kubernetes Configuration File

  kubectl config set-cluster kubernetes-the-hard-way \
    --certificate-authority=ca.crt \
    --embed-certs=true \
    --server=https://server.kubernetes.local:6443 \
    --kubeconfig=kube-controller-manager.kubeconfig

  kubectl config set-credentials system:kube-controller-manager \
    --client-certificate=kube-controller-manager.crt \
    --client-key=kube-controller-manager.key \
    --embed-certs=true \
    --kubeconfig=kube-controller-manager.kubeconfig

  kubectl config set-context default \
    --cluster=kubernetes-the-hard-way \
    --user=system:kube-controller-manager \
    --kubeconfig=kube-controller-manager.kubeconfig

  kubectl config use-context default \
    --kubeconfig=kube-controller-manager.kubeconfig

生成

kube-controller-manager.kubeconfig

5. The kube-scheduler Kubernetes Configuration File

  kubectl config set-cluster kubernetes-the-hard-way \
    --certificate-authority=ca.crt \
    --embed-certs=true \
    --server=https://server.kubernetes.local:6443 \
    --kubeconfig=kube-scheduler.kubeconfig

  kubectl config set-credentials system:kube-scheduler \
    --client-certificate=kube-scheduler.crt \
    --client-key=kube-scheduler.key \
    --embed-certs=true \
    --kubeconfig=kube-scheduler.kubeconfig

  kubectl config set-context default \
    --cluster=kubernetes-the-hard-way \
    --user=system:kube-scheduler \
    --kubeconfig=kube-scheduler.kubeconfig

  kubectl config use-context default \
    --kubeconfig=kube-scheduler.kubeconfig

生成

kube-scheduler.kubeconfig

6. The admin Kubernetes Configuration File

  kubectl config set-cluster kubernetes-the-hard-way \
    --certificate-authority=ca.crt \
    --embed-certs=true \
    --server=https://server.kubernetes.local:6443 \
    --kubeconfig=admin.kubeconfig
# 官方示例使用 127.0.0.1:6443 作为 apiserver 地址,
# 这样 kubeconfig 只在本机有效,远程 jumpbox 使用同一 CA 访问会失败。
# 这里改成 server.kubernetes.local,让远程节点也能通过 ca.crt 验证访问(不改的话后面有个验证不过)

  kubectl config set-credentials admin \
    --client-certificate=admin.crt \
    --client-key=admin.key \
    --embed-certs=true \
    --kubeconfig=admin.kubeconfig

  kubectl config set-context default \
    --cluster=kubernetes-the-hard-way \
    --user=admin \
    --kubeconfig=admin.kubeconfig

  kubectl config use-context default \
    --kubeconfig=admin.kubeconfig

生成

admin.kubeconfig

7. 分发 kubeconfig 文件

拷贝文件到 node 节点

for host in node-0 node-1; do
  ssh root@$host "mkdir -p /var/lib/{kube-proxy,kubelet}"

  scp kube-proxy.kubeconfig \
    root@$host:/var/lib/kube-proxy/kubeconfig \

  scp ${host}.kubeconfig \
    root@$host:/var/lib/kubelet/kubeconfig
done

拷贝文件到 server 节点

scp admin.kubeconfig \
  kube-controller-manager.kubeconfig \
  kube-scheduler.kubeconfig \
  root@server:~/

为什么要拷贝到这些路径?

/var/lib/kubelet/kubeconfig
/var/lib/kube-proxy/kubeconfig

因为:

  • kubelet 启动时会指定 --kubeconfig=/var/lib/kubelet/kubeconfig
  • kube-proxy 也是同理

这些文件会被组件在启动时加载,用于 TLS 双向认证。

生成数据加密配置和密钥

目前为止,解决了:

组件 ↔ apiserver 的通信安全

但 Kubernetes 还有一个非常重要的安全点:

apiserver 存进 etcd 的数据本身是否安全?

默认情况下:

  • Secret
  • Token
  • ServiceAccount
  • Docker Registry 密码

都会以 明文 存储在 etcd 中。

如果 etcd 泄露 = 整个集群沦陷
SO,以下解决这个问题。

以下均在jumpbox上操作:

加密密钥

export ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64)
# 检查
# echo $ENCRYPTION_KEY

这一步,用于加密 etcd 中敏感数据的对称密钥

它不是 TLS 相关的证书,而是:

  • 专门用于“静态数据加密”(Encryption at Rest)
  • 只在 apiserver 端使用

加密配置文件

envsubst < configs/encryption-config.yaml \
  > encryption-config.yaml

这个配置文件告诉 apiserver:

  1. 哪些资源需要被加密(如 Secrets)
  2. 使用哪种加密算法
  3. 使用哪个密钥

apiserver 启动时会加载这个文件,并对写入 etcd 的数据进行加密。

scp encryption-config.yaml root@server:~/

结语

简单来说:

  • kubeconfig 是一个客户端访问 Kubernetes API 的身份配置文件,解决了3个问题:
    • 我要访问谁?(集群 URL)
    • 我是谁?(我的证书、我的私钥)
    • 我要以什么身份 + 访问哪个集群?(上面两个匹对)
  • encryption-config.yaml 就是 apiserver 在写入 etcd 之前,会对指定的资源字段进行加密,然后把密文写进 etcd。()

不配置 encryption-config.yaml 的话,kubernetes 一样可运行(默认不会加密),只是 apiserver 以明文写入/读取 etcd。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐