Kubernetes(K8s)学习笔记(第十二期):集群健康与安全——探针 + 认证授权

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

目录

  1. 引子:集群的"体检"与"门禁"
  2. Health Check(健康检查)
  3. 认证管理(Authentication)
  4. 授权管理(Authorization ------ RBAC)
  5. 服务账户(ServiceAccount)
  6. 总结与知识点一览表

引子:集群的"体检"与"门禁"

在 Kubernetes 集群的日常运维中,有两个问题始终绕不开:

第一,应用是否健康? ------ 就像人需要定期体检一样,集群中的 Pod 也需要持续"体检"。如果 Pod 里的应用已经"病倒"(死锁、崩溃、配置错误),Kubernetes 需要及时发现并采取措施(重启、摘除流量)。没有健康检查的集群,就像没有体温计和血压仪的医院------病人已经高烧昏迷,护士却还在按部就班地换药。

第二,谁可以访问集群? ------ 就像大楼需要门禁系统一样,集群也需要一套完善的"门禁"机制。谁来敲门(认证)、能进哪扇门(授权)、以什么身份进入(服务账户),都需要清晰定义。没有认证授权的集群,就像没有保安和门禁卡的大楼------任何人都可以随意进出,拿走任何东西。

本期就来回答这两个问题

  • 健康检查:告诉你"应用还活着吗?准备好接客了吗?"
  • 认证授权:告诉你"你是谁?你能做什么?"

一句话总结本期 :探针是集群的"体检医生",RBAC 是集群的"门禁系统"------两者共同保障集群的稳定运行安全访问。学完本期,你将能亲手为应用配置健康检查,并为不同用户分配合适的权限。

一、Health Check(健康检查)

1.1 为什么需要健康检查?

在生产环境中,应用可能会因为各种原因变得 unhealthy:临时连接断开、配置错误、应用死锁等。

如果不对 Pod 进行健康检查,会出现以下问题:

  1. 流量打到"死"Pod:Pod 虽然还在运行(进程未退出),但已经无法正常处理请求。没有健康检查,Service 仍会将流量转发给它。
  2. 坏 Pod 永远不重启:进程没有退出,Kubernetes 不会自动重启,应用会一直处于"假死"状态。
  3. 滚动更新失败:新版本 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 探针在生产环境中的最佳实践

  1. readinessProbe 用于滚动更新:新 Pod 启动时,readinessProbe 成功后才会加入 Service,确保新版本准备好后才接收流量。
  2. livenessProbe 用于自愈:当应用死锁或崩溃时,livenessProbe 失败触发重启。
  3. startupProbe 用于慢启动应用:对于启动时间长的应用(如 Java 应用),配置 startupProbe 可以避免 livenessProbe 在启动期间误判。
  4. 合理设置 initialDelaySeconds:给应用足够的启动时间。
  5. 不要混淆两个探针: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)

鉴权流程

  1. 请求通过身份认证后,进入鉴权阶段
  2. Kubernetes 按顺序检查多个鉴权模块
  3. 任意一个模块批准 → 请求通过
  4. 所有模块都拒绝 → 返回 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 ""(空字符串) podsservices
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" rolesrolebindings
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 最佳实践

  1. 最小权限原则:只授予用户完成任务所需的最小权限
  2. 使用预置 ClusterRole :优先使用 vieweditadmin 等预置角色
  3. 区分 Role 和 ClusterRole:Namespace 级别的权限用 Role,集群级权限用 ClusterRole
  4. 定期审计 :定期检查 clusterrolebindingsrolebindings,移除不必要的权限

四、服务账户(ServiceAccount)

4.1 什么是 ServiceAccount?

ServiceAccount(服务账户) 是 Kubernetes 为 Pod 中运行的进程提供的身份标识。

  • 每个 Namespace 都有一个默认的 default ServiceAccount
  • Pod 默认使用 default ServiceAccount 运行
  • 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