64 K8s安全机制

前言

本文系统阐述Kubernetes安全机制的核心架构与实践方法,详细解析API Server保护的三大关键环节:认证、鉴权和准入控制,以及如何通过RBAC实现细粒度权限管理。特别聚焦在实践中如何创建安全隔离的集群访问账号,适用于Kubernetes安全架构设计与运维人员。

  1. 安全机制说明
  2. 认证:身份
  3. 鉴权:权限
  4. 准入控制
  5. 实践:赋权普通用户操作k8s

理论部分

1_安全机制概述

安全机制:保护Kubernetes集群中API Server的三层防护体系,防止未授权访问和操作。

1.1_机制说明

安全体系设计原因:Kubernetes作为分布式集群管理工具,API Server是内部组件通信中介与外部控制入口,安全机制围绕保护API Server设计。

安全三大环节

  1. 认证(Authentication):验证"你是谁",确认请求主体身份 --- 身份验证
  2. 鉴权(Authorization):确定"你能做什么",判定权限范围 --- 资源权限控制
  3. 准入控制(Admission Control):决定"是否允许该请求被接受",请求进一步校验 --- 二次验证

工作流程

  1. 客户端(如kubectl)向API Server发送请求
  2. 请求通过三重安全关卡(认证→鉴权→准入控制)
  3. 所有关卡通过后,API Server才处理该请求

2_认证Authentication

2.1_认证方式

认证方式:API Server支持的三种主要认证方式。

认证方式 实现原理 特点 核心作用
HTTP Token HTTP Header携带难以仿冒的长Token API Server维护Token与用户权限的映射。 授权访问特定API或资源
HTTP Basic Base64编码的用户名:密码放入Authorization字段 简单但安全性极低(密码明文传输,必须配合HTTPS) 最基础的身份验证
HTTPS证书 基于CA根证书签名的双向TLS认证 最严格,实现客户端与服务器的双向身份验证 建立通信双方的可信身份并加密通道

重要说明

  • Token与Basic认证仅支持服务端对客户端的单向认证
  • HTTPS证书认证可实现双向认证(客户端与服务端互相验证)

2.2_认证对象

需要被认证的访问类型

  • Kubernetes组件对API Server的访问:kubectl、kubelet、kube-proxy
  • 由Kubernetes管理的Pod对API Server的访问:coredns、dashboard等

端口与证书安全性

  • Controller Manager、Scheduler与API Server同机,常走非安全端口(如8080)
  • kubectl、kubelet、kube-proxy访问API Server需HTTPS双向认证,端口使用6443

2.3_证书管理

证书颁发方式

  • 手动签发:二进制部署时,需与CA手动签发HTTPS证书
  • 自动签发:kubelet首次访问用token认证,通过后由Controller Manager生成证书

kubeconfig:包含三类关键参数的配置文件

  • 集群参数:CA证书、API Server地址
  • 客户端参数:证书与私钥
  • 上下文参数:集群名、用户名、命名空间
  • kubectl默认位置:~/.kube/config

Service Account (SA):用于Pod中容器访问API Server的身份标识

  • 自动应对Pod动态创建/销毁场景
  • 无需为每个Pod单独发证书
  • 默认每个命名空间都有一个SA

2.4_Secret与SA的关系

Secret对象类型

  • service-account-token:保存ServiceAccount的令牌
  • Opaque:保存用户自定义的保密信息

Service Account组成

  • Token:API Server私钥签名的Token
  • ca.crt:CA根证书,验证API Server证书
  • namespace:service-account-token的命名空间作用域

默认行为

  • 若创建Pod时未指定SA,将使用所属命名空间的default SA

  • 系统自动将以下内容挂载到容器:

    复制代码
    /var/run/secrets/kubernetes.io/serviceaccount/
       ├── ca.crt
       ├── namespace
       └── token

小结

复制代码
k8s 安全机制  3关

认证  鉴权   准入控制

认证  

token 使用很长复杂的token(令牌)字符串 来做认证,通常是单向认证 

basic 使用账号 密码的格式通过 base64编码和解码来做认证  通常是单向的认证

https  使用CA机构签发的证书进行https认证 可以实现双向认证

