1. Kubelet 端口

 
10250
kubelet 主 API(/pods /exec /log /metrics 等,依组件与鉴权设置而定)
一般是 HTTPS + 认证/鉴权(推荐只开放此端口)
 
10255 
kubelet read-only(历史遗留)API
通常是 HTTP 且无认证/鉴权;不少环境会把 readOnlyPort 设为 0 关闭,用来减少暴露面
 
10248 
kubelet 健康检查(healthz)等(依版本/发行版实现)
一般用于本机探活或控制面健康检查;不要对外暴露
 
  • 10250:主 API,一般是 HTTPS + 认证/鉴权

  • 10255:历史遗留的 read-only API,很多环境会选择关闭它(因为它通常是 HTTP 且不做认证/授权)

检查 kubelet 实际监听:

ss -lntp | grep kubelet || true
# 或
netstat -lntp | grep kubelet || true
 

如何确认 10255 是否关闭:

  • 如果你使用 kubelet 配置文件(--config),通常是 readOnlyPort: 0
  • 如果你使用 flag,通常是 --read-only-port=0

2. 为什么需要 TLS bootstrapping

当集群启用 TLS 认证后,节点侧(kubelet / kube-proxy)要用受信 CA 签发的证书去和控制面(kube-apiserver)通信。

节点一多,证书怎么发? TLS bootstrapping 就是把“手工签证书”变成一个可自动化的流程。


3. CSR 类型与自动批准(auto-approve)

按常见实践可以把 kubelet 发起的 CSR 分成 3 类

3.1 kubelet 可能发起的 CSR(逻辑分类)

  • nodeclient

    • kubelet 使用 bootstrap 凭据第一次向 apiserver 请求 client 证书
    • 证书 Subject 常见为:O=system:nodesCN=system:node:<node-name>
  • selfnodeclient

    • kubelet client 证书续期(用于 kubelet → apiserver 的客户端身份)
  • selfnodeserver

    • kubelet serving 证书续期(用于 apiserver / metrics-server / kubectl 等访问 kubelet 10250)

3.2 自动批准为什么需要 RBAC

controller-manager 一般不会对所有 CSR 都自动签发;如果你希望它“只对 kubelet 相关的 CSR 自动批准”,通常就会牵扯到 RBAC 的约束范围。

常见做法是绑定内置的 ClusterRole:

  • system:certificates.k8s.io:certificatesigningrequests:nodeclient
  • system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
  • system:certificates.k8s.io:certificatesigningrequests:selfnodeserver
 
kubectl get clusterrole | grep certificatesigningrequests
 

很多集群里 nodeclient/selfnodeclient 是内置的;selfnodeserver 是否内置取决于版本/发行版。

# 具有创建 nodeclient 类型 CSR 请求的权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:certificates.k8s.io:certificatesigningrequests:nodeclient
rules:
- apiGroups:
  - certificates.k8s.io
  resources:
  - certificatesigningrequests/nodeclient
  verbs:
  - create
---
# 具有创建 selfnodeclient 类型 CSR 请求的权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
rules:
- apiGroups:
  - certificates.k8s.io
  resources:
  - certificatesigningrequests/selfnodeclient
  verbs:
  - create
---
# 具有创建 selfnodeserver 类型 CSR 请求的权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: system:certificates.k8s.io:certificatesigningrequests:selfnodeserver
rules:
- apiGroups:
  - certificates.k8s.io
  resources:
  - certificatesigningrequests/selfnodeserver
  verbs:
  - create

3.3 创建/绑定自动批准规则

4 种场景

  1. 首次 nodeclient(bootstrap)
  2. 首次/后续 selfnodeserver(kubelet serving)
  3. 后续 selfnodeclient(kubelet client renew)
  4. 后续 selfnodeserver(kubelet server renew)
 
# 1) 自动批准 kubelet-bootstrap 用户首次申请 client cert 的 CSR(nodeclient)
kubectl create clusterrolebinding node-client-auto-approve-csr \
--clusterrole=system:certificates.k8s.io:certificatesigningrequests:nodeclient \
--user=kubelet-bootstrap
 
  
 
# 2) 自动批准 system:nodes 组用户更新 kubelet 自身与 apiserver 通讯证书(selfnodeclient)
kubectl create clusterrolebinding node-client-auto-renew-crt \
--clusterrole=system:certificates.k8s.io:certificatesigningrequests:selfnodeclient \
--group=system:nodes
 
 
# 3) 自动批准 system:nodes 组用户更新 kubelet 10250 serving 证书(selfnodeserver)
kubectl create clusterrolebinding node-server-auto-renew-crt \
--clusterrole=system:certificates.k8s.io:certificatesigningrequests:selfnodeserver \
--group=system:nodes
 
  • kubelet-bootstrap 这个用户/组怎么来,取决于你是 kubeadm / 自建 / 发行版;
  • kubeadm 通常使用 bootstrap token 机制;旧方案可能用 token.csv

