当前位置: 首页 > news >正文

K8s 安全机制全解析

一、前言

二、Authentication(认证机制)

2.1 支持的认证方式

2.2 哪些访问需要认证

2.3 通信端口与安全性

2.4 证书的颁发方式

2.5 kubeconfig 文件结构

2.6 ServiceAccount(服务账户)

2.7 Secret 与 ServiceAccount 的关系

三、Authorization(鉴权机制)

3.1 常见授权模式对比

3.2 RBAC 四大核心对象

3.3 角色(Role/ClusterRole)示例

3.4 绑定角色权限(RoleBinding / ClusterRoleBinding)

3.5 主体(Subject)与 JWT

什么是 Subject(主体)

JWT 在 Kubernetes 中的角色

1) JWT 的结构(3 部分)

2) 常见 claim(k8s 环境)

3.6 子资源(Subresources)

四、Admission Control(准入控制)

常见 Admission 插件

五、实践案例:创建受限用户(命名空间级别权限)

Step 0:创建系统用户

Step 1:生成用户 CSR 与证书

Step 2:生成 kubeconfig

Step 3:创建命名空间与 kubeconfig 上下文

Step 4:创建 Role 与 RoleBinding(命名空间级权限)

Step 5:验证(切换到 ciallo 用户执行操作)

Step 6:管理员侧检查(确认 RBAC 生效)

可选:授予命名空间管理员(如果需要)

撤销 / 收回访问(重要)

1. 删除 RoleBinding / Role

2. 撤销用户证书(若用证书认证)

3. 删除 kubeconfig(分发到用户机器上)

审计与排错建议

查看拒绝原因(管理侧)

常见排错命令

如果 kubectl 返回 connection refused 或 The connection to the server localhost:8080 was refused:

额外补充:用 ServiceAccount 做应用访问(更常见的场景)

六、总结(Summary)

一、前言

在 Kubernetes(以下简称 K8s)集群中,安全机制是核心基础设施之一。 API Server 是整个系统的“中枢大脑”,所有控制与资源操作都要经过它。

因此,K8s 的安全体系可以理解为一套完整的“守门系统”,主要包括三层安全防线:

  1. Authentication(认证):你是谁?

  2. Authorization(鉴权):你能做什么?

  3. Admission Control(准入控制):是否允许执行?


二、Authentication(认证机制)

在 K8s 集群中,任何访问 API Server 的请求都需要首先通过认证环节。 这一步确认请求者的身份是否可信。

2.1 支持的认证方式

类型说明安全等级
HTTP Basic Auth使用 用户名:密码(Base64 编码)放入 HTTP Header
HTTP Token Auth通过 Header 携带 Token 进行认证(由 API Server 校验)
HTTPS 证书认证采用双向 TLS 认证,基于 CA 根证书签发✅ 高(推荐)

💡 HTTPS 证书认证是生产环境最安全、最标准的方式,可实现双向信任


2.2 哪些访问需要认证

  • 集群组件访问:如 kubectlkubeletkube-proxy

  • Pod 内访问:如 corednsdashboard 这类运行在 Pod 中的系统组件。


2.3 通信端口与安全性

组件通信端口是否加密
kube-apiserver6443✅ HTTPS(双向认证)
controller-managerscheduler8080⚠️ HTTP(非加密)
kubectlkubelet6443✅ HTTPS

2.4 证书的颁发方式

Kubernetes 提供两种方式生成证书:

  • 手动签发:在二进制部署环境中手动生成并签发 CA 与客户端证书。

  • 自动签发:当 kubelet 第一次加入集群时,用 bootstrap token 认证,Controller Manager 会自动为其颁发证书。


2.5 kubeconfig 文件结构

K8s 的认证核心文件是 ~/.kube/config,它包含三个部分:

部分含义
cluster集群信息(API Server 地址、CA 证书等)
user用户凭据(客户端证书与私钥)
context上下文绑定(集群 + 用户 + 命名空间)