k8s 认证  组件  (**Controller Manager、Scheduler** **kubectl、kubelet、kube-proxy** 等)与apiserver通信,是使用https证书认证,默认使用6443进行通信  (未知Scheduler   Controller  使用内部端口 8080  ),使用kubeconfig配置文件就知道使用什么证书连接到那个K8s的集群的APIserver 

pod 形式 的组件 (dashboad  coredns 外置存储常插件 比如 NFS provsisnor)与APIserver通信,使用serviceaccount作为pod服务的账号来访问APIserver   每个pod都会有 一个 serviceaccouint服务账号,可以创建pod资源时指定serviceaccouint字段

3_鉴权Authorization 重点

3.1_授权策略对比

授权策略 :API Server通过--authorization-mode参数配置。

策略 特点 适用场景
AlwaysDeny 拒绝所有请求 测试环境
AlwaysAllow 允许所有请求 无安全要求环境
ABAC(淘汰) 基于用户配置的属性的静态规则,繁琐需重启ApiServer。 简单权限需求
Webhook 外部REST服务鉴权,触发器钩子 统一外部认证系统
RBAC 基于角色的动态权限,细粒度,与资源模型一致。 生产环境默认(≥v1.6)

RBAC核心优势

  • 覆盖资源(Pod/Deployment/Service)与非资源(元信息/状态)
  • 由标准API资源对象构成,可用kubectl/API管理
  • 运行时可调整,无需重启API Server(ABAC需重启)

3.2_RBAC资源对象

① RBAC引入的四个顶级对象
Role

  • 命名空间级权限定义
  • 定义特定命名空间的权限
    ClusterRole
  • 集群级权限,跨命名空间。
  • 定义集体集群范围内的所有权限
    RoleBinding
  • 命名空间内将角色绑定到主体
  • 将Role或ClusterRole绑定到特定命名空间的主体
    ClusterRoleBinding
  • 集群级将角色绑定到主体
  • 将ClusterRole绑定到整个集群范围内的主体

② 绑定规则

  • RoleBinding可引用ClusterRole,但仍受命名空间限制
  • ClusterRoleBinding只能绑定ClusterRole作用于全集群

③ 权限控制模型

  • 仅能累加(白名单模型)
  • 不存在"先权限多再减少"的黑名单机制
  • Role仅限单一命名空间;ClusterRole可跨命名空间

3.3_角色与角色绑定

① 角色定义

  • Role:只定义在一个命名空间内的权限
  • ClusterRole:可定义跨多个命名空间的权限

Role示例(在default命名空间读取Pod):

yaml 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

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

yaml 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

② 角色绑定

  • RoleBinding:将Role/ClusterRole绑定到主体(User/Group/SA),限于命名空间
  • ClusterRoleBinding:在全集群范围绑定ClusterRole到主体

RoleBinding示例(将pod-reader绑定给jxc用户):

yaml 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: jxc
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

③ 主体(Subject)类型

  • User(用户)
  • Group(用户组)
  • ServiceAccount(服务账号)
  • 系统保留前缀:system:*(管理员应避免普通用户使用)

④ 资源(Resources)定义

  • K8s资源以名称字符串表示(如pods, services)
  • 子资源:如pods/log
  • API访问示例:GET /api/v1/namespaces/{namespace}/pods/{name}/log
  • 在RBAC中使用"资源/子资源"控制访问

④ 常见权限

  • verbs:get、list、watch、create、update、patch、delete、exec
  • resources:services、pods、secrets、configmaps等
  • apiGroups:""(core)、apps、autoscaling等

小结:

复制代码
1、角色(Role/clusterRole)

Role: 定义 特定的命名空间内的权限

clusterRole:定义整体集群范围内的所有权限

2、角色绑定 (RoleBinding/clusterRolebing)

RoleBinding:  将Role或clusterRole绑定到特定(单)的命名空间内的用户、组或服务账号

clusterRolebing:将clusterRole绑定到整个集群范围内的用户、组或服务账号

主体(subject):

用户 (User)   组(Group)    服务账号(SerivceAccount)

权限管理

RBAC   基于 白名单 机制   只能增加权限   无法通过RBAC 直接减少权限

