Kubernetes(K8s)学习笔记(第十二期):集群健康与安全------探针 + 认证授权
本笔记为 Kubernetes 系列第十二期,聚焦集群应用健康检查与访问安全控制。涵盖:Health Check 三种探针(liveness/readiness/startup)及其探测方法(httpGet/exec/tcpSocket)、认证管理(X509 证书用户创建)、授权管理(RBAC 的 Role/ClusterRole 与绑定)、服务账户(ServiceAccount 与 Token 管理)。所有命令和 YAML 示例均已经过整理和注释。全文约 5200 字 ,包含 20 个 YAML 示例 、55+ 命令示例 和 12 张对比表格,是 Kubernetes 集群健康与安全管理的完整指南。
更多kubernetes系列知识:kubernetes从入门到进阶
我的主页:AOwhisky,这里有更多运维系统性知识整理和其他有趣内容,欢迎与我一起探讨学习~
--- Compiled and Authored by Whisky --- July 2 nd, 2026
目录
- 引子:集群的"体检"与"门禁"
- Health Check(健康检查)
- 认证管理(Authentication)
- 授权管理(Authorization ------ RBAC)
- 服务账户(ServiceAccount)
- 总结与知识点一览表
引子:集群的"体检"与"门禁"
在 Kubernetes 集群的日常运维中,有两个问题始终绕不开:
第一,应用是否健康? ------ 就像人需要定期体检一样,集群中的 Pod 也需要持续"体检"。如果 Pod 里的应用已经"病倒"(死锁、崩溃、配置错误),Kubernetes 需要及时发现并采取措施(重启、摘除流量)。没有健康检查的集群,就像没有体温计和血压仪的医院------病人已经高烧昏迷,护士却还在按部就班地换药。
第二,谁可以访问集群? ------ 就像大楼需要门禁系统一样,集群也需要一套完善的"门禁"机制。谁来敲门(认证)、能进哪扇门(授权)、以什么身份进入(服务账户),都需要清晰定义。没有认证授权的集群,就像没有保安和门禁卡的大楼------任何人都可以随意进出,拿走任何东西。
本期就来回答这两个问题:
- 健康检查:告诉你"应用还活着吗?准备好接客了吗?"
- 认证授权:告诉你"你是谁?你能做什么?"
一句话总结本期 :探针是集群的"体检医生",RBAC 是集群的"门禁系统"------两者共同保障集群的稳定运行 与安全访问。学完本期,你将能亲手为应用配置健康检查,并为不同用户分配合适的权限。
一、Health Check(健康检查)
1.1 为什么需要健康检查?
在生产环境中,应用可能会因为各种原因变得 unhealthy:临时连接断开、配置错误、应用死锁等。
如果不对 Pod 进行健康检查,会出现以下问题:
- 流量打到"死"Pod:Pod 虽然还在运行(进程未退出),但已经无法正常处理请求。没有健康检查,Service 仍会将流量转发给它。
- 坏 Pod 永远不重启:进程没有退出,Kubernetes 不会自动重启,应用会一直处于"假死"状态。
- 滚动更新失败:新版本 Pod 启动失败,但旧版本已经被替换,导致服务中断。
kubelet 使用 Probes(探针) 周期性地监控容器中应用是否为 healthy 状态,并根据探测结果决定是否重启容器或将 Pod 从 Service 的 Endpoints 中移除。
1.2 三种探针类型
| 探针类型 | 作用 | 失败后的行为 |
|---|---|---|
| livenessProbe(存活探针) | 检测容器是否正在运行 | 重启容器(Pod 重新创建) |
| readinessProbe(就绪探针) | 检测容器是否准备好接收流量 | 从 Service Endpoints 中移除 Pod IP |
| startupProbe(启动探针) | 检测容器是否已完成初始化 | 失败则重启,成功后才启动其他探针 |
三种探针的关系:
text
Pod 启动
↓
startupProbe(如果配置)------ 成功 → 启动 livenessProbe 和 readinessProbe
↓
readinessProbe(持续检测)------ 失败 → 从 Service 摘除流量
↓
livenessProbe(持续检测)------ 失败 → 重启 Pod
为什么需要 startupProbe?
一些应用(如 Java 应用、大型微服务)启动时间较长,可能需要 30 秒甚至更久才能完全初始化。如果直接用 livenessProbe 检测,启动期间可能因为超时被反复重启,造成"启动 → 检测失败 → 重启 → 再启动"的恶性循环。startupProbe 给了应用一个"宽限期",在启动完成之前,livenessProbe 和 readinessProbe 不会执行,避免了误判。
1.3 四种探测方法
| 方法 | 说明 | 成功条件 |
|---|---|---|
| httpGet | 对容器 IP 的指定端口和路径执行 HTTP GET 请求 | 响应状态码 200-399 |
| exec | 在容器内执行指定命令 | 命令退出码为 0 |
| tcpSocket | 对容器 IP 的指定端口执行 TCP 连接检查 | 端口可连接 |
| grpc | 执行 gRPC 健康检查(RPC 调用) | 响应状态为 SERVING |
本笔记重点介绍前三种,grpc 方法暂不展开。
1.4 探针通用参数
| 参数 | 默认值 | 说明 |
|---|---|---|
initialDelaySeconds |
0(必填) | 容器启动后多久开始探测 |
periodSeconds |
10 | 探测频率(秒) |
timeoutSeconds |
1 | 探测超时时间(秒) |
successThreshold |
1 | 连续成功多少次后判定为成功 |
failureThreshold |
3 | 连续失败多少次后判定为失败 |
1.5 实验:无探针的 Pod
问题演示:没有探针时,Pod 中应用已经"坏掉",但 Pod 状态仍然是 Running。
bash
# 创建普通 Pod
root@master30:~# kubectl run web --image=httpd
# 查看 Pod
root@master30:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
web 1/1 Running 0 10s
# 删除主页文件,应用实际上已无法正常提供服务
root@master30:~# kubectl exec web -- rm -f htdocs/index.html
# 访问测试(返回 404/无内容)
root@master30:~# curl 10.224.73.16
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
...
# 但 Pod 状态仍然是 Running------Kubernetes 不知道应用已经出问题了
root@master30:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
web 1/1 Running 0 2m
1.6 实验:livenessProbe(存活探针)
httpGet 方式 :检测 /index.html 是否存在,不存在则重启 Pod。
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- image: httpd
name: httpd
livenessProbe:
httpGet:
path: /index.html
port: 80
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
timeoutSeconds: 10
bash
root@master30:~# kubectl apply -f deploy-httpGet-liveness.yaml
root@master30:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-85c6ff748f-qwszz 1/1 Running 0 1m
# 删除主页文件
root@master30:~# kubectl exec web-85c6ff748f-qwszz -- rm htdocs/index.html
# 观察 Pod------RESTARTS 变为 1(Pod 被重启)
root@master30:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-85c6ff748f-qwszz 1/1 Running 1 3m
# 访问恢复正常(主页文件在重启后恢复)
root@master30:~# curl 10.98.146.216
<html><body><h1>It works!</h1></body></html>
执行探针(exec)方式:在容器内执行命令检测。
yaml
livenessProbe:
exec:
command:
- cat
- /usr/local/apache2/htdocs/index.html
initialDelaySeconds: 5
periodSeconds: 5
常见问题 :
exec探针要求容器内存在指定的命令。如果命令不存在,探针会失败,Pod 会被反复重启。
1.7 实验:readinessProbe(就绪探针)
作用:当就绪探针失败时,Pod 不会被重启,而是从 Service 的 Endpoints 中移除,不再接收流量。
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- image: httpd
name: httpd
readinessProbe:
httpGet:
path: /index.html
port: 80
initialDelaySeconds: 5
periodSeconds: 5
bash
root@master30:~# kubectl apply -f deploy-readiness.yaml
root@master30:~# kubectl expose deployment web --port=80 --target-port=80
# 查看 Endpoints(3 个 Pod IP)
root@master30:~# kubectl get endpoints web
NAME ENDPOINTS AGE
web 10.224.73.15:80,10.224.73.34:80,10.224.73.35:80 1m
# 删除其中一个 Pod 的主页文件
root@master30:~# kubectl exec web-9479dc55c-6bpg7 -- rm -f htdocs/index.html
# 再次查看 Endpoints------该 Pod 被移出
root@master30:~# kubectl get endpoints web
NAME ENDPOINTS AGE
web 10.224.73.15:80,10.224.73.34:80 2m
# 查看 Pod 状态------READY 变为 0/1,但 RESTARTS 没有增加
root@master30:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-9479dc55c-6bpg7 0/1 Running 0 8m
关键理解:
readinessProbe失败 → Pod 从 Service Endpoints 移除 → 不再接收流量livenessProbe失败 → Pod 重启 → 尝试自我修复- 两者配合使用,可实现"自动摘除故障节点"+"自动尝试恢复"的良性循环。
1.8 实验:startupProbe(启动探针)
适用场景:当应用启动时间较长时,使用 startupProbe 为应用提供"宽限期"。
yaml
apiVersion: apps/v1
kind: Pod
metadata:
name: slow-start-app
spec:
containers:
- name: app
image: myapp:latest
startupProbe:
httpGet:
path: /health
port: 8080
failureThreshold: 30 # 最多允许失败 30 次
periodSeconds: 10 # 每 10 秒探测一次
# 总宽限期 = 30 × 10 = 300 秒(5 分钟)
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 0 # startupProbe 成功后立即开始
periodSeconds: 10
注意 :如果同时配置了 startupProbe 和 livenessProbe,livenessProbe 会在 startupProbe 成功后才开始执行。这确保了慢启动应用不会被误杀。
1.9 tcpSocket 探针
适用于检测 TCP 端口是否可连接(如数据库、Redis 等)。
yaml
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 5
periodSeconds: 5
1.10 探针在生产环境中的最佳实践
- readinessProbe 用于滚动更新:新 Pod 启动时,readinessProbe 成功后才会加入 Service,确保新版本准备好后才接收流量。
- livenessProbe 用于自愈:当应用死锁或崩溃时,livenessProbe 失败触发重启。
- startupProbe 用于慢启动应用:对于启动时间长的应用(如 Java 应用),配置 startupProbe 可以避免 livenessProbe 在启动期间误判。
- 合理设置 initialDelaySeconds:给应用足够的启动时间。
- 不要混淆两个探针:readinessProbe 失败不重启(只摘流量),livenessProbe 失败会重启(影响可能更大)。
健康检查在滚动更新中的应用:
在滚动更新过程中,如果新版本 Pod 的 readinessProbe 一直失败,它就不会被加入 Service 的 Endpoints。滚动更新会暂停,旧版本 Pod 继续提供服务,从而实现了安全的版本发布。这正是 Kubernetes 实现"零停机部署"的关键机制之一。
二、认证管理(Authentication)
2.1 Kubernetes 中的两类用户
Kubernetes 集群有两类用户:
| 类型 | 说明 | 管理方式 |
|---|---|---|
| 普通用户(User) | 由外部身份认证插件管理,Kubernetes 没有对应的 API 对象 | 证书、Token 等 |
| 服务账户(ServiceAccount) | 由 Kubernetes API 管理,有对应的 API 对象 | 由 Kubernetes 自动/手动创建 |
关键理解 :Kubernetes 本身不存储普通用户信息 ,而是通过 X509 证书等认证插件来识别用户身份。证书中的
CN(Common Name)字段即为用户名。这符合 UNIX 哲学------Kubernetes 只专注于应用编排,用户管理则通过接口集成外部系统。
2.2 创建用户(X509 证书方式)
步骤 1:客户端生成私钥和证书签名请求
bash
root@client:~# apt install -y kubectl=1.30.2-1.1
# 生成私钥
root@client:~# openssl genrsa -out whisky.key 2048
# 生成证书签名请求(CSR)
root@client:~# openssl req -new -key whisky.key -out whisky.csr -subj '/CN=whisky/O=kubernetes'
# CN: 用户名(whisky)
# O: 用户组(kubernetes)
# 将 CSR 发送给集群管理员
root@client:~# scp whisky.csr root@master30:
步骤 2:管理员签发证书
bash
root@master30:~# openssl x509 -req -in whisky.csr \
-CA /etc/kubernetes/pki/ca.crt \
-CAkey /etc/kubernetes/pki/ca.key \
-CAcreateserial -out whisky.crt -days 1095
步骤 3:创建 kubeconfig
方法一:使用 kubectl config 命令(推荐)
bash
# 准备配置文件模板
root@client:~# cp config.tpl config
# 设置集群信息
root@client:~# kubectl config set-cluster kubernetes \
--kubeconfig=config \
--certificate-authority=ca.crt \
--server=https://10.1.8.30:6443 \
--embed-certs
# 设置用户凭据
root@client:~# kubectl config set-credentials whisky \
--kubeconfig=config \
--client-key=whisky.key \
--client-certificate=whisky.crt \
--embed-certs
# 设置上下文
root@client:~# kubectl config set-context whisky \
--kubeconfig=config \
--namespace=default \
--cluster=kubernetes \
--user=whisky
# 切换到该上下文
root@client:~# kubectl config use-context whisky --kubeconfig=config
方法二:手动编辑 YAML(不推荐,了解即可)
通过 Base64 编码将证书和密钥嵌入配置文件:
bash
# 获取各文件的 Base64 编码
root@client:~# cat ca.crt | base64 | tr -d '\n'
root@client:~# cat whisky.crt | base64 | tr -d '\n'
root@client:~# cat whisky.key | base64 | tr -d '\n'
步骤 4:授权用户
bash
root@master30:~# kubectl create clusterrolebinding whisky-admin \
--clusterrole=cluster-admin --user=whisky
步骤 5:验证
bash
root@client:~# kubectl get nodes --kubeconfig=config
NAME STATUS ROLES AGE VERSION
master30.whisky.cloud Ready control-plane 40h v1.30.2
worker31.whisky.cloud Ready <none> 40h v1.30.2
worker32.whisky.cloud Ready <none> 40h v1.30.2
2.3 删除用户
删除用户实际上就是删除权限绑定 + 吊销证书:
bash
# 删除权限
root@master30:~# kubectl delete clusterrolebinding whisky-admin
# 验证------已无权限
root@client:~# kubectl get nodes
Error from server (Forbidden): nodes is forbidden: User "whisky" cannot list resource "nodes"...
三、授权管理(Authorization ------ RBAC)
3.1 鉴权概述
Kubernetes API 服务器对每个请求进行鉴权(Authorization),根据策略决定允许或拒绝请求。默认情况下,所有请求都被拒绝(Deny by default)。
鉴权流程:
- 请求通过身份认证后,进入鉴权阶段
- Kubernetes 按顺序检查多个鉴权模块
- 任意一个模块批准 → 请求通过
- 所有模块都拒绝 → 返回 403 Forbidden
常用鉴权模式:
| 模式 | 说明 | 适用场景 |
|---|---|---|
| RBAC | 基于角色的访问控制 | 生产环境推荐 |
| Node | 节点专用鉴权 | 与 RBAC 配合使用 |
| ABAC | 基于属性的访问控制 | 已逐步被 RBAC 取代 |
| AlwaysAllow | 允许所有请求 | 仅测试环境 |
| AlwaysDeny | 拒绝所有请求 | 仅测试环境 |
查看当前鉴权模式:
bash
root@master30:~# cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep authorization-mode
- --authorization-mode=Node,RBAC
3.2 RBAC 核心概念
RBAC(基于角色的访问控制)通过四个核心 API 对象实现权限管理:
| 对象 | 作用 | 范围 |
|---|---|---|
| Role | 定义一组权限(规则) | Namespace 级别 |
| ClusterRole | 定义一组权限(规则) | 集群级别 |
| RoleBinding | 将 Role 绑定给用户/组/SA | Namespace 级别 |
| ClusterRoleBinding | 将 ClusterRole 绑定给用户/组/SA | 集群级别 |
层级关系:
text
User/Group/ServiceAccount
↓(绑定)
Role/ClusterRole(定义了权限规则)
↓
具体的操作权限(get/list/create/delete...)
3.3 Role 与 RoleBinding
创建 Role
示例:创建对 Pod 具有 get/list/watch 权限的 Role
bash
root@master30:~# kubectl create role pod-role \
--verb=get,list,watch --resource=pods -n default
对应的 YAML:
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-role
namespace: default
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
创建 RoleBinding
bash
root@master30:~# kubectl create rolebinding default-pod-whisky \
-n default --role=pod-role --user=whisky
对应的 YAML:
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: default-pod-whisky
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-role
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: whisky
验证:
bash
# whisky 用户可以查看 default 命名空间的 Pod
root@client:~# kubectl get pod -n default
NAME READY STATUS RESTARTS AGE
web 1/1 Running 0 2m
# 但不能查看 kube-system 的 Pod
root@client:~# kubectl get pod -n kube-system
Error from server (Forbidden): pods is forbidden...
3.4 apiGroups 的详细对照表
在 Role 的 rules 中,apiGroups 字段必须正确填写,否则权限不生效。下表列出了常见资源类型及其对应的 apiGroups:
| 资源类型 | apiVersion | apiGroups | 示例 |
|---|---|---|---|
| Pod、Service、PVC、Secret、ConfigMap | v1 | ""(空字符串) |
pods、services |
| Deployment、DaemonSet、StatefulSet | apps/v1 | "apps" |
deployments |
| Job | batch/v1 | "batch" |
jobs |
| CronJob | batch/v1 | "batch" |
cronjobs |
| NetworkPolicy | networking.k8s.io/v1 | "networking.k8s.io" |
networkpolicies |
| Role、RoleBinding、ClusterRole、ClusterRoleBinding | rbac.authorization.k8s.io/v1 | "rbac.authorization.k8s.io" |
roles、rolebindings |
| PersistentVolume、PersistentVolumeClaim | v1 | "" |
persistentvolumes |
| Ingress | networking.k8s.io/v1 | "networking.k8s.io" |
ingresses |
查询资源的 apiGroups:
bash
root@master30:~# kubectl explain deployment | grep VERSION
VERSION: apps/v1 # apiGroups 即为 "apps"
root@master30:~# kubectl explain networkpolicy | grep VERSION
VERSION: networking.k8s.io/v1 # apiGroups 即为 "networking.k8s.io"
错误示例:apiGroups 写错导致权限不生效
yaml
# 错误写法(apiGroups 为空,无法操作 deployment)
rules:
- apiGroups: [""] # 应该是 "apps"
resources: ["deployments"]
verbs: ["get", "list"]
# 正确写法
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list"]
3.5 ClusterRole 与 ClusterRoleBinding
Role vs ClusterRole:
| 对比项 | Role | ClusterRole |
|---|---|---|
| 作用范围 | 单个 Namespace | 所有 Namespace + 集群级资源 |
| 管理资源类型 | Namespace 级资源 | Namespace 级 + 集群级(Node、PV 等) |
| 适用场景 | 细粒度权限控制 | 集群级权限、预置角色 |
预置的 ClusterRole:
| ClusterRole | 权限范围 |
|---|---|
view |
对所有资源的 get/list/watch 权限(只读) |
edit |
在 view 基础上,增加 create/delete/patch/update 权限 |
admin |
对 Namespace 内大部分资源具有所有权限 |
cluster-admin |
对集群所有资源具有所有权限 |
创建 ClusterRole
bash
root@master30:~# kubectl create clusterrole pod-clusterrole \
--verb=get,list,watch --resource=pods
创建 ClusterRoleBinding
bash
root@master30:~# kubectl create clusterrolebinding whisky-pod-clusterrole \
--clusterrole=pod-clusterrole --user=whisky
效果 :whisky 用户可以查看所有 Namespace 的 Pod。
3.6 RBAC 完整实战案例
场景 :为开发者 zhangsan 创建只读权限,仅能查看 dev 命名空间的 Pod 和 Service。
步骤 1:创建用户证书
bash
# 生成私钥和 CSR
root@client:~# openssl genrsa -out zhangsan.key 2048
root@client:~# openssl req -new -key zhangsan.key -out zhangsan.csr -subj '/CN=zhangsan'
# 管理员签发证书
root@master30:~# openssl x509 -req -in zhangsan.csr \
-CA /etc/kubernetes/pki/ca.crt \
-CAkey /etc/kubernetes/pki/ca.key \
-out zhangsan.crt -days 365
步骤 2:创建 Role(dev 命名空间的只读权限)
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: dev-reader
namespace: dev
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list", "watch"]
bash
root@master30:~# kubectl create ns dev
root@master30:~# kubectl apply -f dev-reader-role.yaml
步骤 3:创建 RoleBinding
bash
root@master30:~# kubectl create rolebinding zhangsan-dev-reader \
-n dev --role=dev-reader --user=zhangsan
步骤 4:生成 kubeconfig 并验证
bash
# 创建 kubeconfig(同 2.2 节方法)
root@client:~# kubectl config set-credentials zhangsan \
--client-key=zhangsan.key --client-certificate=zhangsan.crt --embed-certs
# 验证------可以查看 dev 的 Pod 和 Service
root@client:~# kubectl get pods -n dev
No resources found in dev namespace.
root@client:~# kubectl get services -n dev
No resources found in dev namespace.
# 但不能查看 dev 的 Deployment(未授权)
root@client:~# kubectl get deployments -n dev
Error from server (Forbidden): deployments.apps is forbidden...
3.7 RBAC 最佳实践
- 最小权限原则:只授予用户完成任务所需的最小权限
- 使用预置 ClusterRole :优先使用
view、edit、admin等预置角色 - 区分 Role 和 ClusterRole:Namespace 级别的权限用 Role,集群级权限用 ClusterRole
- 定期审计 :定期检查
clusterrolebindings和rolebindings,移除不必要的权限
四、服务账户(ServiceAccount)
4.1 什么是 ServiceAccount?
ServiceAccount(服务账户) 是 Kubernetes 为 Pod 中运行的进程提供的身份标识。
- 每个 Namespace 都有一个默认的
defaultServiceAccount - Pod 默认使用
defaultServiceAccount 运行 - ServiceAccount 可以绑定 RBAC 权限,使 Pod 内的进程具有相应的 API 访问权限
4.2 ServiceAccount vs 普通用户
| 对比项 | 普通用户(User) | 服务账户(ServiceAccount) |
|---|---|---|
| 使用主体 | 人(管理员、开发者) | Pod 中的进程 |
| 作用范围 | 集群范围 | 命名空间范围 |
| 管理方式 | 外部认证系统(证书、OIDC) | Kubernetes API |
| 典型场景 | kubectl 操作集群 |
Pod 通过 API 管理集群 |
4.3 ServiceAccount 的 Token 机制
Kubernetes 1.24+ 版本使用 投射卷(Projected Volume) 方式为 Pod 提供 Token:
yaml
volumes:
- name: kube-api-access-xxxxx
projected:
sources:
- serviceAccountToken: # Token(自动轮转)
path: token
- configMap: # CA 证书
name: kube-root-ca.crt
- downwardAPI: # Namespace 信息
items:
- fieldRef:
fieldPath: metadata.namespace
path: namespace
Pod 内的 Token 信息:
bash
root@master30:~# kubectl exec web -- ls /var/run/secrets/kubernetes.io/serviceaccount
ca.crt namespace token
root@master30:~# kubectl exec web -- cat /var/run/secrets/kubernetes.io/serviceaccount/namespace
auth
4.4 ServiceAccount 管理
创建 ServiceAccount:
bash
root@master30:~# kubectl create sa sa1
root@master30:~# kubectl get sa sa1
NAME SECRETS AGE
sa1 1 9s
授权 ServiceAccount:
bash
# 将 cluster-admin 权限授予 sa1
root@master30:~# kubectl create clusterrolebinding auth-sa1-cluster-admin \
--clusterrole=cluster-admin \
--serviceaccount=auth:sa1
# 格式:--serviceaccount=<namespace>:<serviceaccount-name>
在 Pod 中使用 ServiceAccount:
yaml
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
serviceAccountName: sa1 # 指定使用 sa1
containers:
- image: nginx
name: nginx
验证:
bash
root@master30:~# kubectl get pod web -o yaml | grep serviceAccount
serviceAccount: sa1
serviceAccountName: sa1
4.5 手动管理 ServiceAccount Token
创建临时 Token(推荐):
bash
root@master30:~# kubectl create token sa1
eyJhbGciOiJSUzI1NiIsImt...
创建长期 Token(手动创建 Secret):
yaml
apiVersion: v1
kind: Secret
metadata:
name: sa1-secret
annotations:
kubernetes.io/service-account.name: sa1
type: kubernetes.io/service-account-token
bash
root@master30:~# kubectl apply -f sa1-token.yaml
# Token 会自动填充到 Secret 中
注意 :长期 Token 有安全风险,推荐使用短期 Token(
kubectl create token)。
4.6 典型应用场景
Kubernetes Dashboard 使用 ServiceAccount 访问集群:
bash
root@master30:~# kubectl describe sa kubernetes-dashboard -n kubernetes-dashboard
Name: kubernetes-dashboard
Tokens: kubernetes-dashboard-token-xxxxx
# Dashboard Pod 使用该 SA 访问 API Server
五、总结与知识点一览表
5.1 核心知识点汇总
| 模块 | 核心概念 | 关键命令 |
|---|---|---|
| Health Check | liveness/readiness/startup 探针 | livenessProbe, readinessProbe, startupProbe |
| 探测方法 | httpGet / exec / tcpSocket | 在 Pod Spec 中配置 |
| 认证 | X509 证书用户 | openssl req, kubectl config set-credentials |
| RBAC | Role / ClusterRole / RoleBinding / ClusterRoleBinding | kubectl create role, kubectl create clusterrolebinding |
| ServiceAccount | Pod 身份标识 | kubectl create sa, kubectl create token |
5.2 三种探针对比
| 探针 | 失败后果 | 是否影响流量 | 适用场景 |
|---|---|---|---|
| livenessProbe | 重启 Pod | ✅(Pod 重启期间) | 检测应用死锁/崩溃 |
| readinessProbe | 从 Service 移除 | ✅(仅移除该 Pod) | 检测应用是否准备好服务 |
| startupProbe | 重启 Pod | ✅(启动期间) | 慢启动应用 |
5.3 RBAC 四要素速查
| 对象 | 范围 | 作用 |
|---|---|---|
| Role | Namespace | 定义 Namespace 内资源的权限 |
| ClusterRole | 集群 | 定义集群级资源的权限 |
| RoleBinding | Namespace | 将 Role 绑定给用户/组/SA |
| ClusterRoleBinding | 集群 | 将 ClusterRole 绑定给用户/组/SA |
5.4 常用命令速查
| 操作 | 命令 |
|---|---|
| 查看探针配置 | `kubectl get pod -o yaml |
| 查看 Pod 日志 | kubectl logs <name> |
| 创建 Role | kubectl create role <name> --verb=<verbs> --resource=<resources> |
| 创建 RoleBinding | kubectl create rolebinding <name> --role=<role> --user=<user> |
| 创建 ClusterRole | kubectl create clusterrole <name> --verb=<verbs> --resource=<resources> |
| 创建 ClusterRoleBinding | kubectl create clusterrolebinding <name> --clusterrole=<role> --user=<user> |
| 创建 ServiceAccount | kubectl create sa <name> |
| 创建 Token | kubectl create token <sa-name> |
5.5 常见错误排查
| 错误 | 原因 | 解决方法 |
|---|---|---|
Error from server (Forbidden) |
用户权限不足 | 检查 Role/ClusterRole 和绑定 |
livenessProbe failed |
应用不可用或探针配置不当 | 检查 initialDelaySeconds 和探针路径 |
readinessProbe failed |
应用未就绪 | 检查应用状态,延长 initialDelaySeconds |
| Pod 被反复重启 | livenessProbe 一直失败 | 检查应用是否真正健康,或调整探针参数 |
| ServiceAccount Token 不存在 | 使用旧版本 Kubernetes 或 Token 被删除 | 使用 kubectl create token 生成新 Token |
cannot get resource "deployments" |
apiGroups 未正确填写 | 确认资源对应的 apiGroups 并修正 |
下一期预告:Kubernetes(K8s)学习笔记(第十三期):集群存储与有状态应用(上篇):动态卷供应------StorageClass + Provisioner。涵盖:StorageClass 核心配置、Local Path Provisioner 部署、NFS Provisioner 部署、动态卷 vs 静态卷对比。
--- Compiled and Authored by Whisky --- July 2 nd, 2026