本专栏文章持续更新,新增内容使用蓝色表示。
对 Kubernetes 有点了解的朋友可能知道,访问 Kubernetes 集群通常有三种主要方式:使用 kubectl(命令行工具) 、通过 Dashboard(仪表盘)界面操作 ,或者编写程序直接调用 RESTful API 。但无论采用哪种方式,所有与集群的交互请求都必须首先到达API Server。
然而,并非所有到达 API Server 的请求都会被允许执行。请求需要经过三个关键的安全检查阶段:认证(Authentication)、鉴权(Authorization) 和 准入控制(Admission Control)。这三个阶段共同构成了 Kubernetes 访问控制的核心机制,确保只有合法且合规的请求才能对集群资源进行操作。
本篇主要围绕 认证阶段 展开介绍。
一、3A服务
当客户端尝试访问Kubernetes API Server时,需要经过严格的"安检流程",这个流程可以概括为3A服务。
1. 认证(Authentication)
- "你是自己人吗?"
类比场景 :就像员工进入公司大楼需要刷卡,系统需要验证你的身份是否合法。
核心任务:确认请求方的真实身份,回答"你是谁?"的问题。
2. 鉴权(Authorization)
- "你有权限吗?"
类比场景 :刷卡后,系统检查你是否有权限进入特定楼层或区域。
核心任务:确认已认证的用户是否有权限执行特定操作,回答"你能做什么?"的问题。
3. 准入控制(Admission Control)
- "这个操作合理吗?"
类比场景 :即使有权限,某些特殊操作(如带出机密文件)仍需额外审批。
核心任务:对请求进行最后的合规性检查,确保操作符合集群策略。
这三个步骤都由API Server统一封装和管理,构成了Kubernetes安全的第一道防线。

以上这几个步骤都被封装在API server中。
参考链接:Kubernetes API 访问控制 | Kubernetes
二、认证类型
Kubernetes 支持多种认证方式,安全级别由低到高:
1. HTTP Token 认证
-
工作原理:使用一个难以伪造的长字符串(Token)代表用户身份,每一个 Token 对应一个用户名存储在 API Server 能访问的文件中。
-
实现方式:客户端在 HTTP Header 中携带 Token,API Server 验证Token对应的用户
-
特点:简单但安全性较低,适合内部测试环境
2. HTTP Base 认证
-
工作原理:将"用户名:密码"进行 BASE64 编码后放入 HTTP Request 中的 Authorization Header,发送给服务端,服务端收到后进行解码,获取用户名和密码。
-
实现方式:Authorization: Basic base64(username:password)
-
特点:编码不等于加密,传输过程中仍可能被截获解码
3. HTTPS 证书认证
基于CA根证书签名的客户端身份认证方式。
单向HTTPS认证:客户端验证服务端身份
-
常见场景:普通网站访问
-
特点:确保连接的服务端是可信的
一个简洁的示意图如下:

双向HTTPS认证:客户端和服务端互相验证
-
常见场景:ATM机交易、金融系统
-
特点:最高安全级别,双方都需持有可信证书
安全建议:在相对安全的环境中,可以考虑简化认证以节省资源;但在生产环境,特别是云环境,强烈推荐使用HTTPS证书认证。
三、API Server 的认证策略
3.1 组件认证
3.1.1 无需加密------集群核心组件
Controller Manager、Scheduler
原因:基于 kubeadm API Server 处于同一台机器,通过 127.0.0.1 非安全地址访问即可。
3.1.2 需要加密------客户端工具
1)证书手动签发
例如:kube-proxy、kubectl 等长期存在的客户端。
2)证书自动签发
例如:kubelet(在加入集群时已完成双向认证)。
手动或自动签发的证书通常被封装成 kubeconfig 文件,方便客户端统一管理认证信息。
3.2 Pod 认证
部分 Pod 需要获取集群相关信息时需要访问 API Server ,如 calico、coreDNS,但是 Pod 的创建、销毁是动态的。如果为每个 Pod 都单独颁发证书:
-
性能开销大:频繁的证书签发和撤销操作
-
管理复杂:大量证书的存储和轮换
-
安全风险:证书泄露难以快速应对
所以 Kubernetes 使用了 ServiceAccount 进行 pod 的认证。
类比场景:公司访客系统。与其为每位访客制作工牌,不如使用临时访客证(ServiceAccount),既高效又安全。
四、ServiceAccount
默认情况下,每个 namespace 都会有一个 ServiceAccount,如果 Pod 在创建时没有指定 ServiceAccount,就会使用 Pod 所属的 namespace 的 ServiceAccount。
另外,kubernetes 设计了一种资源对象叫做 Secret,分为两类,一种是用于 ServiceAccount 的 service-account-token,另一种是用于保存用户自定义保密信息的 Opaque。
当Pod使用某个 ServiceAccount 时,对应于此 ServiceAccount 的 service-account-token 类型的 Secret 会自动创建并挂载到 Pod 中。
默认挂载目录:/run/secrets/kubernetes.io/serviceaccount/。
4.1 实验
创建命名空间 test_SA:
bash
kubectl create namespace test_SA
查看当前命名空间下的 SA 证书:
bash
kubectl get serviceaccount -n test_SA
可以看到有个名叫 default 的默认创建的 SA,如果该命名空间下的 Pod 需要访问 API server 的话,就会默认调用此 SA 发起对 API server 的访问。
其次 Pod 在使用 SA 之后,会默认被挂载到 /run/secrets/kubernetes.io/serviceaccount/:
bash
# 查看当前的所有 Pod
kubectl get pod -A
# 选择一个访问 API server 的 pod 进入
kubectl exec -it -n [namespace-name] [pod-name] -- /bin/sh
cd /run/secrets/kubernetes.io/serviceaccount/
ls -l
可以看到有三个文件:
ca.crt # API Server的CA根证书
namespace # 当前Pod所在的命名空间
token # API Server签名的JWT令牌
4.2 ServiceAccount 组成部分
4.2.1 ca.crt
根证书,用于 Client 端(Pod)验证 API Server 发送的证书,确认它的安全性。
4.2.2 token
API Server 私钥签名的 JWT,用于访问 API Server 时,Server 端认证。
补充:Json web token(JWT)适用于分布式站点的单点登录(SSO)场景。
4.2.3 namespace
命名空间,标识这个 service-account-token 的作用域。
4.3 创建 ServiceAccount
4.3.1 方式一:命令行
bash
# 方式一:命令行快速创建
kubectl create serviceaccount my-sa -n my-namespace
# 补充:查看生成ServiceAccount的YAML文件
kubectl create serviceaccount my-sa -n my-namespace --dry-run=client -o yaml
4.3.2 方式二:yaml 文件
bash
# 方式二:YAML声明式创建
cat > my-serviceaccount.yaml <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-serviceaccount
namespace: my-namespace
EOF
kubectl apply -f my-serviceaccount.yaml
总结 ServiceAccount 的核心机制:
按Namespace隔离:每个命名空间自动创建默认ServiceAccount;
动态绑定:Pod未指定ServiceAccount时,自动使用所属命名空间的默认账户;
自动挂载:认证凭证自动挂载到Pod的固定路径。
如有问题或建议,欢迎在评论区中留言~