k8s sa公钥怎么来的

### **ServiceAccount Token 与 CA 证书的完整关系解析**

#### **1. 核心逻辑**
Kubernetes 的 ServiceAccount (SA) Token 本质是 **由集群 CA 体系签名的 JWT**,其信任链如下:
```
ServiceAccount Token 有效性 → 由 sa.key/sa.pub 签名 → sa.pub 必须被集群 CA 证书信任
```
- **签发者**:`kube-controller-manager`(传统 Token)或 `kube-apiserver`(新版 Token)
- **验证者**:`kube-apiserver` 使用集群 CA 证书校验 Token 的合法性

---

### **2. 手动生成 ServiceAccount Token(依赖 CA)**
#### **步骤 1:检查当前集群的 SA 密钥对**
```bash
# 查看集群使用的 SA 密钥
ls /etc/kubernetes/pki/sa.*
# 必须存在:
#   /etc/kubernetes/pki/sa.key (私钥,用于签名 Token)
#   /etc/kubernetes/pki/sa.pub (公钥,用于验证 Token)
```

#### **步骤 2:用集群 CA 体系生成新 SA 密钥(如需)**
```bash
# 生成新的 SA 密钥对(由当前 CA 派生)
sudo kubeadm init phase certs sa --cert-dir /etc/kubernetes/pki

# 生成后检查公钥是否被 CA 信任
openssl x509 -in /etc/kubernetes/pki/ca.crt -pubkey | diff - /etc/kubernetes/pki/sa.pub
# 无输出表示 sa.pub 是 CA 的派生密钥
```

#### **步骤 3:创建 ServiceAccount 并生成 Token**
```bash
# 创建 ServiceAccount
kubectl create serviceaccount my-sa

# 获取自动生成的 Token(新版 Kubernetes)
kubectl create token my-sa --duration=8760h

# 传统方式(需手动绑定 Secret)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: my-sa-token
  annotations:
    kubernetes.io/service-account.name: my-sa
type: kubernetes.io/service-account-token
EOF
```

---

### **3. 验证当前 SA Token 是否依赖 CA**
#### **方法 1:检查 Token 签名密钥**
```bash
# 获取任意 SA Token
TOKEN=$(kubectl get secret $(kubectl get sa my-sa -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 -d)

# 解码 Token 头部查看签名算法
echo $TOKEN | cut -d '.' -f 1 | base64 -d
# 输出应包含:
#   "alg": "RS256"  # 表示使用 RSA 签名(依赖 sa.key/sa.pub)
```

#### **方法 2:强制用 CA 验证 Token**
```bash
# 使用集群 CA 验证 Token
curl -k --cacert /etc/kubernetes/pki/ca.crt \
  -H "Authorization: Bearer $TOKEN" \
  https://<API_SERVER_IP>:6443/api/v1/namespaces/default/pods
# 返回 200 表示 Token 被 CA 信任
```

#### **方法 3:检查组件启动参数**
```bash
# 查看 kube-apiserver 的 SA 配置
ps aux | grep kube-apiserver | grep service-account
# 关键参数:
#   --service-account-key-file=/etc/kubernetes/pki/sa.pub  # 必须与 CA 匹配
#   --service-account-signing-key-file=/etc/kubernetes/pki/sa.key

# 查看 kube-controller-manager 的 SA 配置
ps aux | grep kube-controller-manager | grep service-account
# 关键参数:
#   --service-account-private-key-file=/etc/kubernetes/pki/sa.key
```

---

### **4. SA 与 CA 的生成逻辑**
| 组件                | 依赖关系                                                                 |
|---------------------|--------------------------------------------------------------------------|
| **kube-apiserver**  | 用 `sa.pub` 验证 Token,`sa.pub` 必须与 `ca.crt` 同源                     |
| **controller-manager** | 用 `sa.key` 签发传统 Token,`sa.key` 必须与 `ca.key` 同属一个密钥体系     |
| **Pod/Token**       | 携带的 Token 必须能被 `sa.pub` 验证,且 `sa.pub` 需被集群 CA 信任          |

#### **关键配置文件**
```bash
# CA 证书和密钥
/etc/kubernetes/pki/ca.crt
/etc/kubernetes/pki/ca.key

# ServiceAccount 密钥对(由 CA 派生)
/etc/kubernetes/pki/sa.pub
/etc/kubernetes/pki/sa.key
```

---

### **5. 故障排查**
#### **场景:更新 CA 后 SA Token 失效**
```bash
# 重新生成 SA 密钥对
sudo kubeadm init phase certs sa --cert-dir /etc/kubernetes/pki

# 重启组件
sudo systemctl restart kubelet
```

#### **场景:SA Token 无法通过验证**
```bash
# 检查 sa.pub 是否与 CA 匹配
openssl x509 -in /etc/kubernetes/pki/ca.crt -pubkey | diff - /etc/kubernetes/pki/sa.pub

# 如果不匹配,重新生成 SA 密钥
sudo mv /etc/kubernetes/pki/sa.{key,pub} /tmp/
sudo kubeadm init phase certs sa --cert-dir /etc/kubernetes/pki
```

---

### **6. 总结**
| 操作                          | 命令/检查点                                                                 |
|-------------------------------|----------------------------------------------------------------------------|
| **验证 SA 依赖 CA**           | `openssl x509 -in ca.crt -pubkey` 对比 `sa.pub`                            |
| **手动生成 SA Token**         | `kubectl create token <sa-name>`                                           |
| **修复 CA 更新导致的 SA 问题**| `kubeadm init phase certs sa` + 重启组件                                   |
| **检查 Token 有效性**         | `curl --cacert ca.crt -H "Authorization: Bearer $TOKEN" $APISERVER/api`    |

**核心结论**:  
ServiceAccount Token **必须** 由集群 CA 证书体系(`sa.key/sa.pub`)签名,任何 CA 变更都需同步更新 SA 密钥!

  

posted on 2025-07-05 21:13  吃草的青蛙  阅读(17)  评论(0)    收藏  举报

导航