Lazy loaded image
运维管理
k8s API 安全访问:认证, 鉴权, 准入控制, TLS, RBAC
Words 7104Read Time 18 min
2025-12-8
2025-12-8
date
related_level
slug
k8s_api_security
type
Post
relate_date
summary
介绍 Kubernetes API 访问的安全机制,涵盖认证、鉴权和准入控制三个核心环节
status
Published
tags
k8s
安全
category
运维管理
last_updated
Dec 8, 2025 09:51 AM
是否已更新
orginal_page
是否推荐
 

k8s API 组

参考资料
API 端点分为核心 API 端点 /api 和扩展 API 端点 /apis
  • 核心 API 端点 /api 包含 v1 版本的核心资源
    • 没有以 group 的形式组织,如
      kubectl get --raw /api/v1 | jq '.resources[].name'
  • 扩展 API 端点 /apis 包含核心 API 以外的所有其他 API group 且支持 CRD
    • 以 group 的形式组织,如 Deployment 资源属于 app group
      会包括一些核心功能之外的新特性
      notion image
    • kubectl get --raw /apis | jq '.groups[].name'
API 版本
参考资料
  • API 命名 <group>/<version>
k8s API 版本格式:v<num>[alpha|beta][num]
  • 版本以 v 开头跟一个数字,一个可选的 beta 或者 alpha 和一个可选的附加数字作为版本信息
三种版本体系:vXalphaY, vXbetaY, vX
  • vXalphaY 为试验版本,默认关闭
    • 需要配置特性门控开启
    • 升级可能不兼容
  • vXbetaY 为测试版本,默认开启
    • 一般向后兼容
  • vX 为正式版本,默认开启,可用于生产环境
    • 向后兼容
版本优先级和排序
  • 通过解析 name 字段来确定版本号、稳定性(GA、Beta 或 Alpha) 以及该稳定性级别内的序列
排序规则
  • 遵循 Kubernetes 版本模式的条目在不符合条件的条目之前进行排序
  • 对于遵循 Kubernetes 版本模式的条目,版本字符串的数字部分从最大到最小排序
  • 如果第一个数字后面有字符串 beta 或 alpha,它们首先按去掉 beta 或 alpha 之后的版本号排序(相当于 GA 版本),之后按 beta 先、alpha 后的顺序排序
  • 如果 beta 或 alpha 之后还有另一个数字,那么也会针对这些数字从大到小排序
  • 不符合上述格式的字符串按字母顺序排序,数字部分不经过特殊处理
排序从大到小的样例
首选版本和存储版本
  • 一般资源对象在 API 服务器中会有多个版本同时存在
    • etcd 只存储一个版本
  • Kubernetes API Server 对外展示的默认版本即为首选版本
    • 通常和存储版本一致,但没有要求必须一致
  • Kubernetes 内部在 etcd 中实际存储的资源对象版本即为存储版本
    • kubectl 当前无法查看存储版本,只能通过 etcdctl 查看
kubectl proxy 和 curl 查看首选版本
  • kubectl proxy 8001&
  • curl localhost:8001/apis/authorization.k8s.io | jq '.preferredVersion.version'
  • fg
    • Ctrl+C 终止
设置存储版本:spec.versions[].storage: true
  • 如果没有设置存储版本则无法决定如何序列化到 etcd
  • 多个版本的 CR 可以序列化存储在 etcd 会导致数据不一致
API 弃用原则
  1. 只能在新增 API 组版本时删除元素
      • 已存在版本的 API 元素不可随意删除或大幅改动。
  1. 版本间对象可双向转换
      • 对象在不同 API 版本间读写时必须能还原,避免信息丢失。
      • 新字段需提供等效字段或注解以保持兼容。
  1. 弃用顺序遵循稳定性级别
      • GA(正式)API 可替换 Beta/Alpha。
      • Beta 可替换早期 Beta/Alpha,但不替换 GA。
      • Alpha 可替换早期 Alpha,但不替换 Beta/GA。
  1. API 生命周期由稳定性级别决定
      • GA:可标记弃用,但不会在主要版本中删除
      • Beta:引入后 ≤9 个月或 ≤3 个次要版本可弃用,并在弃用后 9 个月或 3 个次要版本停止支持
      • Alpha:可随时删除,不另行通知
  1. 存储版本与首选版本限制
      • 标记为 preferred 或存储版本的 API,不可在支持老版本的发布版本中提升版本号
      • 用户升级或回滚时,应保持数据兼容和功能不损坏