4. 证书轮换(Certificate Rotation)

证书轮换想解决的场景很朴素:证书快过期时,kubelet 能自己发起 CSR、控制面能签发、kubelet 能 reload

4.1 kubelet 侧常见开关

  • --rotate-certificates:启用 kubelet client 证书轮换(常见于较新版本)
  • RotateKubeletClientCertificate / RotateKubeletServerCertificate:早期可能需要 feature-gates(依版本而定)

4.2 controller-manager 侧

TLS bootstrapping/轮换中签发证书的控制器通常在 kube-controller-manager

  • --experimental-cluster-signing-duration=...:设置签署证书有效期(是否为 experimental 以及参数名可能随版本变化)

5. 开启证书轮换下的“引导过程”

整个过程按时间顺序:

  1. kubelet 读取 bootstrap.kubeconfig(或发行版生成的 bootstrap-kubelet.conf),使用其中的 CA + token 向 apiserver 发起第一次 CSR(nodeclient)。
  2. apiserver 根据 RBAC / 内置控制器策略批准 CSR,并下发 kubelet client 证书(常见落地到 --cert-dir,并写入 --kubeconfig 指定文件)。
  3. kubelet 使用正式身份(O=system:nodesCN=system:node:<NODE_NAME>)与 apiserver 通讯。
  4. kubelet 为自己的 serving 证书(给 10250 用)发起 CSR(常见归类为 selfnodeserver)。
  5. 证书临近过期时,kubelet 自动发起 renew CSR(selfnodeclient + selfnodeserver)。
  6. 新证书签发后,kubelet reload,连接继续(必要时会重建连接)。

6. 组件与 apiserver 通信时用什么身份(kubeconfig)

组件与 apiserver 通信使用什么证书/身份,由它启动参数里的 --kubeconfig 指向的 kubeconfig 决定。

kubeconfig 里常见字段:

  • certificate-authority-data:CA 证书(base64)
  • client-certificate-data / client-certificate:客户端证书
  • client-key-data / client-key:客户端私钥

6.1 kubelet

kubelet 的 kubeconfig(例如 kubelet.conf / kubelet.kubeconfig)很多发行版会自动生成。

查看 kubelet client 证书 Subject:

 
# 常见在 /var/lib/kubelet/pki/
openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -noout -text | sed -n 's/\s\+//g;/Subject:/p'
 

常见能看到:

  • 组(O):system:nodes
  • 用户(CN):system:node:<node-name>

6.2 kube-scheduler / kube-controller-manager

这两个组件通常分别以:

  • system:kube-scheduler

  • system:kube-controller-manager 的身份访问 apiserver。

为什么它们不配置任何证书也能通信?”——多数情况下并不是“没证书”,而是证书通过 kubeconfig / 挂载到静态 Pod 的文件里了(尤其是 kubeadm 部署的控制面)。

排查方法:

 
# 控制面节点上:看看静态 Pod 或 systemd 启动参数
ps -ef | egrep 'kube-scheduler|kube-controller-manager' | grep -v egrep
# 找到 --kubeconfig=... 之后,打开对应 kubeconfig 查看证书字段
 

7. 为什么 kubelet “看起来没绑角色”也能做很多事?

kubectl get clusterrolebinding | grep system:node 看起来“用户/用户组没绑任何角色”,那 kubelet 为什么还能创建 pod?

关键点是:kubelet 的授权不完全依赖常规的 RBAC 绑定

  • apiserver 常见会启用 Node Authorizer
  • 当请求用户属于 system:nodes 且用户名形如 system:node:<node-name> 时,会按“节点身份”授予一组受限权限(最小权限原则)。
  • 如果再启用 NodeRestriction(Admission Plugin),会进一步限制 kubelet 只能修改与自己节点相关的对象。

可以把它理解为:kubelet 作为“节点代理”有一条特殊授权路径(Node Authorizer/NodeRestriction),不完全等价于“给某个用户绑一个 ClusterRole”。


8. 常用操作

8.1 看 CSR 有没有卡住

 
kubectl get csr
kubectl describe csr <name>
  
# 手动批准(需要时)
kubectl certificate approve <name>
 

8.2 检查 kubelet 是否启用了轮换

 
ps -ef | grep kubelet | grep -v grep
# 看是否有 --rotate-certificates / --config=... 以及相关字段