💡 一个 kubeconfig 可以同时包含多个上下文,实现多集群管理。


2.6 ServiceAccount(服务账户)

ServiceAccount(简称 SA) 是专为 Pod 内应用访问 API Server 设计的身份机制。

每个命名空间默认存在一个 default SA,当创建 Pod 时系统会自动挂载认证信息:

/var/run/secrets/kubernetes.io/serviceaccount/├── ca.crt       # 集群 CA 根证书├── namespace    # 当前命名空间└── token        # JWT 签名的访问令牌

Pod 内程序通过这个 token 与 API Server 通信,实现安全认证。 这也是为什么 Pod 内可以直接使用 kubectl 或 API 客户端访问集群的原因。


2.7 Secret 与 ServiceAccount 的关系

K8s 中的 Secret 用于存储敏感信息。与 SA 相关的 Secret 主要有两类:

类型说明
service-account-token系统自动生成,用于认证
Opaque用户自定义的密钥内容

每个 SA 会自动关联一个 service-account-token 类型的 Secret,其中包含:

  • token(由 API Server 私钥签名的 Token,用于服务端认证来访主体)

  • ca.crt(CA 根证书,供客户端验证 API Server 的证书)

  • namespace(该 service-account-token 的命名空间作用域)


三、Authorization(鉴权机制)

认证通过后,K8s 需要确定用户能做什么,即权限控制阶段。 这部分由 --authorization-mode 参数控制。


3.1 常见授权模式对比

模式描述特点
AlwaysDeny拒绝所有请求测试用
AlwaysAllow允许所有请求不安全
ABAC(Attribute-Based)基于属性文件的静态规则授权需重启 API Server
Webhook调用外部 REST 服务判断权限灵活但复杂
✅ RBAC(Role-Based Access Control)基于角色的权限控制官方推荐,动态可调

3.2 RBAC 四大核心对象

对象级别功能
Role命名空间级定义局部权限
ClusterRole集群级定义全局权限
RoleBinding命名空间级将角色绑定到用户/SA
ClusterRoleBinding集群级全局绑定角色

⚙️ 注意:

  • 使用 RoleBinding 绑定 ClusterRole 时仍仅作用于当前命名空间;

  • 使用 ClusterRoleBinding 则可全局生效。


3.3 角色(Role/ClusterRole)示例

  • 权限仅能累加(白名单),不存在“先有很多再减少”的黑名单模型。

  • Role 只能定义在 某个命名空间 内;跨命名空间请使用 ClusterRole

Role 示例(只读访问 default 命名空间的 Pods):

apiVersion: rbac.authorization.k8s.io/v1  #指定 core API 组和版本
kind: Role   #指定类型为 Role
metadata:namespace: default   #使用默认命名空间 name: pod-reader   #Role 的名称
rules:   #定义规则
- apiGroups: [""]  #""表示 apiGroups 和 apiVersion 使用相同的 core API 组,即 rbac.authorization.k8s.ioresources: ["pods"]  #资源对象为 Pod 类型verbs: ["get", "watch", "list"]  #被授予的操作权限#以上配置的意义是,如果把 pod-reader 这个 Role 赋予给一个用户,那么这个用户将在 default 命名空间中具有对 Pod 资源对象 进行 get(获取)、watch(监听)、list(列出)这三个操作权限。

ClusterRole 示例(读取所有命名空间的 Secrets):

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:# "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制name: secret-reader
rules:
- apiGroups: [""]resources: ["secrets"]verbs: ["get", "watch", "list"]

3.4 绑定角色权限(RoleBinding / ClusterRoleBinding)

  • RoleBinding:在命名空间内Role/ClusterRole 赋予 User/Group/ServiceAccount

  • ClusterRoleBinding:在全集群范围ClusterRole 赋予 User/Group/ServiceAccount