设置版本弃用:spec.versions[].served
  • 禁用对应版本 API
设置版本废除:spec.versions[].deprecatedspec.versions[].deprecationWarning
kubectl convert 进行核心 API 版本转换
kubectl 需要安装 kubectl-convert 插件
  • curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl-convert"
    • amd64
  • curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl-convert.sha256"
    • 可选,验证文件完整性
    • echo "$(cat kubectl-convert.sha256) kubectl-convert" | sha256sum --check
  • sudo install -o root -g root -m 0755 kubectl-convert /usr/local/bin/kubectl-convert
  • kubectl convert -f FILENAME [options]
    • --output-version 指定转换版本,默认为 latest
CRD API 版本转换
设置 kube-apiserver --runtime-config 启用或禁用 API 组
  • 修改后需要重启 API 服务器和控制器管理器
  • 禁用 batch/v1
    • --runtime-config=batch/v1=false
  • 启用 batch/v2alpha1
    • --runtime-config=batch/v2alpha1
  • 启用特定版本的 API
    • --runtime-config=storage.k8s.io/v1beta1/csistoragecapacities
kubectl 列出所有支持的资源类型和 API 组 api-resources
  • kubectl api-resources -o wide
  • kubectl api-resources --verbs=list,get
    • 所有支持 list,get 的资源
如何通过 curl 直接访问 k8s api
  • kubectl proxy
    • curl 缺乏认证,通过 kubectl proxy 代理访问
    • 默认在本地 8001 端口开启
  • curl http://localhost:8001
  • 或者 curl https://localhost:6443 手动添加 --cacert, --cert, --key
 

k8s TLS 证书

参考资料
各组件 TLS 证书
外部 CA 机构
  • ca.crt & ca.key
  • 所有部件均需要添加 ca.crt 到根证书库用于信任 CA 签发的证书
etcd
  • etcdserver.crt & etcdserver.key
  • etcd-peer1.crt & etcd-peer1.key
  • etcd-peer2.crt & etcd-peer2.key
kube-api server
  • apiserver.crt & apiserver.key
    • DNS.1: kubernetes
    • DNS.2: kubernetes.default
    • DNS.3: kubernetes.default.svc
  • apiserver-etcd-client.crt & apiserver-etcd-client.key
    • 与 etcd 进行 mtls 身份验证的客户端证书
  • apiserver-kubelet-client.crt & apiserver-kubelet-client.key
    • 与 kubelet 进行 mtls 身份验证的客户端证书
    • O: system:masters
    • O: kubeadm:cluster-admins
      • kubeadm 使用的权限组
kubelet server
  • kubelet.crt & kubelet.key
    • subject: system:node:<node-name>
    • O: system:nodes
  • kubelet-client.crt & kubelet-client.key
    • 与 api-server 进行 mtls 身份验证的客户端证书
kube scheduler
  • scheduler.crt & scheduler.key
    • 与 api-server 进行 mtls 身份验证的客户端证书
kube-controller-manager
  • controller-manager.crt & controller-manager.key
    • 与 api-server 进行 mtls 身份验证的客户端证书
kube-proxy
  • kube-proxy.crt & kube-proxy.key
    • 与 api-server 进行 mtls 身份验证的客户端证书
kubectl
  • client.crt & client.key
    • 与 api-server 进行 mtls 身份验证的客户端证书
