从零搭建 K8s 高可用集群:Ubuntu 3Master 三控合一实战(证书体系全链路加密与双向认证原理解析)
3Master k8s的证书体系的实操
先附上一张k8s双向认证链路表

还需要一张表,需要划分三大根证书以及若干服务端,客户端证书,确保全链路加密通信

***文章中将按照上面两表,进行操作以及讲解***
1,自签证书的生成
步骤1,准备
# cfssl 工具
# 在线安装(推荐)
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssl_1.6.4_linux_amd64 -O /usr/local/bin/cfssl
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssljson_1.6.4_linux_amd64 -O /usr/local/bin/cfssljson
chmod +x /usr/local/bin/cfssl /usr/local/bin/cfssljson
# 验证安装
cfssl version
# 创建证书目录,统一管理
mkdir -p /etc/kubernetes/pki/etcd /etc/kubernetes/pki/front-proxy
cd /etc/kubernetes/pki
# 定义统一公共配置,签发证书时使用
cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": ["signing", "key encipherment", "server auth", "client auth"],
"expiry": "87600h"
},
"etcd": {
"usages": ["signing", "key encipherment", "server auth", "client auth"],
"expiry": "87600h"
}
}
}
}
EOF
步骤2,三个根证书(CA机构)
*注意点:签发只需要在其中一台Master即可,其次同步证书过程中,不要同步私钥(*.key)*
########################### 集群根CA ###########################
cat > ca-csr.json <<EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "kubernetes",
"OU": "k8s-cluster"
}
]
}
EOF
# 签发根CA
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
# 生成文件:ca.csr、ca.crt、ca.key
########################### ETCD CA ###########################
cat > etcd/ca-csr.json <<EOF
{
"CN": "etcd-ca",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "etcd",
"OU": "k8s-cluster"
}
]
}
EOF
# 签发etcd CA
cfssl gencert -initca etcd/ca-csr.json | cfssljson -bare etcd/ca
# 生成文件:etcd/ca.csr、etcd/ca.crt、etcd/ca.key
########################### front proxy CA ###########################
cat > front-proxy/ca-csr.json <<EOF
{
"CN": "front-proxy-ca",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "kubernetes",
"OU": "k8s-cluster"
}
]
}
EOF
# 签发前端代理CA
cfssl gencert -initca front-proxy/ca-csr.json | cfssljson -bare front-proxy/ca
# 生成文件:front-proxy/ca.csr、front-proxy/ca.crt、front-proxy/ca.key
步骤3,签发apiserver,apiserver-etcd-client,apiserver-kubelet-client证书
############### 签发apiserver证书(关键:包含所有IP/域名)###############
cat > apiserver-csr.json <<EOF
{
"CN": "kube-apiserver",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "kubernetes",
"OU": "k8s-cluster"
}
],
"hosts": [
"127.0.0.1",
"10.10.107.223", // master-223 IP
"10.10.107.224", // master-224 IP
"10.10.107.225", // master-225 IP
"10.10.107.222", // VIP(必须加!)
"booiood.cluster.k8s", // VIP域名(必须加!)
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster.local",
"10.96.0.1" // ServiceSubnet网关(你的10.96.0.0/16)
]
}
EOF
# 用根CA签发apiserver证书
cfssl gencert -ca=ca.crt -ca-key=ca.key -config=ca-config.json -profile=kubernetes apiserver-csr.json | cfssljson -bare apiserver
############### 签发apiserver访问etcd客户端证书###############
cat > apiserver-etcd-client-csr.json <<EOF
{
"CN": "kube-apiserver-etcd-client",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "system:masters",
"OU": "k8s-cluster"
}
]
}
EOF
cfssl gencert -ca=etcd/ca.crt -ca-key=etcd/ca.key -config=ca-config.json -profile=etcd apiserver-etcd-client-csr.json | cfssljson -bare apiserver-etcd-client
############### 签发apiserver访问kubelet客户端证书 ###############
cat > apiserver-kubelet-client-csr.json <<EOF
{
"CN": "kube-apiserver-kubelet-client",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "system:masters",
"OU": "k8s-cluster"
}
]
}
EOF
cfssl gencert -ca=ca.crt -ca-key=ca.key -config=ca-config.json -profile=kubernetes apiserver-kubelet-client-csr.json | cfssljson -bare apiserver-kubelet-client
步骤4,签发 etcd 证书
############### etcd server证书 ################
cat > etcd/server-csr.json <<EOF
{
"CN": "etcd-server",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "etcd",
"OU": "k8s-cluster"
}
],
"hosts": [
"127.0.0.1",
"10.10.107.223",
"10.10.107.224",
"10.10.107.225"
]
}
EOF
cfssl gencert -ca=etcd/ca.crt -ca-key=etcd/ca.key -config=ca-config.json -profile=etcd etcd/server-csr.json | cfssljson -bare etcd/server
############### etcd peer证书(节点间通信) ################
cat > etcd/peer-csr.json <<EOF
{
"CN": "etcd-peer",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "etcd",
"OU": "k8s-cluster"
}
],
"hosts": [
"127.0.0.1",
"10.10.107.223",
"10.10.107.224",
"10.10.107.225"
]
}
EOF
cfssl gencert -ca=etcd/ca.crt -ca-key=etcd/ca.key -config=ca-config.json -profile=etcd etcd/peer-csr.json | cfssljson -bare etcd/peer
############### etcd健康检查客户端证书 ################
cat > etcd/healthcheck-client-csr.json <<EOF
{
"CN": "etcd-healthcheck-client",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "etcd",
"OU": "k8s-cluster"
}
]
}
EOF
cfssl gencert -ca=etcd/ca.crt -ca-key=etcd/ca.key -config=ca-config.json -profile=etcd etcd/healthcheck-client-csr.json | cfssljson -bare etcd/healthcheck-client
步骤5,签发kube-proxy前端代理证书
cat > front-proxy-client-csr.json <<EOF
{
"CN": "front-proxy-client",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "kubernetes",
"OU": "k8s-cluster"
}
]
}
EOF
cfssl gencert -ca=front-proxy/ca.crt -ca-key=front-proxy/ca.key -config=ca-config.json -profile=kubernetes front-proxy-client-csr.json | cfssljson -bare front-proxy-client
步骤6,签发admin管理员证书
cat > admin-csr.json <<EOF
{
"CN": "admin",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "system:masters", // 最高权限组,不可改
"OU": "k8s-cluster"
}
]
}
EOF
cfssl gencert -ca=ca.crt -ca-key=ca.key -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
#################### 管理员密钥对 ######################
openssl genrsa -out sa.key 2048
openssl rsa -in sa.key -pubout -out sa.pub
步骤7,签发kubelet证书
##################### 签发kubelet证书 #######################
##################### kubelet需要在所有Node部署,每个kubelet都有自己独立的证书,类似于节点身份证 #######################
cat > kubelet-master-223-csr.json <<EOF
{
"CN": "system:node:master-223", // 固定格式:system:node:<主机名>
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "system:nodes",
"OU": "k8s-cluster"
}
],
"hosts": [
"127.0.0.1",
"10.10.107.223", // 这里是你当前节点的IP
"master-223" // 这里是你在组网篇设置在hosts文件中IP对应的DNS解析名称
]
}
EOF
cfssl gencert -ca=ca.crt -ca-key=ca.key -config=ca-config.json -profile=kubernetes kubelet-master-223-csr.json | cfssljson -bare kubelet-master-223
步骤8,签发kube-controller-manager证书
# 编写CSR文件(集群根CA签发,CN固定为system:kube-controller-manager)
cat > /etc/kubernetes/pki/kube-controller-manager-csr.json <<EOF
{
"CN": "system:kube-controller-manager",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "system:kube-controller-manager",
"OU": "k8s-cluster"
}
]
}
EOF
# 2. 用集群根CA签发证书
cfssl gencert \
-ca=/etc/kubernetes/pki/ca.crt \
-ca-key=/etc/kubernetes/pki/ca.key \
-config=/etc/kubernetes/pki/ca-config.json \
-profile=kubernetes \
/etc/kubernetes/pki/kube-controller-manager-csr.json | cfssljson -bare /etc/kubernetes/pki/kube-controller-manager
步骤9,签发kube-scheduler证书
# 创建CSR文件,存放路径与controller-manager保持一致
cat > /etc/kubernetes/pki/kube-scheduler-csr.json <<EOF
{
"CN": "system:kube-scheduler", // 固定值,apiserver识别scheduler身份的核心
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "system:kube-scheduler", // 固定组,关联RBAC权限,不能改
"OU": "k8s-cluster"
}
]
}
EOF
cfssl gencert \
-ca=/etc/kubernetes/pki/ca.crt \ # 集群根CA公钥
-ca-key=/etc/kubernetes/pki/ca.key \ # 集群根CA私钥(仅223有)
-config=/etc/kubernetes/pki/ca-config.json \ # 复用你的CA配置文件
-profile=kubernetes \ # 复用kubernetes profile即可
/etc/kubernetes/pki/kube-scheduler-csr.json | cfssljson -bare /etc/kubernetes/pki/kube-scheduler
*****kubelet TLS Bootstrapping会自动签发证书以及续期*****
2,证书分发
步骤1,kubelet ↔ kube-apiserver(节点 ↔ 集群入口,最核心、两条方向)
# 定义目标节点变量(方便批量操作)
NODES=("10.10.107.224" "10.10.107.225")
# 批量分发(仅分发公钥/组件证书,不发CA私钥!)
for node in "\${NODES[@]}"; do
# 1. 创建目标目录
ssh root@\${node} "mkdir -p /etc/kubernetes/pki/etcd /etc/kubernetes/pki/front-proxy /var/lib/kubelet/pki"
############## 集群根 CA 证书(ca.crt)—— 全节点分发 ##############
# 2. 分发集群根CA公钥(核心)
scp /etc/kubernetes/pki/ca.crt root@\${node}:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/ca.crt root@\${node}:/etc/kubernetes/pki/
############## kubelet 证书(节点专属) ##############
# 节点签发完成之后将会留在本地,无需处理
############## apiserver 证书(所有控制节点)—— 同步分发 ##############
# 3. 分发apiserver证书(所有控节点都要)
scp /etc/kubernetes/pki/apiserver.crt /etc/kubernetes/pki/apiserver.key root@\${node}:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/apiserver-kubelet-client.crt /etc/kubernetes/pki/apiserver-kubelet-client.key root@\${node}:/etc/kubernetes/pki/
done
步骤2,kube-apiserver ↔ etcd(控制平面 ↔ 集群数据库,核心数据链路)
# 定义目标节点变量(方便批量操作)
NODES=("10.10.107.224" "10.10.107.225")
# 批量分发(仅分发公钥/组件证书,不发CA私钥!)
for node in "\${NODES[@]}"; do
# 1. 创建目标目录
ssh root@\${node} "mkdir -p /etc/kubernetes/pki/etcd /etc/kubernetes/pki/front-proxy /var/lib/kubelet/pki"
# 2. 分发集群根CA公钥(核心)
scp /etc/kubernetes/pki/ca.crt root@\${node}:/etc/kubernetes/pki/
# 3. 分发etcd CA公钥+etcd证书
scp /etc/kubernetes/pki/etcd/ca.crt root@\${node}:/etc/kubernetes/pki/etcd/
scp /etc/kubernetes/pki/etcd/server.crt /etc/kubernetes/pki/etcd/server.key root@\${node}:/etc/kubernetes/pki/etcd/
# 4. 分发apiserver证书(所有控节点都要)
scp /etc/kubernetes/pki/apiserver.crt /etc/kubernetes/pki/apiserver.key root@\${node}:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/apiserver-etcd-client.crt /etc/kubernetes/pki/apiserver-etcd-client.key root@\${node}:/etc/kubernetes/pki/
done
步骤3,etcd 节点间 peer 通信(etcd 集群高可用,多节点必用)
# 定义目标节点变量(方便批量操作)
NODES=("10.10.107.224" "10.10.107.225")
# 批量分发(仅分发公钥/组件证书,不发CA私钥!)
for node in "\${NODES[@]}"; do
# 1. 创建目标目录
ssh root@\${node} "mkdir -p /etc/kubernetes/pki/etcd /etc/kubernetes/pki/front-proxy /var/lib/kubelet/pki"
# 2. 分发etcd CA公钥+etcd证书
scp /etc/kubernetes/pki/etcd/ca.crt root@\${node}:/etc/kubernetes/pki/etcd/
scp /etc/kubernetes/pki/etcd/peer.crt /etc/kubernetes/pki/etcd/peer.key root@\${node}:/etc/kubernetes/pki/etcd/
done
步骤4,kube-controller-manager ↔ kube-apiserver(控制器 ↔ 集群入口)
# 定义目标节点变量(方便批量操作)
NODES=("10.10.107.224" "10.10.107.225")
# 批量分发(仅分发公钥/组件证书,不发CA私钥!)
for node in "\${NODES[@]}"; do
# 1. 创建目标目录
ssh root@\${node} "mkdir -p /etc/kubernetes/pki/etcd /etc/kubernetes/pki/front-proxy /var/lib/kubelet/pki"
# 2. 分发集群根CA公钥(核心)
scp /etc/kubernetes/pki/ca.crt root@\${node}:/etc/kubernetes/pki/
# 3. 分发apiserver证书(所有控节点都要)
scp /etc/kubernetes/pki/apiserver.crt /etc/kubernetes/pki/apiserver.key root@\${node}:/etc/kubernetes/pki/
done
####################### controller-manager 客户端证书 ##########################
################ 可以对controller-manager 客户端证书进行Base64编码 ################
# 1. 编码证书(crt)
CONTROLLER_MANAGER_CRT=$(base64 -w 0 /etc/kubernetes/pki/kube-controller-manager.crt)
# 2. 编码私钥(key)
CONTROLLER_MANAGER_KEY=$(base64 -w 0 /etc/kubernetes/pki/kube-controller-manager.key)
# 3. 编码集群根CA(ca.crt,用于controller-manager验证apiserver)
CA_CRT=$(base64 -w 0 /etc/kubernetes/pki/ca.crt)
# 查看编码后的内容(可选,确认不为空)
echo "证书编码:$CONTROLLER_MANAGER_CRT"
echo "私钥编码:$CONTROLLER_MANAGER_KEY"
echo "CA编码:$CA_CRT"
################ 编码后,内嵌controller-manager 静态 Pod YAML ################
apiVersion: v1
kind: Pod
metadata:
name: kube-controller-manager
namespace: kube-system
spec:
containers:
- name: kube-controller-manager
image: k8s.gcr.io/kube-controller-manager:v1.28.0 # 替换为你的集群版本
command:
- kube-controller-manager
# 内嵌客户端证书(核心参数)
- --client-certificate-data=$(CONTROLLER_MANAGER_CRT) # 替换为实际编码串
- --client-key-data=$(CONTROLLER_MANAGER_KEY) # 替换为实际编码串
# 指定CA证书(验证apiserver用,也可内嵌或指向文件)
- --root-ca-file=/etc/kubernetes/pki/ca.crt # 直接用独立的ca.crt文件(更简单)
# apiserver地址(用你的VIP)
- --kubeconfig=/etc/kubernetes/controller-manager.kubeconfig # 也可直接指定--master=https://10.10.107.222:6443
# 其他必要参数(根据你的集群补充)
- --leader-elect=true
- --cluster-name=kubernetes
- --controllers=*,bootstrapsigner,tokencleaner
- --use-service-account-credentials=true
- --service-account-private-key-file=/etc/kubernetes/pki/sa.key # 之前生成的sa.key
- --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt
- --cluster-signing-key-file=/etc/kubernetes/pki/ca.key
volumeMounts:
- name: k8s-certs
mountPath: /etc/kubernetes/pki
readOnly: true
volumes:
- name: k8s-certs
hostPath:
path: /etc/kubernetes/pki
type: DirectoryOrCreate
hostNetwork: true
priorityClassName: system-node-critical
################ controller-manager Pod Yaml 需要同步到其余的 controller-manager节点 ################
scp /etc/kubernetes/manifests/kube-controller-manager.yaml root@master-224:/etc/kubernetes/manifests/
scp /etc/kubernetes/manifests/kube-controller-manager.yaml root@master-225:/etc/kubernetes/manifests/
步骤5,kube-scheduler ↔ kube-apiserver(调度器 ↔ 集群入口)
# 定义目标节点变量(方便批量操作)
NODES=("10.10.107.224" "10.10.107.225")
# 批量分发(仅分发公钥/组件证书,不发CA私钥!)
for node in "\${NODES[@]}"; do
# 1. 创建目标目录
ssh root@\${node} "mkdir -p /etc/kubernetes/pki/etcd /etc/kubernetes/pki/front-proxy /var/lib/kubelet/pki"
# 2. 分发集群根CA公钥(核心)
scp /etc/kubernetes/pki/ca.crt root@\${node}:/etc/kubernetes/pki/
# 3. 分发apiserver证书(所有控节点都要)
scp /etc/kubernetes/pki/apiserver.crt /etc/kubernetes/pki/apiserver.key root@\${node}:/etc/kubernetes/pki/
done
###################### 要内嵌,先编码 #########################
# 编码证书(crt)
SCHEDULER_CRT=$(base64 -w 0 /etc/kubernetes/pki/kube-scheduler.crt)
# 编码私钥(key)
SCHEDULER_KEY=$(base64 -w 0 /etc/kubernetes/pki/kube-scheduler.key)
# 编码集群根CA(ca.crt,用于scheduler验证apiserver)
CA_CRT=$(base64 -w 0 /etc/kubernetes/pki/ca.crt)
# 查看编码结果(确认不为空)
echo "Scheduler证书编码:$SCHEDULER_CRT"
echo "Scheduler私钥编码:$SCHEDULER_KEY"
###################### 内嵌到 scheduler 静态 Pod YAML #########################
apiVersion: v1
kind: Pod
metadata:
name: kube-scheduler
namespace: kube-system
spec:
containers:
- name: kube-scheduler
image: k8s.gcr.io/kube-scheduler:v1.28.0 # 替换为你的集群版本
command:
- kube-scheduler
# 内嵌客户端证书(核心)
- --client-certificate-data=${SCHEDULER_CRT} # 替换为实际编码串
- --client-key-data=${SCHEDULER_KEY} # 替换为实际编码串
# 指定CA证书(验证apiserver用,直接用文件更简单)
- --root-ca-file=/etc/kubernetes/pki/ca.crt
# apiserver地址(你的VIP)
- --master=https://10.10.107.222:6443
# 开启leader选举(高可用必备)
- --leader-elect=true
hostNetwork: true
priorityClassName: system-node-critical
###################### 同步 scheduler 静态 Pod YAML #########################
# 1. 分发到224节点
scp /etc/kubernetes/manifests/kube-scheduler.yaml root@master-224:/etc/kubernetes/manifests/
# 2. 分发到225节点
scp /etc/kubernetes/manifests/kube-scheduler.yaml root@master-225:/etc/kubernetes/manifests/
步骤6,kube-proxy ↔ kube-apiserver(网络代理 ↔ 集群入口)
# 定义目标节点变量(方便批量操作)
NODES=("10.10.107.224" "10.10.107.225")
# 批量分发(仅分发公钥/组件证书,不发CA私钥!)
for node in "\${NODES[@]}"; do
# 1. 创建目标目录
ssh root@\${node} "mkdir -p /etc/kubernetes/pki/etcd /etc/kubernetes/pki/front-proxy /var/lib/kubelet/pki"
# 2. 分发apiserver证书(所有控节点都要)
scp /etc/kubernetes/pki/apiserver.crt /etc/kubernetes/pki/apiserver.key root@\${node}:/etc/kubernetes/pki/
# 3. 分发前端代理CA公钥+kube-proxy证书
scp /etc/kubernetes/pki/front-proxy/ca.crt root@\${node}:/etc/kubernetes/pki/front-proxy/
scp /etc/kubernetes/pki/front-proxy-client.crt /etc/kubernetes/pki/front-proxy-client.key root@\${node}:/etc/kubernetes/pki/
done
步骤7,kubectl(管理员) ↔ kube-apiserver(客户端 ↔ 集群入口)
# 定义目标节点变量(方便批量操作)
NODES=("10.10.107.224" "10.10.107.225")
# 批量分发(仅分发公钥/组件证书,不发CA私钥!)
for node in "\${NODES[@]}"; do
# 1. 创建目标目录
ssh root@\${node} "mkdir -p /etc/kubernetes/pki/etcd /etc/kubernetes/pki/front-proxy /var/lib/kubelet/pki"
# 2. 分发集群根CA公钥(核心)
scp /etc/kubernetes/pki/ca.crt root@\${node}:/etc/kubernetes/pki/
# 3. 分发apiserver证书(所有控节点都要)
scp /etc/kubernetes/pki/apiserver.crt /etc/kubernetes/pki/apiserver.key root@\${node}:/etc/kubernetes/pki/
# 4. 分发admin证书(可选,方便224/225执行kubectl)
scp /etc/kubernetes/pki/admin.crt /etc/kubernetes/pki/admin.key root@\${node}:/etc/kubernetes/pki/
done
步骤8,Pod 内应用 ↔ kube-apiserver(SA Token 认证,基于CA体系)
# 定义目标节点变量(方便批量操作)
NODES=("10.10.107.224" "10.10.107.225")
# 批量分发(仅分发公钥/组件证书,不发CA私钥!)
for node in "\${NODES[@]}"; do
# 1. 创建目标目录
ssh root@\${node} "mkdir -p /etc/kubernetes/pki/etcd /etc/kubernetes/pki/front-proxy /var/lib/kubelet/pki"
# 2. 分发集群根CA公钥(核心)
scp /etc/kubernetes/pki/ca.crt root@\${node}:/etc/kubernetes/pki/
# 3. 分发SA密钥对(所有控节点都要)
scp /etc/kubernetes/pki/sa.key /etc/kubernetes/pki/sa.pub root@\${node}:/etc/kubernetes/pki/
done
步骤9,3台Master合并证书分发逻辑
# 定义目标节点变量(方便批量操作)
NODES=("10.10.107.224" "10.10.107.225")
# 批量分发(仅分发公钥/组件证书,不发CA私钥!)
for node in "\${NODES[@]}"; do
# 1. 创建目标目录
ssh root@\${node} "mkdir -p /etc/kubernetes/pki/etcd /etc/kubernetes/pki/front-proxy /var/lib/kubelet/pki"
# 2. 分发集群根CA公钥(核心)
scp /etc/kubernetes/pki/ca.crt root@\${node}:/etc/kubernetes/pki/
# 3. 分发etcd CA公钥+etcd证书
scp /etc/kubernetes/pki/etcd/ca.crt root@\${node}:/etc/kubernetes/pki/etcd/
scp /etc/kubernetes/pki/etcd/server.crt /etc/kubernetes/pki/etcd/server.key root@\${node}:/etc/kubernetes/pki/etcd/
scp /etc/kubernetes/pki/etcd/peer.crt /etc/kubernetes/pki/etcd/peer.key root@\${node}:/etc/kubernetes/pki/etcd/
scp /etc/kubernetes/pki/etcd/healthcheck-client.crt /etc/kubernetes/pki/etcd/healthcheck-client.key root@\${node}:/etc/kubernetes/pki/etcd/
# 4. 分发apiserver证书(所有控节点都要)
scp /etc/kubernetes/pki/apiserver.crt /etc/kubernetes/pki/apiserver.key root@\${node}:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/apiserver-etcd-client.crt /etc/kubernetes/pki/apiserver-etcd-client.key root@\${node}:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/apiserver-kubelet-client.crt /etc/kubernetes/pki/apiserver-kubelet-client.key root@\${node}:/etc/kubernetes/pki/
# 5. 分发前端代理CA公钥+kube-proxy证书
scp /etc/kubernetes/pki/front-proxy/ca.crt root@\${node}:/etc/kubernetes/pki/front-proxy/
scp /etc/kubernetes/pki/front-proxy-client.crt /etc/kubernetes/pki/front-proxy-client.key root@\${node}:/etc/kubernetes/pki/
# 6. 分发admin证书(可选,方便224/225执行kubectl)
scp /etc/kubernetes/pki/admin.crt /etc/kubernetes/pki/admin.key root@\${node}:/etc/kubernetes/pki/
# 7. 分发SA密钥对(所有控节点都要)
scp /etc/kubernetes/pki/sa.key /etc/kubernetes/pki/sa.pub root@\${node}:/etc/kubernetes/pki/
done
##################### kubelet证书是所有Node都要独立签发,所以不需要分发 ########################
步骤10,证书验证
# 验证CA公钥存在 224/225
ls /etc/kubernetes/pki/ca.crt /etc/kubernetes/pki/etcd/ca.crt /etc/kubernetes/pki/front-proxy/ca.crt
# 验证apiserver证书包含VIP/域名(所有节点)
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout | grep "DNS\|IP Address"
# 输出:10.10.107.222(VIP)、booiood.cluster.k8s(域名)
# 验证kubelet证书身份(224/225)
# 224节点验证
openssl x509 -in /var/lib/kubelet/pki/kubelet.crt -text -noout | grep "CN="
# 预期:CN=system:node:master-224
# 225节点验证
openssl x509 -in /var/lib/kubelet/pki/kubelet.crt -text -noout | grep "CN="
# 预期:CN=system:node:master-225
步骤11,节点链路验证
########## 验证基础:所有节点 Ready 所有 kube-system Pod running ##########
kubectl get nodes
kubectl get pods -n kube-system
########## kubelet → apiserver(节点注册 / 心跳) ##########
kubectl get nodes
# 看 kubelet 日志
journalctl -u kubelet -f | grep -i 'certificate\|x509\|connect'
# ✅ 节点全 Ready 无 x509 报错、无 connection refused
########## apiserver → kubelet(exec /logs) ##########
# 随便进一个 Pod
kubectl exec -it kube-apiserver-master-223 -n kube-system -- hostname
# 随便看日志
kubectl logs kube-proxy-master-223 -n kube-system
# ✅ 能进 Pod、能看日志 ❌ 失败:error: unable to upgrade connection 就是这条链路坏
########## (apiserver ↔ etcd) ##########
ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
endpoint health
# ✅ 正常:is healthy
# 再看 apiserver 日志:
journalctl -u kube-apiserver -f | grep etcd
# 正常:无 etcd server TLS、x509 报错
########## etcd 集群 peer 通信 ##########
ETCDCTL_API=3 etcdctl \
--endpoints=https://10.10.107.223:2379,https://10.10.107.224:2379,https://10.10.107.225:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
member list
# ✅ 正常:3 个节点都列出
########## controller-manager ↔ apiserver ##########
kubectl get pods -n kube-system | grep controller-manager
# 看日志无证书错误
kubectl logs kube-controller-manager-master-223 -n kube-system | grep -i 'certificate\|auth'
# ✅ 正常:Pod running,无认证错误
########## scheduler ↔ apiserver ##########
kubectl get pods -n kube-system | grep scheduler
kubectl logs kube-scheduler-master-223 -n kube-system | grep -i 'certificate\|auth'
# ✅ 正常:Pod running,无报错
########## kube-proxy ↔ apiserver ##########
kubectl logs kube-proxy-master-223 -n kube-system | grep -i 'front-proxy\|cert'
# ✅ 正常:无 x509: unknown authority
########## Pod 内应用 ↔ apiserver(SA Token) ##########
# 进任意 Pod
kubectl run -it --rm test-pod --image=busybox -- sh
# 在 Pod 里执行:
CA="/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
curl --cacert $CA \
-H "Authorization: Bearer $TOKEN" \
https://10.10.107.222:6443/api
# ✅ 正常:返回 JSON API 列表 ❌ 失败:x509 或 forbidden
########## 简易测试 ##########
kubectl get nodes
kubectl exec -it kube-apiserver-master-223 -n kube-system -- date
etcdctl endpoint health
kubectl run -it --rm test --image=busybox -- curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://10.10.107.222:6443/api
*****下面是理论时间****
3,k8s通信全链路
一、kubelet ↔ kube-apiserver(节点 ↔ 集群入口,最核心、两条方向)
链路1:kubelet → kube-apiserver(节点注册/上报状态/心跳)
- 通信方向:Worker/Master kubelet → Master apiserver
- 步骤1(kubelet 出示):kubelet 发
kubelet.crt(节点证书) - 步骤2(apiserver 验证):apiserver 用 集群根CA公钥 ca.crt 验证
- 步骤3(apiserver 出示):apiserver 发
apiserver.crt(服务端证书) - 步骤4(kubelet 验证):kubelet 用 集群根CA公钥 ca.crt 验证
- 涉及证书:
- kubelet.crt/key(节点本地:/var/lib/kubelet/pki)
- apiserver.crt/key(仅 Master)
- ca.crt(Master + 所有 Worker 都有)
- 关键:双向验证,缺 ca.crt 直接拒绝连接
链路2:kube-apiserver → kubelet(exec/logs/metrics/远程控制)
- 通信方向:Master apiserver → Worker/Master kubelet
- 步骤1(apiserver 出示):apiserver 发
apiserver-kubelet-client.crt(客户端证书) - 步骤2(kubelet 验证):kubelet 用 集群根CA公钥 ca.crt 验证
- 步骤3(kubelet 出示):kubelet 发
kubelet.crt(节点证书) - 步骤4(apiserver 验证):apiserver 用 集群根CA公钥 ca.crt 验证
- 涉及证书:
- apiserver-kubelet-client.crt/key(仅 Master)
- kubelet.crt/key(节点本地)
- ca.crt(Master + 所有 Worker 都有)
- 关键:
kubectl exec/logs完全依赖这条链路
二、kube-apiserver ↔ etcd(控制平面 ↔ 集群数据库,核心数据链路)
- 通信方向:Master apiserver → Master etcd
- 步骤1(apiserver 出示):apiserver 发
apiserver-etcd-client.crt(客户端证书) - 步骤2(etcd 验证):etcd 用 etcd 独立CA公钥 etcd/ca.crt 验证
- 步骤3(etcd 出示):etcd 发
etcd/server.crt(服务端证书) - 步骤4(apiserver 验证):apiserver 用 etcd 独立CA公钥 etcd/ca.crt 验证
- 涉及证书:
- apiserver-etcd-client.crt/key(仅 Master)
- etcd/server.crt/key(仅 Master)
- etcd/ca.crt(仅 Master,apiserver+etcd 共用)
- 关键:etcd 独立CA,和集群根CA解耦,仅 Master 持有
三、etcd 节点间 peer 通信(etcd 集群高可用,多节点必用)
- 通信方向:etcd 节点 ↔ etcd 节点
- 步骤1(节点A出示):发
etcd/peer.crt(peer 双向证书) - 步骤2(节点B验证):用 etcd/ca.crt 验证
- 步骤3(节点B出示):发
etcd/peer.crt - 步骤4(节点A验证):用 etcd/ca.crt 验证
- 涉及证书:etcd/peer.crt/key、etcd/ca.crt(仅 etcd 节点)
- 关键:单节点 etcd 生成但不使用,多节点高可用必须验
四、kube-controller-manager ↔ kube-apiserver(控制器 ↔ 集群入口)
- 通信方向:Master controller-manager → Master apiserver
- 步骤1(controller-manager 出示):内嵌客户端证书(无独立文件)
- 步骤2(apiserver 验证):用 ca.crt 验证
- 步骤3(apiserver 出示):
apiserver.crt - 步骤4(controller-manager 验证):用 ca.crt 验证
- 涉及证书:集群根CA签发客户端证书、ca.crt、apiserver.crt(仅 Master)
- 关键:证书内嵌静态 Pod yaml,无独立 .crt/.key 文件
五、kube-scheduler ↔ kube-apiserver(调度器 ↔ 集群入口)
- 通信方向:Master scheduler → Master apiserver
- 步骤1(scheduler 出示):内嵌客户端证书
- 步骤2(apiserver 验证):用 ca.crt 验证
- 步骤3(apiserver 出示):
apiserver.crt - 步骤4(scheduler 验证):用 ca.crt 验证
- 涉及证书:同 controller-manager(仅 Master,集群根CA签发)
六、kube-proxy ↔ kube-apiserver(网络代理 ↔ 集群入口)
- 通信方向:所有节点 kube-proxy → Master apiserver
- 步骤1(kube-proxy 出示):
front-proxy-client.crt(客户端证书) - 步骤2(apiserver 验证):用 front-proxy/ca.crt(前端代理CA)验证
- 步骤3(apiserver 出示):
apiserver.crt - 步骤4(kube-proxy 验证):用 front-proxy/ca.crt 验证
- 涉及证书:
- front-proxy-client.crt/key(Master + 所有 Worker)
- front-proxy/ca.crt(Master + 所有 Worker)
- apiserver.crt(仅 Master)
- 关键:前端代理CA专属链路,ca.crt 必须同步所有 Worker
七、kubectl(管理员) ↔ kube-apiserver(客户端 ↔ 集群入口)
- 通信方向:kubectl(Master/Worker)→ Master apiserver
- 步骤1(kubectl 出示):
admin.crt(管理员客户端证书) - 步骤2(apiserver 验证):用 ca.crt 验证
- 步骤3(apiserver 出示):
apiserver.crt - 步骤4(kubectl 验证):用 ca.crt 验证
- 涉及证书:
- admin.crt/key(仅 Master,可拷贝到 Worker)
- ca.crt(Master + Worker)
- apiserver.crt(仅 Master)
- 关键:admin 证书属集群根CA,拥有最高权限
八、Pod 内应用 ↔ kube-apiserver(SA Token 认证,基于CA体系)
- 通信方向:Pod 内应用 → Master apiserver
- 非标准 X509 双向认证,基于 CA 信任:
- Pod 自动挂载
ca.crt+ SA Token - 应用用 Token 向 apiserver 认证(Token 由
sa.key签发) - 应用用
ca.crt验证 apiserver.crt
- Pod 自动挂载
- 涉及证书:
- sa.key/sa.pub(仅 Master)
- ca.crt(全节点,自动挂载到 Pod)
- 关键:依赖集群根CA信任链,无独立客户端证书
4,k8s加密通信总结
- 所有核心链路都是双向认证,通信两端必须互相出示证书、互相验证
- 集群根CA(ca.crt) 覆盖:apiserver、kubelet、controller-manager、scheduler、kubectl、Pod
- etcd 独立CA(etcd/ca.crt) 仅覆盖:apiserver↔etcd、etcd peer 通信
- 前端代理CA(front-proxy/ca.crt) 仅覆盖:kube-proxy↔apiserver
- CA 公钥必须在通信两端,CA 私钥永远只在 Master
- apiserver.crt、kubelet.crt、admin.crt 同源签发 → 统一用 ca.crt 验证
更多推荐


所有评论(0)