resource

http  调用 一个方法   get   pull  put  

kubectl get pod    来获取 资源的信息  GET /api/v1/namespaces/pods

4_准入控制AdmissionControl

4.1_准入控制概述

Admission Control:API Server处理请求前的最后一道关卡。

工作机制

  • 一组插件链,请求依次通过该列表
  • 若任意插件拒绝,整个请求即被拒绝
  • 建议采用官方推荐的控制器组合

官方默认插件链

不同版本有所不同

复制代码
NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,NodeRestriction

4.2_关键插件功能

重点插件说明
NamespaceLifecycle

  • 命名空间生命周期管理
  • 阻止在不存在的命名空间创建对象
  • 阻止删除系统命名空间
  • 删除命名空间时级联清理

LimitRanger

  • 配额与限制管理
  • 确保请求不超过该命名空间的LimitRange

ServiceAccount

  • 为Pod自动注入ServiceAccount
  • 便于Pod访问API Server

ResourceQuota

  • 命名空间级高级配额
  • 确保不超过该命名空间的ResourceQuota

NodeRestriction

  • 限制Node加入集群后的权限
  • 遵循最小权限原则

官方文档https://kubernetes.io/zh/docs/reference/access-authn-authz/admission-controllers/

实验部分

1_创建仅能管理指定命名空间的用户

1.1_准备工作

① 创建系统用户
  • 创建操作系统层用户
shell 复制代码
useradd jxc
echo qwer1234 | passwd --stdin jxc
# 切换用户验证
su - jxc
kubectl get pods
ini 复制代码
The connection to the server localhost:8080 was refused - did you specify the right host or port?
连接到服务器 localhost:8080 被拒绝 - 您是否指定了正确的主机或端口?

useradd:创建系统用户
passwd:设置用户密码

jxc用户还未配置kubeconfig所以访问失败,为正常现象

1.2_生成证书与kubeconfig

① 上传证书工具
  • 从本地上传证书工具cfsslcfssljsoncfssl-certinfo到 Master节点主机的/usr/local/bin目录下
shell 复制代码
# user@localhost
scp cfssl cfssljson cfssl-certinfo root@k8s-master01:/usr/local/bin/

CFSSL工具链是用于简单快速创建和管理TLS证书的命令行工具集。
cfss:l是核心生成器
cfssljson:负责拆分证书文件
cfssl-certinfo:用于查看证书信息

RSA/ECC非对称加密工具

注释:RSA历史久远更常见,ECC更小更安全更现代。类似TLS是SSL的迭代产品。

工具 特点 适合场景
OpenSSL 老牌经典,功能全面,预装在多数系统 单次手动操作、故障排查、学习原理
CFSSL 现代,配置驱动,易于自动化 云平台、容器集群(如K8s)、需要批量签发证书
  • 并赋予执行权限
shell。 复制代码
# root@k8s-master
chmod +x /usr/local/bin/cfssl*
mkdir -p /opt/jxc && cd /opt/jxc

cfssl系列工具需提前安装并放置在PATH中

