Kubernetes 证书详解(鉴权)
Kubernetes 证书详解(鉴权)
简介
上一篇 系统分析了 Kubernetes 集群中每个证书的作用和证书认证的原理。对于 Kube-apiserver,Kubelet 来说,它们都能提供 HTTPS 服务,Kube-apiserver、Kubelet 对于一个请求,既要认证也要鉴权。在 Kube-apiserver 中,鉴权也有多种方式:
- Node
- ABAC
- RBAC
- Webhook
在 TLS + RBAC 模式下,访问 Kube-apiserver 有三种方式:
- 证书 + RBAC(就是上一篇说到的那些证书)
- Node + RBAC( Kubelet 访问 Kube-apiserver 时)
- ServiceAccount + RBAC( Kubernetes 集群内 Pod 访问 Kube-apiserver )
关于 RBAC 的内容不熟悉的可以参考官网
K8S 证书的 CN、O
RBAC 鉴权需要对 User 或者 Group 来绑定相应权限达到效果。Kubernetes 证书中的 CN 表示 User,O 表示 Group,看一个例子:
用 openssl 命令解析 kubelet 的客户端证书,kubelet 访问 Kube-apiserver 的时候就会用这个证书来认证,鉴权。
$ openssl x509 -noout -text -in kubelet-client-current.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 271895513527774644 (0x3c5f7876bd86db4)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=kubernetes
Validity
Not Before: May 10 06:48:30 2023 GMT
Not After : Apr 16 06:48:37 2123 GMT
# 看这里
Subject: O=system:nodes, CN=system:node:master-172-31-97-104
Subject Public Key Info:
.......
可以发现 Kubelet 的客户端证书的 O 是 system.nodes,CN 是 system:node:master-172-31-97-104 ,所以在 Kubernetes 中,每个结点的 Kubelet 都被赋予 *system:node:"结点名称"* 的 User,且附属于 *system.nodes* 的 Group。
Kubernetes RBAC 鉴权机制就是利用将权限绑定到 User 或者 Group,使得 User、Group 拥有对应权限,下面就看看 Kubernetes 如何 根据证书、ServiceAccount 鉴权的。
Kubectl
Kubectl 使用 KubeConfig 与 Kube-apiserver 进行认证、鉴权。认证上一篇说过了,就是通过 TLS 认证。这里说鉴权,先看看 KubeConfig 的客户端证书 O、CN
使用 openssl 命令解析 KubeConfig 中 client-certificate-data 字段,查看 KubeConfig 客户端证书的 O、CN
$ cat /root/.kube/config | grep client-certificate-data: | sed 's/ client-certificate-data: //g' | base64 -d | openssl x509 -noout -subject
# 结果
subject= /O=system:masters/CN=kubernetes-admin
可以发现 KubeConfig 客户端证书为 kubernetes-admin User 且属于 system:masters Group。
system:masters 是 Kubernetes 内置的用户组,且 Kubernetes 集群中也包含许多默认 ClusterRole、ClusterRolebinding,其中 cluster-admin 的 ClusterRolebinding 就将 cluster-admin 的 ClusterRole 绑定到 *system:masters* Group,这样 KubeConfig 就拥有权限来操作 Kube-apiserver 了。
# cluster-admin ClusterRole 拥有所有资源的所有权限
$ kubectl get clusterrole cluster-admin -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2023-05-10T06:49:27Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: cluster-admin
resourceVersion: "85"
uid: 006af228-e6ef-43fa-a73f-ca0c109b13f0
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'
- nonResourceURLs:
- '*'
verbs:
- '*'
-------------------------------------------------------------------
# cluster-admin ClusterRoleBinding 将 cluster-admin ClusterRole 绑定到 system:masters Group
$ kubectl get clusterrolebinding cluster-admin -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2023-05-10T06:49:27Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: cluster-admin
resourceVersion: "147"
uid: 980fbdff-6750-4957-b5fa-954a5013b192
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
# clusterRole name
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
# Group name
name: system:masters
经过上面的操作,Kubectl 就可以使用 KubeConfig 来操作 Kube-apiserver 了。
Kube-scheduler、Kube-controller-manager
同样 Kube-scheduler、Kube-controller-manager 也是使用各自的 KubeConfig 来认证、鉴权。但是他们和 Kubectl 的 KubeConfig 不属于同一个用户、组。
使用 openssl 命令解析 Kube-scheduler 的 KubeConfig 中 client-certificate-data 字段,查看 KubeConfig 客户端证书的 O、CN
$ cat /etc/kubernetes/scheduler.conf | grep client-certificate-data: | sed 's/ client-certificate-data: //g' | base64 -d | openssl x509 -noout -subject
# 结果
subject= /CN=system:kube-scheduler
可以发现 KubeConfig 客户端证书为 kubernetes-admin User 但是不属于某个 Group。
system:kube-scheduler 也是 Kubernetes 集群内部的设置的用户,Kubernetes 集群中也存在对应默认的 ClusterRole system:kube-scheduler 和 ClusterRoleBinding system:kube-scheduler。
# system:kube-scheduler ClusterRole 拥有细分的权限
$ kubectl get clusterrole system:kube-scheduler -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2023-05-10T06:49:27Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:kube-scheduler
resourceVersion: "115"
uid: b1ddf98c-bdb9-4d4d-9af3-9db1c97b038a
rules:
- apiGroups:
- ""
- events.k8s.io
resources:
- events
verbs:
- create
- patch
- update
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- create
- apiGroups:
- coordination.k8s.io
resourceNames:
- kube-scheduler
resources:
- leases
verbs:
- get
- update
- apiGroups:
- ""
resources:
- endpoints
verbs:
- create
.......
# 一些更细致的权限
--------------------------------------------------------------------------
# system:kube-scheduler ClusterRoleBinding 将 system:kube-scheduler ClusterRole 绑定到 system:kube-scheduler User
$ kubectl get clusterrolebinding system:kube-scheduler -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2023-05-10T06:49:27Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:kube-scheduler
resourceVersion: "155"
uid: a9b8a85e-bb5c-483c-a08e-51822ce84d7f
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
# ClusterRole name
name: system:kube-scheduler
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
# User name
name: system:kube-scheduler
可以发现 Kube-scheduler 权限并不是向 Kubectl 那样拥有所有资源的所有操作权限,即使是内部组件,基于最小权限原则,Kubernetes 依然会为这两个用户只绑定必要的权限。
Kube-controller-manager 和 Kube-scheduler 一样,只不过 Kube-controller-manager 的 User 是 system:kube-controller-manager,其默认的 ClusterRole、ClusterRoleBinding 名称不同而已,可以根据 Kube-scheduler 自行验证~
system:前缀是 Kubernetes 保留的关键字,用于描述内置的系统用户和系统用户组,在 Kube-apiserver 启动时,会默认为这些用户绑定好对应的权限,具体参考官网
Kubelet
Kubelet 同样也会访问 Kube-apiserver,Kubelet 使用其客户端证书与 Kube-apiserver 认证、鉴权。
使用 openssl 命令解析 Kubelet 客户端证书,查看证书的 O、CN
$ openssl x509 -noout -subject -in /var/lib/kubelet/pki/kubelet-client-current.pem
# 结果
subject= /O=system:nodes/CN=system:node:master-172-31-97-104
可以发现 Kubelet 客户端证书为 system:node:master-172-31-97-104 User 且属于 system:nodes Group。
还是和上面一样,system:nodes 也是 Kubernetes 内置用户组,通过查看其默认的 ClusterRole、ClusterRoleBinding
$ kubectl get clusterrolebinding system:node -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2023-05-10T06:49:27Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:node
resourceVersion: "157"
uid: 8ba46211-bdae-493f-8f5f-3386fe63ba29
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:node
发现 system:node ClusterRoleBinding 并没有绑定 system:node:master-172-31-97-104 User 或者 system:nodes Group。官方文档也有介绍:https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/rbac/#core-component-roles
实际上 Kubernetes 现在基于 Node Authorizer 来限制kubelet只能读取和修改本节点上的资源,并不是使用 RBAC 来鉴权。为了获得节点鉴权器的授权,Kubelet 必须使用一个凭证以表示它在 system:nodes 组中,用户名为 system:node:<nodeName>。这个凭证就是从 Kubelet 客户端证书获取,也就是上面的 O、CN
Node Authorizer 参考:https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/node/
Kube-apiserver
前面都是在说其他组件访问 Kube-apiserver,然后 Kube-apiserver 对访问者进行授权,然而 Kube-apiserver 也会作为客户端去访问 Kubelet,例如:kubectl logs/exec,Kube-apiserver 都会去访问 Kubelet。Kubelet 作为服务端内部也是通过 TLS + RBAC 这种模式去认证、鉴权。
使用 openssl 命令解析 Kube-apiserver 客户端证书,查看证书的 O、CN
$ openssl x509 -noout -subject -in /etc/kubernetes/pki/apiserver-kubelet-client.crt
# 结果
subject= /O=system:masters/CN=kube-apiserver-kubelet-client
可以发现 Kube-apiserver 访问 Kubelet 客户端证书为 kube-apiserver-kubelet-client User 且属于 system:masters Group。
在 Kubectl 章节介绍了 system:masters 属于内置用户组,且默认拥有超级权限,所以 Kube-apiserver 可以去访问 Kubelet 操作资源。
ServiceAccount
上面说的几种情况,都是根据 User 或者 Group 鉴别其是否拥有权限,ServiceAccount 和 User、Group 属于同一性质。
在 Kubernetes 集群内部,比如 Pod 需要访问 Kube-apiserver,就会使用其配置的 Service Account(没有配置,则使用默认) 与 Kube-apiserver 认证、鉴权。
通过一个例子来说明:
mysql 这个 Pod 配置 mysql-sa 这个 ServiceAccount
# pod 部分 yaml
nodeName: master-172-31-97-104
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
# serviceAccount 配置
serviceAccount: mysql-sa
serviceAccountName: mysql-sa
terminationGracePeriodSeconds: 10
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
operator: Exists
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
然后查看对应 Role,查看拥有的权限
$ kubectl get role mysql-role -n test -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: mysql-role
namespace: test
rules:
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
查看 RoleBinding,然后会发现将上面的 Role 与 Pod 的 ServiceAccount 绑定。
$ kubectl get rolebinding mysql-role -n test -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: mysql-rolebinding
namespace: test
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
# role name
name: mysql-role
subjects:
- kind: ServiceAccount
# serviceAccount name
name: mysql-sa
namespace: test
这样 mysql-sa ServiceAccount 就拥有了 Configmmap,Event 这两个资源的所有权限。
所以当 Pod 内部去访问 Kube-apiserver,实际上 Kube-apiserver 是根据其 ServiceAccount 来鉴定其拥有的权限,而不是 User 或者 Group。
总结
上面的鉴权原理,可以下面这张图做个总结