kubeadm 使用 TLS 证书详细一览
需要以下证书
默认 CN
父级 CA
O(位于 Subject 中)
kind
主机(SAN)
kube-etcd
etcd-ca
server、client
<hostname><Host_IP>localhost127.0.0.1
kube-etcd-peer
etcd-ca
server、client
<hostname><Host_IP>localhost127.0.0.1
kube-etcd-healthcheck-client
etcd-ca
client
kube-apiserver-etcd-client
etcd-ca
client
kube-apiserver
kubernetes-ca
server
<hostname><Host_IP><advertise_IP>1
kube-apiserver-kubelet-client
kubernetes-ca
system:masters
client
front-proxy-client
kubernetes-front-proxy-ca
client
证书路径
默认 CN
建议的密钥路径
建议的证书路径
命令
密钥参数
证书参数
etcd-ca
etcd/ca.key
etcd/ca.crt
kube-apiserver
--etcd-cafile
kube-apiserver-etcd-client
apiserver-etcd-client.key
apiserver-etcd-client.crt
kube-apiserver
--etcd-keyfile
--etcd-certfile
kubernetes-ca
ca.key
ca.crt
kube-apiserver
--client-ca-file
kubernetes-ca
ca.key
ca.crt
kube-controller-manager
--cluster-signing-key-file
--client-ca-file, --root-ca-file, --cluster-signing-cert-file
kube-apiserver
apiserver.key
apiserver.crt
kube-apiserver
--tls-private-key-file
--tls-cert-file
kube-apiserver-kubelet-client
apiserver-kubelet-client.key
apiserver-kubelet-client.crt
kube-apiserver
--kubelet-client-key
--kubelet-client-certificate
front-proxy-ca
front-proxy-ca.key
front-proxy-ca.crt
kube-apiserver
--requestheader-client-ca-file
front-proxy-ca
front-proxy-ca.key
front-proxy-ca.crt
kube-controller-manager
--requestheader-client-ca-file
front-proxy-client
front-proxy-client.key
front-proxy-client.crt
kube-apiserver
--proxy-client-key-file
--proxy-client-cert-file
etcd-ca
etcd/ca.key
etcd/ca.crt
etcd
--trusted-ca-file, --peer-trusted-ca-file
kube-etcd
etcd/server.key
etcd/server.crt
etcd
--key-file
--cert-file
kube-etcd-peer
etcd/peer.key
etcd/peer.crt
etcd
--peer-key-file
--peer-cert-file
etcd-ca
etcd/ca.crt
etcdctl
--cacert
kube-etcd-healthcheck-client
etcd/healthcheck-client.key
etcd/healthcheck-client.crt
etcdctl
--key
--cert
notion image
k8s 证书签名请求(CertificateSigningRequest, CSR)
参考资料
与集群内证书相关操作由 kube-controller-manager 处理
  • 具有 CSR-APPROVING, CSR-SIGNING 控制器
  • 可以指定签署证书的 CA
    • --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt
    • --cluster-signing-key-file=/etc/kubernetes/pki/ca.key
证书签名鉴权:需要能创建, 检索, 批准和签署 CSR 的 ClusterRole
  • vim access/certificate-signing-request/clusterrole.yaml
k8s 提供了一些内置 signer
  • signerName
    • kubernetes.io/kube-apiserver-client
    • kubernetes.io/kube-apiserver-client-kubelet
    • kubernetes.io/kube-serving
    • kubernetes.io/legacy-unknown
创建 k8s CertificateSigningRequest 对象
  • openssl genrsa -out myuser.key 3072
  • openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser"
    • 使用私钥生成 CSR 文件
    • k8s 中的证书 subject 是用户名称,O 是用户所属的群组
  • cat << EOF | kubectl apply -f - apiVersion: certificates.k8s.io/v1 kind: CertificateSigningRequest metadata: name: myuser-csr spec: request: $(cat myuser.csr | base64 -w 0) signerName: kubernetes.io/kube-apiserver-client expirationSeconds: 86400 # 一天 usages: - client auth EOF
批准 CSR 并查看证书
  • kubectl get csr
  • kubectl certificate approve myuser-csr
    • myuser-csr 为之前创建的 CSR 对象名称
  • 如果需要拒绝
    • kubectl certificate deny myuser-csr
  • kubectl get csr/myuser-csr -o yaml
    • groups 代表权限组
  • kubectl get csr/myuser-csr -o jsonpath='{.status.certificate}' | base64 -d
    • 签发后证书值以 Base64 编码格式显示在 .status.certificate 下
配置证书到 kubeconfig
  • kubectl get csr/myuser-csr -o jsonpath='{.status.certificate}' | base64 -d > myuser.crt
  • kubectl config set-credentials myuser --client-key=myuser.key --client-certificate=myuser.crt --embed-certs=true
  • kubectl config set-context myuser --cluster=kubernetes --user=myuser
    • 添加上下文
  • kubectl --context myuser auth whoami
    • 测试
  • kubectl auth whoami
可选:创建 Role 和 RoleBinding
  • kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods
  • kubectl create rolebinding developer-binding-myuser --role=developer --user=myuser
 

