从 0 到 1 理解 Kubernetes:一次“破坏式”学习实践(三)
前言
本章节主要完成两件事情:
- 为 Kubernetes 各个组件生成并配置 kubeconfig 文件,用于 基于 TLS 证书的身份认证与安全通信
- 为 apiserver 生成并配置数据加密密钥,用于 对 etcd 中的敏感数据进行静态加密(Encryption at Rest)
一、生成 kubeconfig 配置文件
1. kubeconfig 基本说明
在 Kubernetes 中,几乎所有组件都是“客户端”:
- kubelet
- kube-proxy
- controller-manager
- scheduler
- admin
它们都会以 客户端身份 访问 apiserver,而不是通过匿名 HTTP。
因此,每个组件都需要一个 kubeconfig 文件,用于:
- 指定 apiserver 地址
- 指定信任的 CA(ca.crt)
- 指定自身的身份(客户端证书 + 私钥)
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:
- 哪些资源需要被加密(如 Secrets)
- 使用哪种加密算法
- 使用哪个密钥
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。
更多推荐



所有评论(0)