每个组件都代表着不同的 K8S 角色与 Kube-apiserver 鉴权。
到这里整个 Kubernetes 证书都讲解完了,包括认证、鉴权。掌握了 Kubernetes 组件之间的调用关系,以及双向 TLS 认证 就可以理清证书的作用和关系,同时还需掌握证书内容的 O、CN、SANS 等字段作用,才能明白 Kubernetes 是如何根据证书 + RBAC 进行访问授权的。
最后有兴趣可以使用二进制部署一个 Kubernetes 集群,通过手动签发证书,来加深理解~
引用
Kubernetes 官方文档 Node Authorizer

关注微信公众号,可了解更多云原生详情~
Kubernetes 证书详解(鉴权)的更多相关文章
- iOS-申请测试证书详解(多图原创)
申请测试证书详解 前言 App开发和发布过程中证书基础知识:1. Certification(证书)证书是对电脑开发资格的认证,每个开发者帐号有一套,分为两种:1) Developer Certifi ...
- iOS开发者证书-详解
iOS开发者证书-详解/生成/使用 本文假设你已经有一些基本的Xcode开发经验, 并注册了iOS开发者账号. 相关基础 加密算法 现代密码学中, 主要有两种加密算法: 对称密钥加密 和 公开密钥加密 ...
- kubernetes 控制器详解【持续完善中】
目录 资源创建详解 一:Pod及常用参数 1.简介 2.模板 3.删除pod 4.设置Pod主机名 5.镜像拉取策略(ImagePullPolicy) 二:RC 1.简介 2.模板 三:Deploym ...
- k8s入坑之路(2)kubernetes架构详解
每个微服务通过 Docker 进行发布,随着业务的发展,系统中遍布着各种各样的容器.于是,容器的资源调度,部署运行,扩容缩容就是我们要面临的问题. 基于 Kubernetes 作为容器集群的管理平 ...
- 网络传输中的各种加密算法+SSL+CA证书详解
1. 数据传输分类 在互联网上数据传输有两种:明文传输和加密传输.明文传输的协议有:ftp.http.smtp.telnet.但是为了数据的完整性和安全性,所以后来引用了加密等相关手段来保证数据的安全 ...
- 【转载】k8s入坑之路(2)kubernetes架构详解
每个微服务通过 Docker 进行发布,随着业务的发展,系统中遍布着各种各样的容器.于是,容器的资源调度,部署运行,扩容缩容就是我们要面临的问题. 基于 Kubernetes 作为容器集群的管理平台被 ...
- SSL证书详解和CFSSL工具使用
公钥基础设施(PKI) 基础概念 CA(Certification Authority)证书,指的是权威机构给我们颁发的证书. 密钥就是用来加解密用的文件或者字符串.密钥在非对称加密的领域里,指的是私 ...
- iOS证书详解--再转
一.成员介绍1. Certification(证书)证书是对电脑开发资格的认证,每个开发者帐号有一套,分为两种:1) Developer Certification(开发证书)安装在电脑上 ...
- IOS开发环境更换后重新制作Provisioning Profile证书详解
新换了台Macbook,又折腾了一遍Provisioning Profile证书,苹果的证书繁锁复杂,每次制作都相当麻烦,而且Provisioning Profile证书是与设备绑定的,所以更换开发环 ...
- 阿里云部署SSL证书详解
http://mp.weixin.qq.com/s/NV7Zad4DVEgzG2GCHYJVLw 查找中间证书 为了确保兼容到所有浏览器,我们必须在阿里云上部署中间证书,如果不部署证书,虽然安装过程可 ...
随机推荐
- K8S安全学习
k8s安全学习 一.云 云的定义看似模糊,但本质上,它是一个用于描述全球服务器网络的术语,每个服务器都有一个独特的功能.云不是一个物理实体,而是一个庞大的全球远程服务器网络,它们连接在一起,旨在作为单 ...
- 如何理解redis两种不同的持久化方式
其实redis就是一种高级的以键值对形式存储数据的数据库,而它的好处就是他可以支持数据的持久化,其实redis之所以会有这样的优点,主要是因为,redis的数据都是存放在内存中的,如果不配置持久化,那 ...
- Little Snitch 5 - Mac 老牌防火墙安全工具软件小飞贼,监控和组织特定软件的网络连接
一旦连接到Internet,应用程序就可以随时随地发送它们想要的任何东西.通常情况下,他们是为你做的.但有时,例如在跟踪软件.木马或其他恶意软件的情况下,它们不会.但你不会注意到任何东西,因为所有这些 ...
- kubernetes(k8s)部署 Metrics Server 资源
资源使用指标,例如容器 CPU 和内存使用率,可通过 Metrics API 在 Kubernetes 中获得.这些指标可以直接被用户访问,比如使用 kubectl top 命令行,或者被集群中的控制 ...
- [Linux]CentOS查看RPM包依赖问题
[经典应用案例] 查看此文前,可先查看 此博文中:在安装软件过程中,如何解决的依赖组件问题? [数据库/Linux]CentOS7安装MySQL Percona版(RPM方式) : 2-1 依赖组件问 ...
- [Linux]常用命令之【source|export/env】#点命令/环境变量#
1 source 1-1 source 命令概述 source命令用法:source FileName 简述 source命令(从 C Shell 而来)是bash shell的内置命令. sourc ...
- [Linux]查看硬件及操作系统信息
许多的软件产品对硬件及操作系统等环境是有具体要求的,那么这时候如何快速知晓目标机器的目标资源信息是较为频繁的操作. 命令 全部硬件及系统信息 dmidecode (软硬件全部信息) hostnamec ...
- django渲染模版时比实际少了8小时?
这是因为django的时间是UTC时间. 我们通过改配置文件将其改成本地时间 修改配置文件 # 将时间从UTC转化成当前时间 TIME_ZONE = 'Asia/Shanghai' # USE_TZ ...
- Midjourney:一步一步教你如何使用 AI 绘画 MJ
一步一步如何使用 Midjourney 教程:教学怎么用 MJ? 一.Midjourney(MJ)是什么? Midjourney是一款使用文字描述来生成高质量图像的AI绘画工具.这篇文章主要介绍了Mi ...
- Java 新的生态型应用开发框架,Solon v2.2.13 发布
Java 新的生态型应用开发框架,Solon :更快.更小.更简单.从零开始构建,有自己的标准规范与开放生态: 150多个生态插件,可以满足各种场景开发 大量的国产框架适配,可以为应用软件国产化提供更 ...