K8s-kubelet认证授权流程
Kubelet 认证授权通信流程
目标
这篇文档只回答一个核心问题:kubelet 如何验证和授权对 kubelet API 的访问请求?
重点放在 kubelet 的认证模块、授权模块以及与 API Server 的交互流程。
一句话摘要
kubelet 通过 webhook 认证和授权,将客户端请求转发给 API Server 进行验证,支持匿名访问、证书认证和 bootstrap token 认证等多种方式。
1. 流程总览
从通信视角看,这条链路包含三个层次:
- **认证层 (Authentication)**:验证客户端身份。
- **授权层 (Authorization)**:验证客户端是否有权限执行操作。
- **准入层 (Admission)**:对请求进行额外检查和修改(仅部分操作)。
架构总览图
flowchart TB
subgraph 客户端["请求来源"]
direction LR
API[kube-apiserver<br/>proxy/attach/exec]
KUBECTL[kubectl<br/>直接访问 kubelet]
PROBE[探针/监控<br/>healthz/metrics]
ANON[匿名请求<br/>未认证]
end
subgraph 认证["认证层 (Authentication)"]
direction TB
ANONYMOUS[Anonymous<br/>匿名认证]
X509[X509 Cert<br/>证书认证]
BOOTSTRAP[Bootstrap Token<br/>启动引导]
WEBHOOK[Webhook<br/>委托 API Server]
end
subgraph 授权["授权层 (Authorization)"]
direction TB
ALWAYS_ALLOW[AlwaysAllow<br/>允许所有]
WEBHOOK_AUTHZ[Webhook<br/>委托 API Server]
end
subgraph Kubelet["Kubelet API"]
direction TB
HANDLERS[请求处理器]
PODS[/pods 端点]
EXEC[/exec 端点]
METRICS[/metrics 端点]
end
API --> WEBHOOK
KUBECTL --> X509
KUBECTL --> WEBHOOK
PROBE --> ANONYMOUS
ANON --> ANONYMOUS
WEBHOOK --> WEBHOOK_AUTHZ
X509 --> WEBHOOK_AUTHZ
BOOTSTRAP --> WEBHOOK_AUTHZ
ANONYMOUS --> ALWAYS_ALLOW
WEBHOOK_AUTHZ --> HANDLERS
ALWAYS_ALLOW --> HANDLERS
HANDLERS --> PODS
HANDLERS --> EXEC
HANDLERS --> METRICS
认证授权流程图
flowchart TD
subgraph 请求["HTTP 请求"]
A1[客户端发起请求] --> A2{检查认证配置}
end
subgraph 认证["认证流程"]
A2 --> B1{authentication.anonymous.enabled?}
B1 -->|true| B2{有认证信息?}
B2 -->|无| B3[匿名用户]
B2 -->|有| B4{认证方式}
B1 -->|false| B4
B4 -->|X509 证书| B5[证书认证]
B4 -->|Bearer Token| B6{Token 类型}
B6 -->|Bootstrap Token| B7[Bootstrap 认证]
B6 -->|Service Account| B8[Webhook 认证]
B5 --> B9[提取用户信息]
B7 --> B9
B8 --> B9
B3 --> B9
end
subgraph 授权["授权流程"]
B9 --> C1{authorization.mode?}
C1 -->|AlwaysAllow| C2[允许所有请求]
C1 -->|Webhook| C3[构建 SubjectAccessReview]
C3 --> C4[POST API Server /apis/authorization.k8s.io/v1/subjectaccessreviews]
C4 --> C5{API Server 返回}
C5 -->|allowed: true| C6[授权通过]
C5 -->|allowed: false| C7[拒绝请求]
end
subgraph 处理["请求处理"]
C2 --> D1[执行请求]
C6 --> D1
C7 --> D2[403 Forbidden]
D1 --> D3[返回响应]
end
这张图想表达什么
- kubelet 支持多种认证方式,可以委托给 API Server。
- 授权默认使用 Webhook 模式,需要 API Server 批准。
- 匿名访问只适用于特定端点(如 /healthz)。
2. 分阶段通信流程
阶段一:认证 (Authentication)
这个阶段的本质是:验证请求者的身份。
步骤 1.1:检查认证配置
kubelet 启动时根据配置初始化认证器:
--anonymous-auth=true/false:是否允许匿名访问--client-ca-file:客户端 CA 证书文件--authentication-token-webhook:使用 webhook 认证
通信方向:kubelet 启动配置
步骤 1.2:提取认证信息
从请求中提取认证信息:
- TLS 证书(X509)
- Bearer Token(Header: Authorization: Bearer xxx)
通信方向:HTTP 请求解析
步骤 1.3:匿名认证
如果允许匿名且请求没有认证信息,则识别为匿名用户 system:anonymous。
通信方向:认证模块内部处理
步骤 1.4:证书认证
如果配置了 --client-ca-file,kubelet 会验证客户端证书,提取 Common Name (CN) 作为用户名。
通信方向:kubelet → 证书验证
步骤 1.5:Webhook 认证
如果启用 webhook 认证,kubelet 将 Token 发送给 API Server 进行验证。
通信方向:kubelet → API Server(POST /apis/authentication.k8s.io/v1/tokenreviews)
步骤 1.6:构建用户信息
认证成功后,构建用户信息(用户名、组、UID 等)。
通信方向:认证模块内部构建
阶段二:授权 (Authorization)
这个阶段的本质是:验证用户是否有权限执行请求的操作。
步骤 2.1:检查授权配置
kubelet 启动时根据配置初始化授权器:
--authorization-mode=AlwaysAllow/Webhook:授权模式
通信方向:kubelet 启动配置
步骤 2.2:AlwaysAllow 模式
如果配置为 AlwaysAllow,所有请求都被授权。
通信方向:授权模块内部处理
步骤 2.3:Webhook 授权
如果配置为 Webhook,kubelet 构建 SubjectAccessReview 对象发送给 API Server。
通信方向:kubelet → API Server(POST /apis/authorization.k8s.io/v1/subjectaccessreviews)
步骤 2.4:API Server 授权检查
API Server 检查用户是否有权限执行该操作:
- 检查 RBAC 规则
- 检查 Node 授权规则(针对 kubelet 节点)
通信方向:API Server 内部 RBAC/Node 授权器
步骤 2.5:返回授权结果
API Server 返回 allowed: true/false。
通信方向:API Server → kubelet
阶段三:请求处理
这个阶段的本质是:执行授权通过的请求。
步骤 3.1:路由请求
kubelet 根据请求路径路由到对应的处理器。
通信方向:HTTP 路由
步骤 3.2:执行处理逻辑
处理器执行具体逻辑,如获取 Pod 列表、执行命令等。
通信方向:kubelet 内部处理
步骤 3.3:返回响应
返回处理结果给客户端。
通信方向:kubelet → 客户端
3. 详细流程图
3.1 kubelet API 端点与权限要求
flowchart TB
subgraph 只读端点["只读端点 (无需特殊权限)"]
direction LR
H1[/healthz]
H2[/healthz/syncloop]
H3[/healthz/log]
end
subgraph 认证端点["需要认证"]
direction TB
P1[/pods - list pods]
P2[/spec - node spec]
P3[/stats - resource stats]
P4[/metrics - prometheus metrics]
end
subgraph 敏感端点["需要认证+授权"]
direction TB
S1[/exec - container exec]
S2[/portForward - port forward]
S3[/attach - container attach]
S4[/logs - container logs]
S5[/runningpods - running pods]
S6[/configz - kubelet config]
end
subgraph 权限要求["所需 RBAC 权限"]
direction TB
R1[nodes/proxy]
R2[nodes/stats]
R3[pods/exec]
R4[pods/portForward]
R5[pods/log]
end
P1 --> R1
P3 --> R2
S1 --> R3
S2 --> R4
S4 --> R5
3.2 kubectl exec 完整流程图
sequenceDiagram
autonumber
participant K as kubectl
participant API as kube-apiserver
participant AUTHZ as Authorization
participant KL as Kubelet
participant CRI as Container Runtime
K->>API: POST /api/v1/namespaces/default/pods/pod-1/exec
Note over API: API Server 认证+授权
API->>AUTHZ: 检查 pods/exec 权限
AUTHZ-->>API: allowed
API->>KL: POST /exec/<pod-uid>/<container>?command=...
Note over KL: Kubelet 认证
KL->>KL: 提取 TLS 客户端证书
KL->>KL: 验证证书 (CN=system:node:node-1)
Note over KL: Kubelet 授权 (Webhook)
KL->>API: POST /apis/authorization.k8s.io/v1/subjectaccessreviews
Note over KL,API: SubjectAccessReview{<br/> user: system:node:node-1,<br/> verb: create,<br/> resource: pods/exec<br/>}
API->>AUTHZ: Node 授权器检查
Note over AUTHZ: 检查节点是否有权限访问该 Pod
AUTHZ-->>API: allowed: true
API-->>KL: allowed: true
KL->>CRI: ExecSync/Exec in container
CRI-->>KL: exec stream
KL-->>API: WebSocket/SPDY stream
API-->>K: exec stream
K->>K: 显示终端输出
3.3 证书认证流程图
flowchart TD
subgraph 客户端["客户端"]
C1[生成 CSR]
C2[获取签名证书]
C3[使用证书访问 kubelet]
end
subgraph CA["证书签发"]
CA1[kubelet 启动<br/>生成私钥和 CSR]
CA2[发送 CSR 到 API Server]
CA3[Controller Manager 签名]
CA4[获取签名证书]
end
subgraph 认证["证书认证"]
A1[客户端发送请求<br/>带 TLS 证书]
A2[kubelet 验证证书<br/>使用 client-ca-file]
A3[提取 CN 作为用户名<br/>system:node:node-1]
A4[提取 O 作为组<br/>system:nodes]
end
C1 --> C2 --> C3
CA1 --> CA2 --> CA3 --> CA4
C3 --> A1 --> A2 --> A3 --> A4
4. 关键配置
4.1 kubelet 认证配置
1 | # kubelet 配置 |
4.2 RBAC 规则示例
1 | # API Server 访问 kubelet 的权限 |
4.3 端点权限映射
| 端点 | 所需权限 | 说明 |
|---|---|---|
/healthz |
无 | 健康检查 |
/pods |
nodes/proxy | Pod 列表 |
/stats |
nodes/stats | 资源统计 |
/metrics |
nodes/metrics | Prometheus 指标 |
/exec/* |
pods/exec | 容器执行 |
/portForward/* |
pods/portForward | 端口转发 |
/attach/* |
pods/exec | 容器附加 |
/logs/* |
pods/log | 容器日志 |
5. 详细时序图
5.1 Webhook 认证时序图
sequenceDiagram
autonumber
participant CLIENT as 客户端
participant KL as Kubelet
participant AUTH as Authenticator
participant CACHE as 认证缓存
participant API as kube-apiserver
CLIENT->>KL: GET /pods (Authorization: Bearer <token>)
KL->>AUTH: AuthenticateRequest(req)
AUTH->>AUTH: 提取 Bearer Token
AUTH->>CACHE: 检查缓存
alt 缓存命中
CACHE-->>AUTH: 返回缓存的用户信息
else 缓存未命中
AUTH->>API: POST /apis/authentication.k8s.io/v1/tokenreviews
Note over AUTH,API: TokenReview{<br/> spec.token: <token><br/>}
API->>API: 验证 Token
API-->>AUTH: TokenReview.status{<br/> authenticated: true,<br/> user: {username, groups, uid}<br/>}
AUTH->>CACHE: 缓存认证结果
end
AUTH-->>KL: user.Info
KL->>KL: 继续授权流程
5.2 Webhook 授权时序图
sequenceDiagram
autonumber
participant KL as Kubelet
participant AUTHZ as Authorizer
participant CACHE as 授权缓存
participant API as kube-apiserver
Note over KL: 认证完成,用户为 system:node:node-1
KL->>AUTHZ: AuthorizeRequest(req, user)
AUTHZ->>AUTHZ: 提取请求属性
Note over AUTHZ: verb=get, resource=pods, name=pod-1
AUTHZ->>CACHE: 检查缓存
alt 缓存命中
CACHE-->>AUTHZ: 返回缓存结果
else 缓存未命中
AUTHZ->>API: POST /apis/authorization.k8s.io/v1/subjectaccessreviews
Note over AUTHZ,API: SubjectAccessReview{<br/> spec: {<br/> user: system:node:node-1,<br/> groups: [system:nodes, system:authenticated],<br/> resourceAttributes: {<br/> verb: get,<br/> resource: pods,<br/> name: pod-1,<br/> namespace: default<br/> }<br/> }<br/>}
API->>API: Node Authorizer 检查
Note over API: 检查 Pod 是否调度到此节点
API-->>AUTHZ: SubjectAccessReview.status{<br/> allowed: true<br/>}
AUTHZ->>CACHE: 缓存授权结果
end
AUTHZ-->>KL: authorized=true
KL->>KL: 执行请求
5.3 匿名访问时序图
sequenceDiagram
autonumber
participant PROBE as 健康检查器
participant KL as Kubelet
participant AUTH as Authenticator
participant AUTHZ as Authorizer
PROBE->>KL: GET /healthz (无认证信息)
KL->>AUTH: AuthenticateRequest(req)
AUTH->>AUTH: 检查请求头 - 无 Authorization
alt anonymous.enabled=true
AUTH->>AUTH: 识别为匿名用户
Note over AUTH: user=system:anonymous<br/>groups=[system:unauthenticated]
AUTH-->>KL: user.Info{system:anonymous}
else anonymous.enabled=false
AUTH-->>KL: 认证失败
KL-->>PROBE: 401 Unauthorized
end
KL->>AUTHZ: AuthorizeRequest(req, anonymous)
alt authorization.mode=AlwaysAllow
AUTHZ-->>KL: allowed
else authorization.mode=Webhook
Note over AUTHZ: 检查匿名用户权限
alt /healthz 端点
AUTHZ-->>KL: allowed (默认允许)
else 其他端点
AUTHZ-->>KL: denied
KL-->>PROBE: 403 Forbidden
end
end
KL->>KL: 执行健康检查
KL-->>PROBE: 200 OK
6. 故障排查指南
6.1 常见问题与诊断方法
问题 1:kubectl exec 失败 (403 Forbidden)
症状:
1 | Error from server: error dialing backend: x509: certificate signed by unknown authority |
或
1 | error: unable to upgrade connection: Unauthorized |
排查流程图:
flowchart TD
A[kubectl exec 失败] --> B{检查错误类型}
B -->|401 Unauthorized| C[认证问题]
C --> C1[检查 API Server token]
C --> C2[检查 kubelet client-ca-file]
B -->|403 Forbidden| D[授权问题]
D --> D1[检查 RBAC 规则]
D1 --> D2[检查 nodes/proxy 权限]
D1 --> D3[检查 pods/exec 权限]
B -->|x509 错误| E[证书问题]
E --> E1[检查 CA 证书配置]
E --> E2[检查证书有效期]
E --> E3[检查证书链]
A --> F{检查 kubelet 配置}
F --> F1[authentication.anonymous.enabled]
F --> F2[authorization.mode]
F --> F3[client-ca-file 路径]
诊断命令:
1 | # 检查 RBAC 权限 |
问题 2:metrics 端点无法访问
症状:Prometheus 无法抓取 kubelet metrics
排查流程图:
flowchart TD
A[metrics 不可访问] --> B{检查匿名访问}
B --> B1[anonymous.enabled?]
B1 -->|false| B2[需要认证]
B2 --> B3[配置 ServiceAccount token]
B1 -->|true| C{检查授权}
C --> C1[authorization.mode]
C1 -->|Webhook| C2[需要 nodes/metrics 权限]
C1 -->|AlwaysAllow| C3[应该可以访问]
A --> D{检查网络}
D --> D1[防火墙规则]
D --> D2[kubelet 端口]
D --> D3[HTTPS 配置]
A --> E{检查证书}
E --> E1[client-ca-file]
E --> E2[tls-cert-file]
E --> E3[tls-private-key-file]
诊断命令:
1 | # 测试 metrics 端点 |
问题 3:节点状态无法更新
症状:kubelet 无法更新 Node status
排查流程图:
flowchart TD
A[Node status 更新失败] --> B{检查 kubelet 证书}
B --> B1[证书是否存在]
B1 -->|否| B2[检查 bootstrap 过程]
B1 -->|是| B3[检查证书有效期]
A --> C{检查 RBAC}
C --> C1[检查 system:nodes 组]
C --> C2[检查 Node 授权器]
A --> D{检查 API Server 连接}
D --> D1[网络连通性]
D --> D2[kubeconfig 配置]
D --> D3[API Server 可用性]
诊断命令:
1 | # 检查 kubelet 证书 |
6.2 关键日志关键词
| 场景 | 日志关键词 | 含义 |
|---|---|---|
| 认证失败 | Authentication failed |
认证失败 |
| 授权失败 | Forbidden |
授权拒绝 |
| 证书错误 | x509 |
证书相关错误 |
| Token 验证 | TokenReview |
Token 验证请求 |
| 授权检查 | SubjectAccessReview |
授权检查请求 |
| 匿名访问 | system:anonymous |
匿名用户访问 |
6.3 配置参数参考
| 参数 | 默认值 | 说明 |
|---|---|---|
--anonymous-auth |
true | 允许匿名访问 |
--client-ca-file |
无 | 客户端 CA 证书 |
--authentication-token-webhook |
false | 启用 webhook 认证 |
--authentication-token-webhook-cache-ttl |
2m | 认证缓存时间 |
--authorization-mode |
AlwaysAllow | 授权模式 |
--authorization-webhook-cache-authorized-ttl |
5m | 授权缓存时间 |
6.4 一键诊断命令
1 | # kubelet 认证授权诊断脚本 |
7. 安全最佳实践
7.1 生产环境推荐配置
1 | # kubelet 安全配置 |
7.2 RBAC 最小权限原则
1 | # 监控系统需要的最小权限 |
8. 版本差异说明
1.27 → 1.28 变化
| 变化点 | 说明 |
|---|---|
| TLS Bootstrap 改进 | 更安全的证书轮换机制 |
| 认证缓存优化 | 更高效的缓存实现 |
1.28 → 1.29 变化
| 变化点 | 说明 |
|---|---|
| 匿名访问限制 | 默认更严格的匿名访问控制 |
| 授权日志增强 | 更详细的授权日志 |
9. 代码入口(精简版)
如果读者想从流程跳回实现,可从下面几个入口开始:
- 认证模块:
pkg/kubelet/server/auth.go - 授权模块:
pkg/kubelet/server/auth.go - Webhook 认证器:
staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/webhook.go - Kubelet Server:
pkg/kubelet/server/server.go - 认证接口定义:
staging/src/k8s.io/apiserver/pkg/authentication/authenticator/interfaces.go - 授权接口定义:
staging/src/k8s.io/apiserver/pkg/authorization/authorizer/interfaces.go
10. 面试题与详细解答
问题 1:kubelet 的认证方式有哪些?生产环境应该如何配置?
回答要点:
kubelet 支持的认证方式:
| 认证方式 | 配置参数 | 适用场景 |
|---|---|---|
| 匿名认证 | --anonymous-auth=true |
健康检查端点 |
| X509 证书 | --client-ca-file |
API Server 访问 |
| Bootstrap Token | --bootstrap-token-auth |
节点初始化 |
| Webhook 认证 | --authentication-token-webhook=true |
统一身份认证 |
认证流程优先级:
1 | 1. 检查是否有 TLS 客户端证书 → X509 认证 |
生产环境推荐配置:
1 | # kubelet 配置 |
安全最佳实践:
- 禁用匿名访问:
anonymous.enabled: false - 使用 Webhook 认证:与 API Server 统一身份管理
- 启用证书轮换:
rotateCertificates: true - 禁用只读端口:
readOnlyPort: 0
问题 2:kubectl exec 是如何通过 API Server 访问 kubelet 的?认证授权流程是什么?
回答要点:
完整流程:
1 | kubectl → API Server (认证+授权) → kubelet (认证+授权) → CRI → 容器 |
详细步骤:
kubectl 发起请求:
1
kubectl exec -it pod-name -- /bin/sh
API Server 认证:
- 验证 kubectl 的 token/certificate
- 确认用户身份
API Server 授权:
- 检查
pods/exec权限 - RBAC 规则匹配
- 检查
API Server 转发请求:
- 构建 kubelet 请求 URL
- 使用 kubelet 客户端证书
kubelet 认证:
- 验证 API Server 的客户端证书
- 提取用户信息(CN=system:node:node-1)
kubelet 授权(Webhook):
- 构建 SubjectAccessReview
- 发送到 API Server
- Node Authorizer 检查
kubelet 执行命令:
- 调用 CRI Exec
- 返回流式输出
认证授权时序图:
sequenceDiagram
participant K as kubectl
participant API as kube-apiserver
participant KL as Kubelet
K->>API: POST /api/v1/namespaces/default/pods/pod-1/exec
Note over API: API Server 认证<br/>验证用户身份
Note over API: API Server 授权<br/>检查 pods/exec 权限
API->>KL: POST /exec/<pod-uid>/<container>
Note over KL: Kubelet 认证<br/>验证 API Server 证书
KL->>API: POST /apis/authorization.k8s.io/v1/subjectaccessreviews
Note over KL,API: SubjectAccessReview{<br/> user: system:node:node-1,<br/> verb: create,<br/> resource: pods/exec<br/>}
API-->>KL: allowed: true
Note over KL: 授权通过
KL->>KL: 调用 CRI Exec
KL-->>API: WebSocket/SPDY stream
API-->>K: exec stream
Node Authorizer 检查逻辑:
1 | // Node Authorizer 只允许节点访问自己节点上的 Pod |
问题 3:kubelet 的 Node Authorizer 是如何工作的?为什么需要 Node Authorizer?
回答要点:
Node Authorizer 设计目的:
- 最小权限原则:节点只能访问自己节点上的资源
- 隔离性:防止一个节点访问另一个节点的数据
- 安全性:即使节点被攻破,影响范围有限
Node Authorizer 检查规则:
| 资源 | 允许的操作 | 限制条件 |
|---|---|---|
| Pod | 读取、状态更新 | 只能访问调度到本节点的 Pod |
| Secret | 读取 | 只能访问本节点 Pod 使用的 Secret |
| ConfigMap | 读取 | 只能访问本节点 Pod 使用的 ConfigMap |
| Node | 状态更新 | 只能更新自己的 Node 对象 |
| PV/PVC | 读取 | 只能访问本节点 Pod 使用的卷 |
授权检查流程:
1 | // 1. 检查用户身份 |
为什么需要 Node Authorizer:
RBAC 的局限性:
- RBAC 只能基于角色授权
- 无法表达”节点只能访问自己的资源”
安全场景:
1
2
3
4
5
6
7
8
9
10假设没有 Node Authorizer:
1. 攻击者攻破 node-1
2. 获取 node-1 的 kubelet 证书
3. 可以访问所有节点的 Secret/Pod 信息
4. 集群完全暴露
有 Node Authorizer:
1. 攻击者攻破 node-1
2. 只能访问 node-1 上的 Pod 和相关资源
3. 影响范围受限
配置示例:
1 | # kube-apiserver 配置 |
问题 4:如何为监控系统配置访问 kubelet metrics 的权限?
回答要点:
方案一:使用 ServiceAccount + RBAC
1 | # 1. 创建 ServiceAccount |
方案二:配置 kubelet 允许匿名访问 metrics
1 | # kubelet 配置(不推荐生产环境) |
Prometheus 抓取配置:
1 | # Prometheus 配置 |
访问 kubelet metrics 的方式:
| 方式 | URL | 权限要求 |
|---|---|---|
| 通过 API Server 代理 | /api/v1/nodes/{node}/proxy/metrics |
nodes/proxy |
| 直接访问 kubelet | https://{node}:10250/metrics |
nodes/metrics |
安全建议:
- 使用 ServiceAccount:避免使用匿名访问
- 最小权限:只授予必要的 metrics 权限
- 网络隔离:限制监控系统的网络访问
- 证书管理:定期轮换 ServiceAccount token
问题 5:kubelet 的 TLS Bootstrap 是什么?如何工作?
回答要点:
TLS Bootstrap 概念:
TLS Bootstrap 允许 kubelet 在没有预分配证书的情况下启动,通过向 API Server 发送 CSR(Certificate Signing Request)来获取证书。
工作流程:
1 | 1. kubelet 启动,使用 bootstrap token 认证 |
配置步骤:
创建 Bootstrap Token:
1
2
3
4
5
6
7
8# 创建 token secret
kubectl create secret generic bootstrap-token-abcdef \
--namespace kube-system \
--type bootstrap.kubernetes.io/token \
--from-literal=token-id=abcdef \
--from-literal=token-secret=0123456789abcdef \
--from-literal=usage-bootstrap-authentication=true \
--from-literal=usage-bootstrap-signing=true配置 kubelet:
1
2
3
4
5# kubelet 配置
bootstrapKubeconfig: /etc/kubernetes/bootstrap-kubelet.conf
certDir: /var/lib/kubelet/pki
rotateCertificates: true # 自动轮换证书
serverTLSBootstrap: true # 启用服务端证书 bootstrap配置 RBAC:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28# 允许 kubelet 创建 CSR
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubeadm:node-autoapprove-csr
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:certificates.k8s.io:certificatesigningrequests:nodeclient
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:bootstrappers
# 允许自动批准 CSR
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubeadm:node-autoapprove-certificate
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:nodes
证书轮换:
1 | 证书有效期:1 年 |
安全考虑:
Bootstrap Token 安全:
- Token 有时效性
- 使用后应销毁
CSR 审批:
- 可以配置自动审批
- 也可以手动审批(更安全)
证书撤销:
- 目前 Kubernetes 不支持证书撤销
- 依赖证书短期有效
问题 6:如何排查 kubectl exec/logs 失败的问题?常见错误有哪些?
回答要点:
常见错误及原因:
| 错误信息 | 原因 | 解决方法 |
|---|---|---|
error dialing backend |
kubelet 不可达 | 检查 kubelet 状态 |
x509: certificate signed by unknown authority |
证书问题 | 检查 CA 证书 |
Unauthorized |
认证失败 | 检查 token/证书 |
Forbidden |
授权失败 | 检查 RBAC 规则 |
connection refused |
kubelet 端口未监听 | 检查 kubelet 配置 |
排查流程:
flowchart TD
A[kubectl exec 失败] --> B{检查错误类型}
B -->|401 Unauthorized| C[认证问题]
C --> C1[检查 API Server token]
C --> C2[检查 kubelet client-ca-file]
B -->|403 Forbidden| D[授权问题]
D --> D1[检查 RBAC 规则]
D --> D2[检查 nodes/proxy 权限]
D --> D3[检查 pods/exec 权限]
B -->|x509 错误| E[证书问题]
E --> E1[检查 CA 证书配置]
E --> E2[检查证书有效期]
E --> E3[检查证书链]
B -->|connection refused| F[连接问题]
F --> F1[检查 kubelet 是否运行]
F --> F2[检查防火墙规则]
F --> F3[检查端口配置]
详细排查步骤:
步骤 1:检查 API Server 日志
1 | # 查看 API Server 日志 |
步骤 2:检查 kubelet 状态
1 | # 检查 kubelet 服务 |
步骤 3:检查证书配置
1 | # 检查 kubelet 证书 |
步骤 4:检查 RBAC 权限
1 | # 检查用户权限 |
步骤 5:网络连通性测试
1 | # 从 API Server 测试 kubelet 连接 |
一键诊断脚本:
1 |
|
问题 7:kubelet 的认证缓存机制是如何工作的?如何调优缓存参数?
回答要点:
缓存机制目的:
- 减少 API Server 压力:避免每次请求都调用 API Server
- 降低延迟:缓存命中时直接返回结果
- 提高可用性:API Server 短暂不可用时仍可工作
认证缓存:
1 | authentication: |
缓存工作原理:
1 | 请求到达 → 检查缓存 → 命中 → 返回缓存结果 |
授权缓存:
1 | authorization: |
为什么授权失败缓存时间短:
- 权限变化:用户可能刚获得权限
- 安全考虑:减少未授权窗口
- 重试需求:允许快速重试
缓存 Key 计算:
1 | // 认证缓存 Key |
调优建议:
| 场景 | 认证缓存 | 授权成功缓存 | 授权失败缓存 |
|---|---|---|---|
| 高安全要求 | 30s | 1m | 10s |
| 正常生产环境 | 2m | 5m | 30s |
| 高性能要求 | 5m | 10m | 1m |
监控缓存效率:
1 | # 查看 kubelet 指标 |
缓存失效场景:
- TTL 到期:自动失效
- kubelet 重启:缓存清空
- 配置变更:重新加载
最佳实践:
- 根据安全需求调整 TTL:高安全环境使用短 TTL
- 监控缓存命中率:评估缓存效果
- 平衡性能和安全:找到合适的平衡点