k8s 认证和权限控制

  • API 请求处理流程:认证(Authentication) → 鉴权(authorization) → 准入控制(Admission Control) → 持久化到 etcd
k8s 中的用户以及用户认证
  • 用户认证验证 API 请求是否来自特定请求者
    • 所有通过身份认证的用户,system:authenticated 组都会被添加到其组列表中
两类用户:由 Kubernetes 管理的 ServiceAccount 和普通 User
  • 普通 User 由集群外部系统管理(如管理员分发的证书、OIDC 身份提供商、用户名/密码文件等)
    • Kubernetes 不存储普通用户的信息,也没有对应的 API 对象
  • ServiceAccount 由 Kubernetes API 自身管理,其凭据以 Secret 形式保存,并自动挂载到 Pod 中,供集群内进程访问 API
所有 API 请求都关联以下身份之一
  • 某个普通用户
  • 某个服务账号
  • 匿名用户(未认证时)
    • 默认启用
    • 获得用户名 system:anonymous 和对应的用户组 system:unauthenticated
    • 为用户 * 或用户组 * 赋予访问权限的策略规则并不包含匿名用户
当向 API 服务器发出 HTTP 请求时,身份验证插件会尝试将以下属性与请求关联起来
  • 用户名
    • 证书验证中,Subject CommonName 字段作为用户名
  • UID
  • 用户组 User Groups
    • 证书验证中,O(Organization)字段作为所属组
    • OIDC Token 中,groups 声明作为用户组
    • Webhook 中,X-Remote-Group 表头作为用户组
  • 附加字段
k8s 中的用户组对字符串没有格式要求, 只是不能使用保留的前缀 system:
  • 前缀 system: 是 Kubernetes 系统保留
  • (复数)system:serviceaccounts: 是用于服务账户组名的前缀
    • 服务账户用户名的前缀为单数 system:serviceaccount:
一些常见内置用户名和用户组名
身份认证策略
  • Kubernetes 通过身份认证插件来认证 API 请求的身份
  • 可以同时启用多种身份认证方法,并且通常会至少使用两种方法
    • 针对服务账号使用服务账号令牌
    • 至少另外一种方法对用户的身份进行认证
  • 主要身份认证策略
    • basic auth 静态密码文件
      • API 服务器会从文件中读取密码信息
        • --basic-auth-file=SOMEFILE.csv
      • 文件内容格式
        • passwd1,user1,uid1,"group1,group2,group3"
          • group 组名信息可选
      • 可以在请求中添加 basic auth 认证信息
        • curl -u "user1:passwd1"
      • 长期有效,并且在不重启 API 服务器的情况下无法更改
      静态令牌文件
      • API 服务器会从文件中读取持有者令牌
        • --token-auth-file=SOMEFILE.csv
      • 文件内容格式
        • token,user,uid,"group1,group2,group3"
          • group 组名信息可选
      • 可以在请求中放入持有者令牌
        • curl --header "Authorization: Bearer <token>"
      • 长期有效,并且在不重启 API 服务器的情况下无法更改令牌列表
      X.509 客户端证书
      • 用户持有由集群 CA 签发的客户端证书
      • Common Name 被作为请求的用户名
      • 可以通过证书的 organization 字段标明用户的组成员信息
      启动引导令牌(Bootstrap Tokens)
      • 仅用于节点加入集群(如 kubeadm join
      ServiceAccount 令牌(JWT)
      • Pod 自动挂载由 K8s 签发的 JWT Token(存储在 Secret 中)
      OpenID Connect(OIDC)令牌
      • 集成外部身份提供商
      Webhook 令牌认证
      • 用来验证持有者令牌的回调机制
      • API Server 将 Token 转发给外部 Webhook 服务验证
k8s 服务账户
服务账号具有以下属性
  • 名字空间限定: 每个服务账号都与一个 Kubernetes 名字空间绑定
    • 每个名字空间在创建时,会获得一个名为 default 的 ServiceAccount
    • 用户账户是全局性的
  • 轻量级: 服务账号存在于集群中,并在 Kubernetes API 中定义
  • 可移植性: 复杂的容器化工作负载的配置包中可能包括针对系统组件的服务账号定义。 服务账号的轻量级性质和名字空间作用域的身份使得这类配置可移植。
服务账号与用户账号的区别
  • 用户账号是集群中通过了身份认证的人类用户,不存在于 Kubernetes API 服务器中
  • 服务账号存在于集群中,并在 Kubernetes API 中定义
描述
服务账号
用户或组
位置
Kubernetes API(ServiceAccount 对象)
外部
访问控制
Kubernetes RBAC 或其他鉴权机制
Kubernetes RBAC 或其他身份和访问管理机制
目标用途
工作负载、自动化工具
服务账号使用场景
  • Pod 需要与 Kubernetes API 服务器通信
  • Pod 需要与外部服务进行通信
  • 使用 imagePullSecret 完成在私有镜像仓库上的身份认证
  • 外部服务需要与 Kubernetes API 服务器进行通信
  • 在集群中使用了第三方安全软件,该软件依赖不同 Pod 的 ServiceAccount 身份,按不同上下文对这些 Pod 分组
服务账户授权和令牌类型
  • 要使用服务账户,需要使用鉴权机制(如 RBAC)进行授权并指派给 Pod
    • kubernetes 1.24 之后不再默认为新建的服务账户创建令牌
服务账户令牌代表 Pod 或应用的身份
  • 在创建集群时,Kubernetes 会自动为集群中的每个名字空间创建一个名为 default 的 ServiceAccount 对象
    • 该服务账户权限仅限于默认 API 发现权限
  • 如果没有为 pod 手动指派 ServiceAccount,Kubernetes 会自动将当前命名空间中 default 的 ServiceAccount 指派给该 pod
服务账户令牌类型
  • TokenRequest API(推荐)
    • 在 Pod 中请求一个短期的服务账号令牌
    • 此令牌会自动过期,并可在过期时被轮换
  • 令牌卷投射(推荐)
    • 使用 Pod 规约告知 kubelet 将服务账号令牌作为投射卷添加到 Pod 中
    • 所投射的令牌会自动过期,在过期之前 kubelet 会自动轮换此令牌
  • 服务账号令牌 Secret(不推荐)
    • 将服务账号令牌以 Kubernetes Secret 的形式挂载到 Pod 中
    • 这些令牌不会过期且不会轮换
创建 kubernetes.io/service-account-token 类型 Secret 作为长期有效的令牌
  • 需要对应服务账户已经存在
  • kubectl apply -f - <<EOF apiVersion: v1 kind: Secret metadata: name: build-robot-secret annotations: kubernetes.io/service-account.name: build-robot type: kubernetes.io/service-account-token EOF
将 ServiceAccount 令牌投射到 Pod 中
  • 可以指定令牌的期望属性, 例如 audience 和 expirationSeconds
    • 这些属性在 default ServiceAccount 令牌上无法配置
手动指派服务账户给 pod
  • 设置 pod 的 spec.serviceAccountName 字段为对应命名空间的 ServiceAccount 对象
  • 默认情况下,Kubernetes 会将所指派的 ServiceAccount 的令牌提供给 Pod
    • 可以通过 automountServiceAccountToken 字段设置为 false 来忽略
可以通过 RoleBinding 绑定 ServiceAccount 进行跨名字空间访问
  • 在 monitoring 命名空间中创建 Role 和 RoleBinding 但绑定 default 命名空间中的服务账户
  • 指派了该服务账户的 pod 可以通过 ServiceAccount 执行 monitoring 命名空间下的 Role 授权范围内的操作
为服务账号添加 ImagePullSecrets 拉取私有镜像库镜像
  • 创建 ImagePullSecrets
    • kubectl create secret docker-registry myregistrykey \ --docker-server=<registry name> \ --docker-username=DUMMY_USERNAME \ --docker-password=DUMMY_DOCKER_PASSWORD\ --docker-email=DUMMY_DOCKER_EMAIL
  • 假设 pod 未指派特定服务账户,添加到 default 服务账户
    • kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}'
      • 如果有指派,对应替换 default 即可
鉴权检查 API 请求用户是否有权限执行当前操作
  • API 请求的所有部分都必须通过某种鉴权机制才能继续
    • 即默认情况下拒绝访问
  • 当系统配置了多个鉴权模块时,Kubernetes 将按顺序使用每个模块
    • kube-apiserver 设置 --authorization-mode=Node,RBAC,Webhook 将顺序使用
      • 前一个拒绝后会转给后续模块继续处理,任一通过后续则不会再检查