② 创建证书请求文件
shell 复制代码
# root@k8s-master01:/opt/jxc
vim user-cert.sh
bash 复制代码
#!/bin/bash
kube_user=jxc
cat > "$kube_user"-csr.json <<EOF
{
  "CN": "$kube_user",
  "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/$kube_user/"$kube_user"-csr.json | cfssljson -bare $kube_user

algo:algorithm(算法)的缩写
CN:作为User身份
names.O:作为Group身份(k8s)

API Server会将CN作为User,names.O作为Group
"hosts": []:用户认证不需要填写,服务器/节点/Pod认证才需要补全hosts信息(IP/域名)。后面会warning警告,不必理会。

  • 执行证书生成,会在/etc/kubernetes/pki/生成证书:jxc-key.pemjxc.pemjxc.csr
shell 复制代码
# root@k8s-master01:/opt/jxc
chmod +x user-cert.sh
./user-cert.sh
ls /opt/jxc /etc/kubernetes/pki/ | grep ^jxc
ini 复制代码
jxc.csr
jxc-key.pem
jxc.pem
jxc-csr.json

jxc-csr.json:生成证书的申请配置模板 ,里面填写了你的身份信息和需求。
jxc-key.pem:你的私钥 ,是绝不能泄露的核心秘密,用来证明你的身份并对CSR签名。
jxc.csr:根据配置和私钥生成的证书请求文件 ,包含你的公钥和信息,并由私钥签名(数字签名),提交给CA机构用于申请证书。
jxc.pem:CA机构颁发给你的正式证书,包含了你的公钥和CA的签名,是公开的身份凭证。

③ 生成kubeconfig
  • 创建kubeconfig生成脚本
shell 复制代码
vim rbac-kubeconfig.sh
bash 复制代码
#!/bin/bash
APISERVER=192.168.100.13	# 必须替换为实际API Server IP
kube_user=jxc	# 替换为🗺的kube用户
kube_namespace=yjs1023	# 替换为实际的命名空间

# 设置集群参数
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="$kube_user".kubeconfig

# 设置客户端认证参数
kubectl config set-credentials "$kube_user" \
  --client-key=/etc/kubernetes/pki/"$kube_user"-key.pem \
  --client-certificate=/etc/kubernetes/pki/"$kube_user".pem \
  --embed-certs=true \
  --kubeconfig="$kube_user".kubeconfig

# 设置上下文参数
kubectl config set-context kubernetes \
  --cluster=kubernetes \
  --user="$kube_user" \
  --namespace="$kube_namespace" \
  --kubeconfig="$kube_user".kubeconfig

# 使用上下文参数生成 .kubeconfig 文件
kubectl config use-context kubernetes --kubeconfig="$kube_user".kubeconfig

设置集群参数、客户端认证参数和上下文

  • 生成实际kubeconfig
shell 复制代码
chmod +x rbac-kubeconfig.sh
./rbac-kubeconfig.sh

生成jxc.kubeconfig文件

1.3_权限配置

① 创建命名空间与应用配置
  • 创建测试命名空间
shell 复制代码
kubectl create namespace yjs1023
  • 分发kubeconfig到用户目录
shell 复制代码
mkdir -p /home/jxc/.kube
cp jxc.kubeconfig /home/jxc/.kube/config
chown -R jxc:jxc /home/jxc/.kube/

使jxc用户能使用此配置文件

② 创建RBAC规则
  • 创建rbac.yaml权限配置文件
shell 复制代码
vim rbac.yaml
yaml 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: yjs1023
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list", "create"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: yjs1023
subjects:
- kind: User
  name: jxc
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

定义jxc在yjs1023命名空间的权限:

  • get/watch/list/create Pod
  • 应用RBAC配置
shell 复制代码
kubectl apply -f rbac.yaml
kubectl get role,rolebinding -n yjs1023
ini 复制代码
NAME                                        CREATED AT
role.rbac.authorization.k8s.io/pod-reader   2026-01-21T14:28:54Z

NAME                                              ROLE              AGE
rolebinding.rbac.authorization.k8s.io/read-pods   Role/pod-reader   28s

1.4_权限验证

① 验证jxc各项权限
  • 切换用户并创建测试Pod
shell 复制代码
su - jxc
cat > role-rolebinding-test.yaml <<'YAML'
apiVersion: v1
kind: Pod
metadata:
  name: role-rolebinding-test
spec:
  containers:
    - name: nginx
      image: nginx
YAML
kubectl create -f role-rolebinding-test.yaml
kubectl get pods -o wide

预期输出:role-rolebinding-test成功创建并运行

  • 测试跨命名空间访问
shell 复制代码
kubectl get pods -n default
ini 复制代码
Error from server (Forbidden): pods is forbidden: User "jxc" cannot list resource "pods" in API group "" in the namespace "default"

访问其他命名空间失败,权限受限

  • 测试其他资源访问
shell 复制代码
kubectl get svc
ini 复制代码
Error from server (Forbidden): services is forbidden: User "jxc" cannot list resource "services" in API group "" in the namespace "yjs1023"

无权限查看Service资源

② 管理员视角验证
  • root用户查看资源
shell 复制代码
# root@k8s-master
kubectl get pods --all-namespaces -o wide
ini 复制代码
NAMESPACE    NAME                 READY   STATUS    RESTARTS   AGE    IP            NODE         NOMINATED NODE   READINESS GATES
yjs1023   role-rolebinding-test   1/1     Running   0          5m2s   10.244.1.17   k8s-node01   <none>           <none>

确认RoleBinding已生效

  • 查看所有角色和绑定
shell 复制代码
kubectl get role,rolebinding -n yjs1023
③ 可选:授予管理员权限
  • 授予用户特定命名空间管理员权限
shell 复制代码
kubectl create rolebinding jxc-admin-binding \
  --clusterrole=admin \
  --user=jxc \
  --namespace=yjs1023

将集群admin角色绑定到用户,但限制在yjs1023命名空间

结语

复制代码
如果想要有让一个pod 或者 Serivce secert configmap等 /普通用户   具有 接入  k8s =集群相关资源的操作权限

1、创建serviceaccount  或者 用户

2、做认证   token/证书认证

​     ① serviceaccount 会自动 生成Serivceaccount  token 的 secret  资源

​     ② 用户需要创建证书,使用cfssl等工具通过CA证书和私钥文件  生成 证书和 私钥文件, 使用CA证书和私钥文件来去创建kubeconfig配置文件, 把kubeconfig配置文件导入用户的家目录中 目录名.kube/config文件中

3、做RBAC鉴权  Role|clusterRole 创建角色赋予给资源的操作权限(**resources**、verbs)  Rolebinding|cluster Rolebinding  把主体(用户|组|服务账号)和角色进行绑定

此时切换用户后pod 或者用户具有相关的命名空间的中对相关子资源有了操作权限

API Server安全:Kubernetes通过认证、鉴权和准入控制三道防线保护API Server;6443端口是安全访问的关键门户。

RBAC架构:基于Role/ClusterRole定义权限,通过RoleBinding/ClusterRoleBinding进行绑定;实现命名空间级精细权限控制。

安全最佳实践:最小权限原则,通过SA管理Pod访问权限;RBAC结合NetworkPolicy实现纵深防御。

!question\] 请问Kubernetes安全体系的三个环节分别是什么? 认证(确认身份)、鉴权(确认权限)、准入控制(请求验证), 请求必须经过这三道关卡才能被API Server处理 \[!question\] 为什么说RBAC是生产环境的推荐选择? RBAC支持运行时调整权限,无需重启API Server;通过标准API资源管理;支持命名空间级和集群级权限控制 \[!question\] ServiceAccount自动产生哪些内容? 自动挂载三个文件到容器:token(认证令牌)、ca.crt(API Server根证书)、namespace(命名空间信息) \[!question\] 如何限制用户只能在特定命名空间操作? 通过Role+RoleBinding组合:Role定义命名空间内权限,RoleBinding将角色绑定到特定用户 \[!question\] AlwaysAllow和AlwaysDeny策略适用于什么场景? AlwaysAllow用于无安全要求或测试场景;AlwaysDeny用于安全测试,模拟拒绝所有请求环境

相关推荐
fanruitian2 小时前
centos 安装minikube
docker·kubernetes·centos
Justin_192 小时前
K8s常见问题(4)
云原生·容器·kubernetes
噎住佩奇2 小时前
单节点 K8s 集群上部署 Longhorn
云原生·容器·kubernetes
编码如写诗2 小时前
【信创-k8s】麒麟V11使用containerd2.1.5全离线安装k8s1.32.11+KubeSphere
云原生·容器·kubernetes
徐先生 @_@|||2 小时前
YARN、YARN/K8s混合模式与Kubernetes分析对比
docker·云原生·容器·kubernetes
合新通信 | 让光不负所托3 小时前
边缘计算节点空间受限,用浸没式液冷光模块能同时满足小型化和高性能需求吗?
大数据·人工智能·阿里云·云计算·边缘计算
China_Yanhy3 小时前
生产级 Amazon MSK (Express 模式) 架构构建与选型实战白皮书
架构·kafka·云计算·aws
Justin_193 小时前
K8s常见问题(5)
云原生·容器·kubernetes
Thomas21433 小时前
jupyterhub on k8s jupyter总是无响应
jupyter·容器·kubernetes