(1)RoleBinding 示例(在 default 内授予用户 cy 读取 Pods 的 Role)

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: read-podsnamespace: default
subjects:
- kind: Username: cyapiGroup: rbac.authorization.k8s.io
roleRef:kind: Rolename: pod-readerapiGroup: rbac.authorization.k8s.io#将 default 命名空间的 pod-reader Role 授予 cy 用户,此后 cy 用户在 default 命名空间中将具有 pod-reader 的权限---------------------------------------------------------------
#示例2,在 `kube-public` 内给用户 `qh` 引用 ClusterRole `secret-reader`apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: read-secretsnamespace: kube-public
subjects:
- kind: Username: qhapiGroup: rbac.authorization.k8s.io
roleRef:kind: ClusterRolename: secret-readerapiGroup: rbac.authorization.k8s.io#以上 RoleBinding 引用了一个 ClusterRole,这个 ClusterRole 具有整个集群内对 secrets 的访问权限;但是其授权用户 qh 只能访问 kube-public 空间中的 secrets(因为 RoleBinding 定义在 kube-public 命名空间)

(2)ClusterRoleBinding 示例

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: read-secrets-global
subjects:
- kind: Groupname: managerapiGroup: rbac.authorization.k8s.io
roleRef:kind: ClusterRolename: secret-readerapiGroup: rbac.authorization.k8s.io#以上 ClusterRoleBinding 授权 manager 组内所有用户在全部命名空间中对 secrets 进行访问。


3.5 主体(Subject)与 JWT

什么是 Subject(主体)

在 RBAC 的世界里,Subject 表示“谁将被授予权限”。Subject 有三类:

  • User:外部或系统用户(通常是证书 CN、外部身份提供者中的用户名)。

  • Group:用户组(便于把权限授予一组用户)。

  • ServiceAccount:Kubernetes 内部的服务账户(用于 Pod 内部进程访问 API Server)。

示例(RoleBinding 中的 subjects):

subjects:
- kind: Username: aliceapiGroup: rbac.authorization.k8s.io
- kind: Groupname: dev-teamapiGroup: rbac.authorization.k8s.io
- kind: ServiceAccountname: myappnamespace: app-namespace

注意:

  • ServiceAccount 需要 namespace 字段(如果跨命名空间引用 SA,必须写明)。

  • User/Group 的名字按照认证系统决定(证书的 CN、OIDC 的 sub / preferred_username 等)。

  • system: 前缀为系统保留,如 system:masters 是集群管理员组,普通用户勿滥用。


JWT 在 Kubernetes 中的角色

Kubernetes 使用 JWT(JSON Web Token)作为一种常见的 token 格式 —— 尤其体现在 ServiceAccount 的 token(早期是长期有效的 secret token,现代推荐用短期绑定 token / TokenRequest)。

1) JWT 的结构(3 部分)

JWT = header.payload.signature(都使用 base64url 编码):

  • header:算法(如 alg: RS256)和类型 typ: JWT

  • payload(声明 claims):包含 iss(issuer)、sub(subject)、aud(audience)、exp(过期时间)、iat(签发时间)、以及 k8s 自定义字段(例如 kubernetes.io/serviceaccount/namespacekubernetes.io/serviceaccount/secret.name 等)。

  • signature:由签名密钥对 header+payload 计算得到,保证不可篡改。

2) 常见 claim(k8s 环境)
  • iss:token 的颁发者(例如 kubernetes/serviceaccount 或 API Server)。

  • sub:主体(如 system:serviceaccount:namespace:name)。

  • aud:受众(token 能被哪些服务器接受,如 kubernetes.default.svc.cluster.local)。

  • exp:过期时间(UNIX 时间)。

  • k8s 特有:kubernetes.io/serviceaccount/namespace, kubernetes.io/serviceaccount/secret.name, kubernetes.io/serviceaccount/service-account.name 等。

    常见 verbs / resources / apiGroups 速查

    • verbsgetlistwatchcreateupdatepatchdeleteexec

    • resources(示例):servicesendpointspodssecretsconfigmapscrontabsdeploymentsjobsnodesrolebindingsclusterrolesdaemonsetsreplicasetsstatefulsetshorizontalpodautoscalersreplicationcontrollerscronjobs

    • apiGroups""(core)、appsautoscalingbatch