可选鉴权模式
  • AlwaysAllow
  • AlwaysDeny
  • ABAC(基于属性的访问控制)
  • RBAC(基于角色的访问控制)
  • Webhook
RBAC(Role-Based Access Control)控制 User/ServiceAccount 可以对哪些资源执行什么操作
参考资料
RBAC 工作原理
  1. 用户或 Pod(通过 ServiceAccount)发起 API 请求(如 kubectl create pod
  1. (认证)API Server 验证身份
  1. (鉴权)RBAC 引擎检查该身份是否有权限执行此操作(基于绑定的角色)
  1. 若无权限 → 返回 403 Forbidden
Role 和 ClusterRole 包含一组代表相关权限的规则(rule)
Role 用来在某个命名空间内设置访问权限
ClusterRole 作用于整个集群,可以授予以下权限
  • 所有命名空间中的资源(如 pods、deployments)
  • 集群级资源(如 nodes、namespaces、pv、clusterroles)
  • 非资源端点(如 /healthz/metrics
role 通过 rules 字段限定引用资源
  • 支持 resources、apiGroups 和 verbs 对象
apiGroups 常见取值
含义
示例 resouces
""(空字符串)
核心 API 组
pods, services, configmaps, nodes
"apps"
应用相关资源
deployments, statefulsets, daemonsets
"batch"
批处理任务
jobs, cronjobs
"networking.k8s.io"
网络策略
ingresses, networkpolicies
"rbac.authorization.k8s.io"
RBAC 资源
roles, clusterroles, rolebindings
"*"
所有 API 组
verbs 常见取值
动词
说明
get
获取单个资源
list
列出某类资源(命名空间内或集群级)
watch
监听资源变更(流式)
create
创建资源
update
更新已有资源(全量替换)
patch
部分更新资源(推荐用于控制器)
delete
删除单个资源
deletecollection
删除整个资源集合(如 kubectl delete pods --all
impersonate
模拟其他用户或组
bind / escalate
特定于 RBAC 资源的权限(如绑定角色、提升权限)
利用 / 分割资源和子资源
  • GET /api/v1/namespaces/{namespace}/pods/{name}/log
  • 允许读取并访问 pod 的 log 子资源
限定 resourceNames 引用特定名称的资源
  • 限制可以 get 和 update 一个名为 my-configmap 的 ConfigMap
  • 对于 resourceNames,空集表示没有任何限制
通配符 * 引用
  • 批量引用所有的 resourcesapiGroups 和 verbs 对象
  • 对于 resourceNames,空集表示没有任何限制
nonResourceURLs 限定非资源类 API 路径的访问权限
  • 通常用于监控系统(如 Prometheus)或健康检查工具
角色绑定(Role Binding)是将 role 中定义的权限赋予一个或者一组主体(subject)
  • 主体可以是用户、组或服务账户
  • RoleBinding 在指定的名字空间中执行授权
    • RoleBinding 可以引用某 ClusterRole 并将该 ClusterRole 绑定到 RoleBinding 所在的名字空间
  • ClusterRoleBinding 在集群范围执行授权
    • 如果希望将某 ClusterRole 绑定到集群中所有名字空间,则要使用 ClusterRoleBinding
创建了绑定之后,你不能再修改绑定对象所引用的 Role 或 ClusterRole
  • 试图改变绑定对象的 roleRef 将导致合法性检查错误
  • 改变现有绑定对象中 roleRef 字段的内容,必须删除重新创建绑定对象
    • 通过 kubectl auth reconcile 可以创建或者更新包含 RBAC 对象的清单文件, 并且在必要的情况下删除和重新创建绑定对象,以改变所引用的角色
声明式设置 RBAC 示例
  • Role 示例
    • pod-reader
  • ClusterRole 示例
    • secret-reader
  • RoleBinding 示例
    • read-pods
      read-secrets
  • ClusterRoleBinding 示例
    • read-secrets-global
kubectl 创建 RBAC 资源
  • kubectl create serviceaccount dashboard-sa
    • 创建 serviceaccount
  • kubectl create token dashboard-sa
    • 创建 token,令牌名称要和 serviceaccount 对应
    • --duration 延长令牌有效期
  • kubectl create role <name> -n <namespace> --verb=get,list,watch --resource=pods,pods/status
    • 创建 role
    • clusterole 同理但不需要添加 namespace
    • --resource-name=readablepod 进一步限定 resource 的名称为 readablepod
  • kubectl create rolebinding <name> -n <namespace> --role=admin --user=user1 --user=user2 --group=group1
    • 创建 rolebinding
    • 指定不同类型 subject --user, --group, --serviceaccount=<namespace:serviceaccountname>
    • --clusterrole=clusteradmin 绑定 clusterrole 而非 role
准入控制用于在对象被创建(create)/更新(update, patch)/删除(delete)前,验证或修改其内容
  • 准入控制器不会(也不能)阻止读取(get, watch, list)对象的请求
    • 读取操作会绕过准入控制层
  • 准入控制器机制可以执行验证(Validating) 和/或变更(Mutating) 操作
    • 变更(Mutating)控制器可以为正在修改的资源修改数据
工作原理
  1. 请求通过认证和 RBAC 授权。
  1. 进入 准入控制器链
  1. 多个准入插件依次处理请求:
      • 先运行 Mutating(变更)准入控制器:自动修改对象(如 DefaultStorageClass、LimitRanger)
      • 再运行 Validating(验证)准入控制器:检查是否合法(如 ResourceQuota、PodSecurity)
      • 如果先执行验证的话,如同时启用 NamespaceAutoProvision 和 NamespaceExists 的情况下,用于创建缺失命名空间的 NamespaceAutoProvision 将永远无法生效
  1. 任一验证失败 → 拒绝请求;变更型会修改对象后再继续
kube-apiserver 启用/禁用某个准入控制器
  • 以裸机服务形式执行 kube-apiserver
    • kube-apiserver \ --enable-admission-plugins=<ad-plugin1>,<ad-plugin2>,... \ --disable-admission-plugins=<ad-plugin1>,<ad-plugin2>,...
  • 如果是 staticpod 部署的话修改 kube-apiserver 配置文件
    • vim /etc/kubernetes/manifests/kube-apiserver.yaml
查看默认启用的准入控制器列表
  • kube-apiserver -h | grep enable-admission-plugins
  • cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep enable-admission-plugins
  • kubectl exec -n kube-system kube-apiserver-controlplane -- \ kube-apiserver -h | grep enable-admission-plugins
一些内置准入控制器样例
  • DefaultStorageClass
    • 变更型,为 PVC 自动设置默认 StorageClass
  • LimitRanger
    • 变更和验证型,确保请求不会违反 Namespace 中 LimitRange 对象所设置的任何约束并为 Pod 设置默认 CPU/Memory requests/limits
  • NamespaceLifecycle
    • 验证型,正在终止的命名空间不能创建新对象,并确保拒绝不存在的命名空间中的请求,防止删除三个系统保留命名空间 default、kube-system、kube-public
  • ResourceQuota
    • 验证型,检查命名空间资源配额是否超限
  • PodSecurity
    • 替代了 PSP (PodSecurityPolicy)
    • 验证型,强制执行 Pod 安全标准(如禁止特权容器)
  • OwnerReferencesPermissionEnforcement
    • 验证型,防止不具备对该对象具有 delete 权限的用户设置 metadata.ownerReference
动态准入控制 Webhook:MutatingAdmissionWebhook, ValidatingAdmissionWebhook
  • 参考资料
    • KubernetesKubernetes动态准入控制
    • https://www.qikqiak.com/post/k8s-admission-webhook/
  • 准入 Webhook 是一种用于接收准入请求并对其进行处理的 HTTP 回调机制
  • 同样可以执行验证(Validating) 和/或变更(Mutating) 操作
    • 先调用变更性质的准入 Webhook 再调用验证准入 Webhook
Webhook server 样例
  • 可以在集群内部署容器也可以在外部以服务形式提供
  • 官方
  • 带 TLS 认证的 HTTP 服务
验证准入 Webhook 配置样例
  • rules 段参考准入控制器即可
如果是外部服务需要修改 clientConfig 提供 url
准入 Webhook 配置身份验证
  • kube-apiserver 需要配置 --admission-control-config-file 参数指定准入控制配置文件的位置
configuration.kubeConfigFile 指定 Webhook 控制器读取凭据的位置
在 kubeConfig 文件中,提供证书凭据
 
 
上一篇
Linux 包管理器
下一篇
k8s 原生网络管理简介

Comments
Loading...