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 kubectl get --raw /apis | jq '.groups[].name'
以 group 的形式组织,如 Deployment 资源属于 app group
会包括一些核心功能之外的新特性

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 弃用原则
- 只能在新增 API 组版本时删除元素
- 已存在版本的 API 元素不可随意删除或大幅改动。
- 版本间对象可双向转换
- 对象在不同 API 版本间读写时必须能还原,避免信息丢失。
- 新字段需提供等效字段或注解以保持兼容。
- 弃用顺序遵循稳定性级别
- GA(正式)API 可替换 Beta/Alpha。
- Beta 可替换早期 Beta/Alpha,但不替换 GA。
- Alpha 可替换早期 Alpha,但不替换 Beta/GA。
- API 生命周期由稳定性级别决定
- GA:可标记弃用,但不会在主要版本中删除
- Beta:引入后 ≤9 个月或 ≤3 个次要版本可弃用,并在弃用后 9 个月或 3 个次要版本停止支持
- Alpha:可随时删除,不另行通知
- 存储版本与首选版本限制
- 标记为 preferred 或存储版本的 API,不可在支持老版本的发布版本中提升版本号
- 用户升级或回滚时,应保持数据兼容和功能不损坏
设置版本弃用:spec.versions[].served
- 禁用对应版本 API
设置版本废除:spec.versions[].deprecated 和 spec.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
设置 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>、localhost、127.0.0.1 |
kube-etcd-peer | etcd-ca | ㅤ | server、client | <hostname>、<Host_IP>、localhost、127.0.0.1 |
kube-etcd-healthcheck-client | etcd-ca | ㅤ | client | ㅤ |
kube-apiserver-etcd-client | etcd-ca | ㅤ | client | ㅤ |
kube-apiserver | kubernetes-ca | ㅤ | server | |
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 |

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-clientkubernetes.io/kube-apiserver-client-kubeletkubernetes.io/kube-servingkubernetes.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-csrmyuser-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 请求的身份
- 可以同时启用多种身份认证方法,并且通常会至少使用两种方法
- 针对服务账号使用服务账号令牌
- 至少另外一种方法对用户的身份进行认证
- 主要身份认证策略
- 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 服务器的情况下无法更改令牌列表
- 用户持有由集群 CA 签发的客户端证书
- Common Name 被作为请求的用户名
- 可以通过证书的 organization 字段标明用户的组成员信息
- 仅用于节点加入集群(如
kubeadm join) - Pod 自动挂载由 K8s 签发的 JWT Token(存储在 Secret 中)
- 集成外部身份提供商
- 用来验证持有者令牌的回调机制
- API Server 将 Token 转发给外部 Webhook 服务验证
basic auth 静态密码文件
静态令牌文件
X.509 客户端证书
启动引导令牌(Bootstrap Tokens)
ServiceAccount 令牌(JWT)
OpenID Connect(OIDC)令牌
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(基于角色的访问控制)
- Node
- 专门对 kubelet 发出的 API 请求进行授权
- https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/node/
- Webhook
RBAC(Role-Based Access Control)控制 User/ServiceAccount 可以对哪些资源执行什么操作
RBAC 工作原理
- 用户或 Pod(通过 ServiceAccount)发起 API 请求(如
kubectl create pod)
- (认证)API Server 验证身份
- (鉴权)RBAC 引擎检查该身份是否有权限执行此操作(基于绑定的角色)
- 若无权限 → 返回
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,空集表示没有任何限制
通配符 * 引用
- 批量引用所有的
resources、apiGroups和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)控制器可以为正在修改的资源修改数据
工作原理
- 请求通过认证和 RBAC 授权。
- 进入 准入控制器链
- 多个准入插件依次处理请求:
- 先运行 Mutating(变更)准入控制器:自动修改对象(如 DefaultStorageClass、LimitRanger)
- 再运行 Validating(验证)准入控制器:检查是否合法(如 ResourceQuota、PodSecurity)
- 如果先执行验证的话,如同时启用 NamespaceAutoProvision 和 NamespaceExists 的情况下,用于创建缺失命名空间的 NamespaceAutoProvision 将永远无法生效
- 任一验证失败 → 拒绝请求;变更型会修改对象后再继续
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
- 参考资料
Kubernetes动态准入控制
动态准入控制
除了内置的 admission 插件, 准入插件可以作为扩展独立开发,并以运行时所配置的 Webhook 的形式运行。 此页面描述了如何构建、配置、使用和监视准入 Webhook。 什么是准入 Webhook? 准入 Webhook 是一种用于接收准入请求并对其进行处理的 HTTP 回调机制。 可以定义两种类型的准入 Webhook, 即验证性质的准入 Webhook 和变更性质的准入 Webhook。 变更性质的准入 Webhook 会先被调用。它们可以修改发送到 API 服务器的对象以执行自定义的设置默认值操作。 在完成了所有对象修改并且 API 服务器也验证了所传入的对象之后, 验证性质的 Webhook 会被调用,并通过拒绝请求的方式来强制实施自定义的策略。 说明: 如果准入 Webhook 需要保证它们所看到的是对象的最终状态以实施某种策略。 则应使用验证性质的准入 Webhook,因为对象被修改性质 Webhook 看到之后仍然可能被修改。 尝试准入 Webhook 准入 Webhook 本质上是集群控制平面的一部分。你应该非常谨慎地编写和部署它们。 如果你打算编写或者部署生产级准入 Webhook, 请阅读用户指南以获取相关说明。 在下文中,我们将介绍如何快速试验准入 Webhook。 先决条件 确保启用 MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook 控制器。 这里是一组推荐的准入控制器, 通常可以启用。 确保启用了 admissionregistration.k8s.io/v1 API。 编写一个准入 Webhook 服务器 请参阅 Kubernetes e2e 测试中的 Admission Webhook 服务器的实现。 Webhook 处理由 API 服务器发送的 AdmissionReview 请求,并且将其决定作为 AdmissionReview 对象以相同版本发送回去。
- 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 文件中,提供证书凭据
- Author:白鸟3
- URL:https://blog.kun2peng.top/operation/k8s_api_security
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