3.6 子资源(Subresources)

有些资源有子资源,例如获取 Pod 日志:

GET /api/v1/namespaces/{namespace}/pods/{name}/log

RBAC 可对其精确控制:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:namespace: defaultname: pod-and-pod-logs-reader
rules:
- apiGroups: [""]resources: ["pods", "pods/log"]verbs: ["get", "list"]

四、Admission Control(准入控制)

通过认证与鉴权后,请求仍需经过 Admission Controller 检查。 它是一系列插件链,用于验证、修改或拒绝请求。

常见 Admission 插件

插件功能
NamespaceLifecycle管理命名空间生命周期
LimitRanger控制资源限制
ServiceAccount自动为 Pod 注入 SA
ResourceQuota命名空间配额管理
NodeRestriction限制 Node 的注册与权限
Mutating/ValidatingWebhook动态策略验证(如 OPA/Gatekeeper)

五、实践案例:创建受限用户(命名空间级别权限)

目标:创建一个名为 ciallo 的用户,仅能在 yozusoft 命名空间管理 Pods。

Step 0:创建系统用户

useradd ciallo
passwd ciallo# 切换为该用户尝试访问
su - ciallo
kubectl get pods
# The connection to the server localhost:8080 was refused - did you specify the right host or port?


Step 1:生成用户 CSR 与证书

ciallo-csr.json(注意 CN 将作为 k8s User 名称,names[].O 会作为 Group):

# 下载最新版本(根据需要可去 GitHub 查看最新版本)
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssl_1.6.5_linux_amd64
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssljson_1.6.5_linux_amd64# 添加执行权限
chmod +x cfssl_1.6.5_linux_amd64 cfssljson_1.6.5_linux_amd64# 移动到 /usr/local/bin
sudo mv cfssl_1.6.5_linux_amd64 /usr/local/bin/cfssl
sudo mv cfssljson_1.6.5_linux_amd64 /usr/local/bin/cfssljsonmkdir -p /opt/ciallo && cd /opt/ciallo
------------------------------------------------------------
vim user-cert.sh
#######################
cat > ciallo-csr.json <<EOF
{"CN": "ciallo","hosts": [],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","ST": "BeiJing","L": "BeiJing","O": "k8s","OU": "System"}]
}
EOF
------------------------------------------------------------------
cd /etc/kubernetes/pki/
cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes /opt/ciallo/ciallo-csr.json | cfssljson -bare ciallo (报错就先执行下面的命令,然后再重新执行该命令)
------------------------------------------------------------------
chmod +x user-cert.sh
./user-cert.sh


Step 2:生成 kubeconfig

借助 kubectl config 创建专属 kubeconfig(示例脚本):

cd /opt/ciallovim rbac-kubeconfig.sh
APISERVER=$1
# 设置集群参数
export KUBE_APISERVER="https://$APISERVER:6443"
kubectl config set-cluster kubernetes \--certificate-authority=/etc/kubernetes/pki/ca.crt \--embed-certs=true \--server=${KUBE_APISERVER} \--kubeconfig=ciallo.kubeconfig# 设置客户端认证参数
kubectl config set-credentials ciallo \--client-key=/etc/kubernetes/pki/ciallo-key.pem \--client-certificate=/etc/kubernetes/pki/ciallo.pem \--embed-certs=true \--kubeconfig=ciallo.kubeconfig# 设置上下文参数
kubectl config set-context kubernetes \--cluster=kubernetes \--user=ciallo \--namespace=yozusoft \--kubeconfig=ciallo.kubeconfig# 使用上下文参数生成 ciallo.kubeconfig 文件
kubectl config use-context kubernetes --kubeconfig=ciallo.kubeconfig


