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:nodes、CN=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:nodeclientsystem:certificates.k8s.io:certificatesigningrequests:selfnodeclientsystem: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:
- create3.3 创建/绑定自动批准规则
4 种场景
- 首次 nodeclient(bootstrap)
- 首次/后续 selfnodeserver(kubelet serving)
- 后续 selfnodeclient(kubelet client renew)
- 后续 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. 开启证书轮换下的“引导过程”
整个过程按时间顺序:
- kubelet 读取
bootstrap.kubeconfig(或发行版生成的bootstrap-kubelet.conf),使用其中的 CA + token 向 apiserver 发起第一次 CSR(nodeclient)。 - apiserver 根据 RBAC / 内置控制器策略批准 CSR,并下发 kubelet client 证书(常见落地到
--cert-dir,并写入--kubeconfig指定文件)。 - kubelet 使用正式身份(
O=system:nodes、CN=system:node:<NODE_NAME>)与 apiserver 通讯。 - kubelet 为自己的 serving 证书(给 10250 用)发起 CSR(常见归类为 selfnodeserver)。
- 证书临近过期时,kubelet 自动发起 renew CSR(selfnodeclient + selfnodeserver)。
- 新证书签发后,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=... 以及相关字段