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 信任:
    1. Pod 自动挂载 ca.crt + SA Token
    2. 应用用 Token 向 apiserver 认证(Token 由 sa.key 签发)
    3. 应用用 ca.crt 验证 apiserver.crt
  • 涉及证书:
    • sa.key/sa.pub(仅 Master)
    • ca.crt(全节点,自动挂载到 Pod)
  • 关键:依赖集群根CA信任链,无独立客户端证书

4,k8s加密通信总结

  1. 所有核心链路都是双向认证,通信两端必须互相出示证书、互相验证
  2. 集群根CA(ca.crt) 覆盖:apiserver、kubelet、controller-manager、scheduler、kubectl、Pod
  3. etcd 独立CA(etcd/ca.crt) 仅覆盖:apiserver↔etcd、etcd peer 通信
  4. 前端代理CA(front-proxy/ca.crt) 仅覆盖:kube-proxy↔apiserver
  5. CA 公钥必须在通信两端,CA 私钥永远只在 Master
  6. apiserver.crt、kubelet.crt、admin.crt 同源签发 → 统一用 ca.crt 验证
Logo

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

更多推荐