Step 3:创建命名空间与 kubeconfig 上下文

kubectl create namespace yozusoft
chmod +x rbac-kubeconfig.sh
./rbac-kubeconfig.sh 192.168.10.10# 分发 kubeconfig
mkdir -p /home/ciallo/.kube
cp ciallo.kubeconfig /home/ciallo/.kube/config
chown -R ciallo:ciallo /home/ciallo/.kube/# 查看 kubeconfig
cat ciallo.kubeconfig

Step 4:创建 Role 与 RoleBinding(命名空间级权限)

rbac.yaml

vim rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:namespace: yozusoftname: pod-reader
rules:
- apiGroups: [""]resources: ["pods"]verbs: ["get", "watch", "list", "create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: read-podsnamespace: yozusoft
subjects:
- kind: Username: cialloapiGroup: rbac.authorization.k8s.io
roleRef:kind: Rolename: pod-readerapiGroup: rbac.authorization.k8s.io

应用:

kubectl apply -f rbac.yaml
kubectl get role,rolebinding -n yozusoft
# role.rbac.authorization.k8s.io/pod-reader   32s
# rolebinding.rbac.authorization.k8s.io/read-pods   32s


Step 5:验证(切换到 ciallo 用户执行操作)

su - ciallo# 创建 Pod(允许)
cat > pod-test.yaml <<'YAML'
apiVersion: v1
kind: Pod
metadata:name: pod-test
spec:containers:- name: nginximage: nginx
YAMLkubectl create -f pod-test.yaml
kubectl get pods -o wide
# NAME       READY   STATUS    RESTARTS   AGE    IP           NODE     NOMINATED NODE   READINESS GATES
# pod-test   1/1     Running   0          114s   10.244.2.2   node02   <none>           <none># 访问 svc(拒绝)
kubectl get svc
# Error from server (Forbidden): services is forbidden: User "ciallo" cannot list resource "services" in API group "" in the namespace "kgc"# 访问 default 命名空间(拒绝)
kubectl get pods -n default
# Error from server (Forbidden): pods is forbidden: User "ciallo" cannot list resource "pods" in API group "" in the namespace "default"


Step 6:管理员侧检查(确认 RBAC 生效)

# root 用户查看:
kubectl get pods --all-namespaces -o wide
# NAMESPACE  NAME       READY  STATUS  RESTARTS  AGE   IP           NODE
# yozusoft        pod-test   1/1    Running 0         107s  10.244.2.2   node01
# ...
# 可见 RoleBinding 生效:用户仅能管理指定命名空间资源。


可选:授予命名空间管理员(如果需要)

kubectl create rolebinding ciallo-admin-binding \--clusterrole=admin \--user=ciallo \--namespace=yozusoft

撤销 / 收回访问(重要)

1. 删除 RoleBinding / Role

kubectl delete rolebinding read-pods -n yozusoft
kubectl delete role pod-reader -n yozusoft

2. 撤销用户证书(若用证书认证)

证书撤销在 k8s 中通常不是单条 API;常见做法:

  • 从发布方(CA)撤销证书并更新信任链(更换 CA 或更新 CRL),或

  • 在 API Server 端配置认证 webhook 去校验白名单(例如把该证书列入拒绝名单)。 若只是要阻止一个 kubeconfig,删除或收回 kubeconfig 是立即有效的(用户客户端失去凭证)。

3. 删除 kubeconfig(分发到用户机器上)

rm -rf /home/ciallo/.kube/config

审计与排错建议

查看拒绝原因(管理侧)

启用并查看 API Server 审计日志(若已开启 audit policy):

  • 审计日志会显示 user, verb, resource, namespace, responseStatus,便于定位被拒绝请求的主体与原因。

常见排错命令

  • 查看用户信息(以 admin 身份):

kubectl auth can-i create pods --as=ciallo -n yozusoft
kubectl auth can-i list services --as=ciallo -n yozusoft
  • 在集群上以 target user 模拟权限检查:

kubectl auth can-i get pods --as=ciallo -n yozusoft

如果 kubectl 返回 connection refusedThe connection to the server localhost:8080 was refused

  • 检查 kubeconfig server 地址是否正确(kubectl config view)。

  • 检查 API Server 是否运行并监听 6443,防火墙规则是否允许访问。


额外补充:用 ServiceAccount 做应用访问(更常见的场景)

如果目标是给应用(而不是人)授权,推荐使用 ServiceAccount 而非给 Pod 注入用户 kubeconfig:

创建 SA、Role、RoleBinding:

kubectl create sa myapp -n yozusoft
# Role (pod-reader) 与 RoleBinding 绑定到 ServiceAccount
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: myapp-readpodsnamespace: yozusoft
subjects:
- kind: ServiceAccountname: myappnamespace: yozusoft
roleRef:kind: Rolename: pod-readerapiGroup: rbac.authorization.k8s.io
EOF

Pod 使用 serviceAccountName: myapp,并建议使用 TokenRequest / projected short-lived tokens,而不是长-lived Secrets。


六、总结(Summary)

安全层级功能关键组件
认证(Authentication)验证用户身份Token / Cert / SA
鉴权(Authorization)权限控制RBAC / Webhook
准入控制(Admission)最终验证与策略控制Admission Plugins

安全最佳实践建议:

  • 使用 TLS 双向认证 确保通信安全;

  • 启用 RBAC 实现最小权限原则;

  • 配合 Admission Webhook 做策略审查;

  • 为每个微服务/用户单独创建 ServiceAccount 或 kubeconfig

  • 搭配 NetworkPolicy / WAF / 限速 加强集群防御。

http://www.dtcms.com/a/504376.html

相关文章:

  • 备案的网站名称湖南众诚建设 官方网站
  • 从0死磕全栈之使用 VS Code 调试 Next.js 应用完整指南
  • 换空间对网站排名的影响吗信息技术做网站
  • 做网站赚钱流程松江集团网站建设
  • NVIDIA大模型推理框架:TensorRT-LLM软件流程(一)
  • Altium Designer(AD24)Design设计功能总结
  • html 网站源码 卖手机推广网络怎么做
  • 吐鲁番好网站建设设计步骤的英文
  • C++如何实现小程序BUG自动给修复
  • Redis字符串编码
  • React中的事件绑定
  • [嵌入式系统-152]:CAN总线最大数据只有8个字节,CAN FD最大才64个字节,这么小的数据量,如何进行稍大一点的数据传输?
  • 个人网站做论坛还是博客好广州网站备案公司
  • 仓颉 Markdown 解析库在 HarmonyOS 应用中的实践
  • 肇庆 网站建设ci设计
  • 小九源码-springboot089-在线学习平台
  • 申请域名就可以做网站了吗网站如何做的有气质
  • 乐陵市住房和城乡建设局网站济南建立网站
  • 旅游网页设计模板网站保定网站制作网页
  • C++类和对象(中):构造函数与析构函数的核心逻辑
  • 数据结构--顺序表的测试
  • Intel HD Graphics 2000可以在window 11 中使用openGL
  • 昆明网站建设网站一建论坛建工教育网
  • 建站宝盒设置wordpress 跳转到首页
  • PySide6 文本编辑(QTextEdit)查找功能进阶 读取并记录上一次状态
  • Vivado 增量综合检查点错误的排查与解决
  • 学院的网站怎么做自己怎么制作网页游戏
  • 哪家企业的网站做的好榆林微网站建设
  • 【嵌入式】环形缓冲区缓和读写速度差的原因分析
  • 聊城开发区建设局网站郑州聚商网络科技有限公司