目次
1、机制说明
2、认证
组件和插件对apiserver的访问
API Server必要认证的类型
ServiceAccount(SA)
ServiceAccount的组成
ServiceAccount补充
认证过程一图流
kubeconfig
3、鉴权
RBAC特性优势
RBAC资源对象
特殊的绑定关系
用户/组哪里来?
Role
ClusterRole
RoleBinding+Role
RoleBinding+ClusterRole
ClusterRoleBinding+ClusterRole
概念的补充
Resource子资源
Subject
4、开始实行
下载证书天生工具cfssl
天生证书
设置集群参数
设置客户端认证参数
设置上下文参数
权限绑定
基于系统用户的权限隔离(非必须,一个扩展)
补充-资源与角色类型的匹配
补充-常见的预定义角色
5、准入控制
1、机制说明
kubernetes作为一个分布式集群的管理工具,保证集群的安全性是其一个重要任务。API Server是集群内部各个组件通信的中介,也是外部控制的入口。以是kubernetes的安全机制基本就是围绕掩护API Server来设计的
图片解析,当用户或者Pod服务要访问k8s集群内部的一些资源就要3A机制,也就是颠末三个步骤,这三个步骤都封装在了API Server内部,并且按序进行
- Authentication(验证/认证):验证用户或者服务是否是有来到进群内部的资格,就像进公司刷门禁卡
- AUthorization(鉴权/授权):鉴定用户或服务的权利,可以干什么不能干什么
- AdmissionControl(准入控制):在认证和授权通事后,还可以进一步检查请求是否满足集群的策略要求。就像进了公司,有了进机房的权利,但是你不能放火,放火就会制止你
2、认证
认证有三种类型
- HTTP Token:通过一个Token来识别合法用户
- 它的认证用一个很长的特殊编码方式的并且难以被模拟的字符串-Token来表达客户的一种方式。Token是一个很长很复杂的字符串,每个Token对应一个用户名存储在APIServer能访问的文件中。当客户端发起API调用请求是,必要在HTTP Header里放入Token
- HTTP Base:通过用户名+密码的方式认证
- 用户名和密码用BASE64算法进行编码后的字符串放在HTTP Request中的Header Authorization域里发送给服务端,服务端收到后进行编码,获取用户名、密码
- HTTPS:最严格的证书认证,基于CA根证书署名的客户端身份认证方式
- https认证分为单向和双向
- 单向:比如访问百度,是我们必要认证百度的资质,百度服务器向用户提供身份认证,客户端通过验证服务器的数字证书确保服务器的真实性,客户端无需向服务器提供认证信息
- 双向:比如ATM机,必要银行和我们双向认证。就是客户端除了验证服务器的数字证书外,还必要向服务器提供本身的证书。服务器和客户端都要向对方提供认证
而k8s用的就是用的https双向认证,认证流程如下图
简单来说就是张三(client)想和李四(server)做生意,但是双方互不认识。
这时王二(CA)出现了,德高望重。分别给了张三、李四一张保举信(证书)。到了两人见面时候了,李四先给出本身的保举信,张三一看保举信确认是李四了,这时候在把本身的保举信给李四看,双方通过认证以后,就可以关起门发财了(加密通讯)
就是这么个流程
组件和插件对apiserver的访问
kubernetes组件对API Server的访问
- kubectl:命令行工具 ,命令必要传达给apiserver去处理
- Controller Manger:通过apiserver确认每个节点的控制器、pod状态
- Scheduler:通过apiserver监听各个节点的状态进行Pod的调理
- kubelet:通过apiserver监听当前节点必要运行的Pod,通过调用CRI接口实现容器的创建
- kube-proxy:监听apiserver当前节点干系的ipvs规则合法防火墙规则,实现规则的订定
从上面组件可以看到集群中自带的组件都必要对apiversion发起访问。还有一些插件比如calico,dns这些插件是Pod方式工作在集群中的,当然部门组件也是这种情势。
以是calico、dns这些插件如果不访问apiserver的话,怎么知道哪些Pod必要分配IP地址,必要进行dns解析呢
API Server必要认证的类型
先说组件,无需加密的组件:
- Contorller Mangeer、Scheduler和API Server。
因为在同一台呆板,以是直接用API Server的非安全端口访问“--insecure-bind-address=127.0.0.1”。基于kubeadm安装的方式它们才在一起,二进制安装的话不一定,以是二进制安装的话它们也必要双向认证
必要加密的组件分两种,手动颁发证书和自动颁发证书:
- 手动颁发证书:kube-proxy、kubectl通过k8s集群的根CA进行签发HTTPS证书。
从集群的安装到现在都没有做过手动签发证书的操纵,因为基于kubeadm安装的方式,它已经把手动签发证书的操纵替我们给做了,并不是不必要手动签发
- 自动颁发证书:kubelet。kubelet首次访问API Server时,利用token做认证,通事后Controller Manager会为kubelet天生一个证书,以后的访问就都是用证书做认证了。
为什么apiserver会如此信任kubelet会给它自动签发证书?来看下
- kubeadm join 192.168.176.101:6443 --token 7vw0x2.yhu1b4sob2fem9a5 --discovery-token-ca-cert-hash sha256:6126cbbab761e2f56c3a9bf1cfc590ad05508b289552bd9ea683ef629b929f20 --cri-socket unix:///var/run/cri-dockerd.sock
- 192.168.176.101:6443 --token 7vw0x2.yhu1b4sob2fem9a5
- 先看命令前半部分,这个就是集群给node节点颁发的令牌,在令牌时效内用这个令牌访问apiserver,它就把这个node当作自己人
- --discovery-token-ca-cert-hash sha256:6126cbbab761e2f56c3a9bf1cfc590ad05508b289552bd9ea683ef629b929f20
- 再看命令后半部分,这是当前CA证书的哈希值,用来给kubelet确认apiserver是否合法,防止它认错人。当kubbelet拿着集群给的令牌找apiserver时候,apiserver会拿出自己的证书给kubelet看,kubelet会用哈希值和apiserver证书的哈希值做确认。这是就是一个双向加密的方式
复制代码 再说Pod,先想一个问题,组件和是集群同生死的,签发证书没问题。但是Pod的寿命是动态的,有1000个Pod就要签发1000次证书么?要是刚签发完证书Pod就死了呢?
以是Pod认证不是通过双向认证做到的,而是另一个东西Service Account
ps:部门组件也是pod状态运行的,
ServiceAccount(SA)
Pod中的容器访问API Server,因为Pod的创建、销毁是动态的,以是要为他手动天生证书就不可行了。k8s用了sa来办理Pod访问apiserver的认证问题
ServiceAccount的组成
k8s设计了一种资源对象叫Secret,分为两类。一种是用于sa的Service-account-token,另一种是用于掩护用户自定义保密信息的Opaque。sa中用到三个文件:
- ca.crt:根证书。用于client端验证API Server发送的证书
- token:根据API Server私钥基于JWT规范签发出来的字符串。用于Pod访问API Server时的Server端认证
- namespace:标识这个servcie-account-token的作用域名空间。因为Pod是名称空间级别的,而apiserver是集群级别,名称空间级别访问集群级别时候,就要告诉集群Pod在什么名字空间上
Json web token(JWT)。不消了解太多,只要知道它的重要功能:适用于分布式站点的单点登录(SSO)场景。
普通来说就是A访问B,B不必要访问A,这就是单点登录。在集群中就是Pod访问API Server,但是API Server不可能访问Pod
ServiceAccount补充
默认情况下,每个namespace都会有个SA,如果Pod在创建时没有指定SA,就会利用Pod所属的namespace中的SA。
如上图,新创建了一个ns,然后get ns就可以看到默认的sa,如果在test这个ns下运行pod,pod就会默认调用此sa发起对apiserver的访问,如果必要的话
当pod利用了sa后,它会挂载到容器内的这个路径下
- /run/secrets/kubernetes.io/serviceaccount/
复制代码
认证过程一图流
kubeconfig
kubeconfig这个文件包罗了集群参数(CA证书、API Server地址),客户端参数(证书和私钥),集群context信息(集群名称、用户名)。k8s组件通过启动是指定差别的kubeconfig文件可以切换到差别的集群
实在在一开始就对这个文件进行过操纵了,还记得集群安装结束后提示我们要执行的命令吗?
- mkdir -p $HOME/.kube
- sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
- sudo chown $(id -u):$(id -g) $HOME/.kube/config
- 这个admin.conf文件就是kubeconfig文件类型
复制代码 看下文件中有什么
这个文件就是管理员通向集群的钥匙,相当关键。kubernetes-admin 用户是由 kubeadm 默认创建的管理员用户
当kubectl执行命令时候,就会调用当前家目次的.kube/config文件来加载配置。通过这个文件,kubectl 知道应该毗连哪个集群、利用哪个用户认证以及在哪个命名空间执行操纵来试一下。
将文件移动到别的目次然后执行命令,如下图
3、鉴权
上面的认证过程只是确认通信的双方都是可信的,可以相互通信。而鉴权是确定请求方有哪些资源的权限。API Server现在支持以下几种授权策略(可通过API Server的启动参数“--authorization-mode”设置)
- AlwaysDeny :拒绝全部的请求,一般用于测试
- AlwaysAllow:吸收全部请求,如果集群不必要授权流程可以采取该策略
- ABAC(Attribute-Based Access Control):基于属性的访问控制,表现利用用户配置的授权规则对用户进行请求匹配和控制。很贫困,快被镌汰了
- Webhook:通过调用外部REST服务对用户进行授权
- RBAC(Role-Based Access Control):基于角色的访问控制,现行默认规则
RBAC特性优势
RBAC机制在k8s 1.5中引入,现行版本成为了默认尺度。相对于其他访问控制方式,拥有以下优势:
- 对进群中的资源和非资源均拥有完整的覆盖
- 整个RBAC完全由几个API对象完成,同其他API对象一样,可以用kubectl或API进行操纵
- 可以在运行是调整,无需重启API Server
RBAC资源对象
RBAC引入了4个新的顶级资源对象:Role、ClusterRole、RoleBinding、ClusterRoleBinding,4种对象类型均可以通过kubectl和API进行操纵
图片解析:右边的资源对象,不管是对象的建立、获取照旧更新等操纵,可以理解为一种权限。将这种权限具象化成Role,再将Role通过RoleBinding和用户、用户组及服务账户进行绑定,使它们拥有对应的权限
通过图片有个大致的了解了,在看下资源对象的绑定关系,分为三种
- Role必须通过RoleBinding绑定,作用范围仅限于命名空间
- ClusterRole通过ClusterRoleBinding绑定,作用范围是集群
- ClusterRole通过RoleBinding绑定,作用范围仅限于特定命名空间,是特殊的绑定关系
特殊的绑定关系
这种方式实在就是限定ClusterRole的作用域,让它的辐射范围从整个集群,通过RoleBinding限定在各个namespace中
解析上图:现在有四个命名空间,分别在每个命名空间下创建一个用户。如果想让四个用户具备分别管理各自所在空间的管理权限的话,必须要创建Role,然后RoleBinding。算一算分别创建了三个用户、三个角色、三个角色绑定,共12个资源对象
换个方式创建Role看下
解析上图:不在每个ns中创建一个Role,直接创建一个ClusterRole来管理全部ns空间权限,现在任意一个用户ClusterRoleBinding和它进行绑定会怎样? 看图,B-user绑定了ClusterRole,现在它不仅是本身ns的管理员,照旧全部ns的。固然只创建了9个资源对象,但是如许就越权了,不安全
在换个方式看下
看图,创建RoleBinding资源对象的时候,必须在其定义中指定 metadata.namespace 字段,也就是说必须要指定它当前所在的命名空间,如许各个用户在本身所在的ns中用ClusterRole,就等同于在各自ns中有了管理员权限
普通点说,一个学校校长(admin-ClusterRole)的权利最大它和整个学校(集群)绑定(ClusterRoleBinding);班主任(ABCD-user)在它们各自班级(namespace)的权利(Role)最大,它们和本身的班级绑定(RoleBinding);这时候校长(admin-ClusterRole)来到A班级,把他关在A班(namespace),把它和A班绑定(RoleBindind),他再大的权利也只能在A班级利用,出不去
从第一张图到第三张图,资源对象从12个缩减到了9个,看着不多。
但是如果集群中有10个ns呢?100个呢?
以是通过这种特殊的绑定关系,来减少资源对象的创建,也更轻易管理
用户/组哪里来?
前面的理论中提到了权限的的附着点有“用户”、“用户组”、“Service Account”
SA前面说过了创建方式,命令或者资源清单的方式都可以。它背后的ns、ca.crt、token都是自动封装,自动天生。不必要手动干预
- kuberctl create sa saName -n nsName
- kubectl create sa test --dry-run=client -o yaml
复制代码 但是在k8s中并没有创建用户和组的干系命令,该怎么获取用户呢?看官方的描述如下:
全部 Kubernetes 集群都有两类用户:由 k8s 管理的服务账号(Service Account)和普通用户。
Kubernetes 假定普通用户是由一个与集群无关的服务通过以下方式之一进行管理的:
- 负责分发私钥的管理员
- 类似 Keystone 或者 Google Accounts 这类用户数据库
- 包罗用户名和密码列表的文件
Kubernetes 本身并不内置普通用户的管理功能,也没有专门的 API 对象(如 User 对象)来表现普通用户,普通用户的认证通常依靠于外部机制,比如证书、OAuth、LDAP 或 OpenID Connect(OIDC)。在这里,就说基于证书的用户认证
签发证书是apiserver.crt来签发的,目次在/etc/kubernetes/pki下,参数这里用json格式列出来
- {
- "CN": "admin" #用户名
- "hosts": [], #证书可访问地址,客户端ip/源ip,没写就是什么样的源ip都可以使用此证书
- "key": {
- "algo": "rsa",
- "size": 2048
- },
- "names": [
- {
- "C": "CN",
- "ST": "Hangzhou",
- "L": "XS",
- "O": "system:masters", #用户组
- "OU": "System"
- }
- ]
- }
复制代码 Role
在RBAC API中,Role表现一组权限,权限只会增加(累加权限),不存在一个资源开始就有许多权限然后通过RBAC对其进行减少的操纵;Role可以定义在一个namespace中,如果想跨ns则可以创建ClusterRole
- apiVersion: rbac.authorization.k8s.io/v1
- kind: Role
- metadata:
- name: pod-reader
- namespace: default # 不写默认就是它,这里方便理解所以写上。
- rules:
- - apiGroups: [""] # 空字符串表示核心 API 组,例如 Pod 属于核心组。
- resources: ["pods"] # 定义资源类型,这里是 pods。
- verbs: ["get", "watch", "list"] # 允许的操作,包括获取、监听和列出 Pod。
复制代码 代码是角色的创建方式
ClusterRole
ClusterRole具有与Role相同的额权限角色控制能力,差别的是ClusterRole是集群级别的,ClusterRole可以用于
- 集群级别的资源控制(如node访问权限)
- 非资源型endpoints(如“/health访问”)
- 全部命名空间资源控制(如pod)
- apiVersion: rbac.authorization.k8s.io/v1
- kind: ClusterRole
- metadata:
- name: secret-reader #这里没写命名空间,因为已经是集群级别了,狮子不会住在老鼠洞
- rules:
- - apiGroup: [""]
- resources: ["secrets"]
- verbs: ["get","watch","list"]
复制代码 代码是集群角色的创建方式
RoleBinding+Role
RoleBinding可以将角色中定义的权限授予用户或者用户组,RoleBinding包罗一组权限列表(subject),权限列表中包罗有差别情势的待授予权限资源类型(users、groups、service account);RoleBinding同样包罗对Bind的Role引用;RoleBinding适用于某个命名空间内授权,而ClusterRoleBinding适用于集群范围内的授权
- apiVersion: rbac.authorization.k8s.io/v1
- kind: RoleBinding
- metadata:
- name: read-pods
- namespace: default
- subjects: # 定义绑定的用户、组或服务账号。也就是权限的附着点
- - kind: User # 绑定的主体类型,这里是单个用户。
- name: jane # 用户的名称,必须与认证时的用户名一致。
- apiGroup: rbac.authorization.k8s.io # 指定 RBAC 的 API 组。
- roleRef: # 定义与哪个 Role 或 ClusterRole 绑定。
- kind: Role # 绑定的角色类型,这里是 Role。
- name: pod-reader # 绑定的 Role 名称,这里是 pod-reader。
- apiGroup: rbac.authorization.k8s.io # 指定 Role 的 API 组。
复制代码 代码是角色绑定的创建方式
RoleBinding+ClusterRole
RoleBinding同样可以引用ClusterRole来对当前namespace内用户、用户组、Service account进行授权,这种操纵允许集群管理员在整个集群内定义一些通用的ClusterRole,然后在差别的namespace中利用RoleBinding来引用
- apiVersion: rbac.authorization.k8s.io/v1
- kind: RoleBinding
- metadata:
- name: read-secrets
- namespace: dev
- subject: # 定义绑定的用户、组或服务账号。
- - kind: User # 绑定的主体类型,这里是单个用户。
- name: dave # 用户的名称,必须与认证时的用户名一致。
- apiGroup: rbac.authorization.k8s.io # 指定 RBAC 的 API 组。
- roleRef: # 定义与哪个 Role 或 ClusterRole 绑定。
- kind: ClusterRole # 绑定的角色类型,这里是 ClusterRole。
- name: secret-reader # 绑定的 ClusterRole 名称,这里是 secret-reader。
- apiGroup: rbac.authorization.k8s.io # 指定 ClusterRole 的 API 组。
复制代码 ClusterRoleBinding+ClusterRole
利用ClusterRoleBinding可以对整个集群中的全部命名空间资源权限进行授权;一下ClusterRoleBinding样例展示了授权manager组内全部用户在全部命名空间中随secret进行访问
- apiVersion: rbac.authorization.k8s.io/v1
- kind: ClusterRoleBinding
- metadata:
- name: read-secrets-global
- subject: # 定义绑定的用户、组或服务账号。
- - kind: Group # 绑定的主体类型,这里是一个用户组。
- name: manager # 组的名称,所有属于该组的用户都会继承权限。
- apiGroup: rbac.authorization.k8s.io # 指定 RBAC 的 API 组。
- roleRef: # 定义与哪个 Role 或 ClusterRole 绑定。
- kind: ClusterRole # 绑定的角色类型,这里是 ClusterRole。
- name: secret-reader # 绑定的 ClusterRole 名称,这里是 secret-reader。
- apiGroup: rbac.authorization.k8s.io # 指定 ClusterRole 的 API 组。
复制代码 概念的补充
Resource子资源
k8s集群内一些资源一般一起名称字符串来表现,这些字符串一般会在API的URL地址中出现,同时某些资源也会包罗子资源,例如logs资源就属于pods的子资源,API中RUL样例如下
- GET /api/v1/namespace/{namespace}/pods/{name}/logs #相当于获取命名空间下的pod demo的日志
- #这个样例就是查看日志时候,其操作的本质:像API发送URL的请求
复制代码 如果要在RBAC授权模子中控制这些子资源的访问权限,可以通过/分隔符来实现,以下是一个定义pods资源logs访问权限的Role定义样例
- apiVersion: rbac.authorization.k8s.io/v1
- kind: Role
- metadata:
- name: pod-and-pod-logs-reader
- namespace: default
- rules:
- - apiGroup: [""]
- resource: ["pods/log"]
- verbs: ["get","list"]
复制代码 Subject
RoleBinding和ClusterRoleBinding可以将Role绑定到Subject;Subject可以是groups、users或者Service accounts
Subject中利用Users利用字符串表现,它可以是一个普通的名字字符串,如“jim”;也可以是email格式的邮箱地址,如“xxxx@163.com”;乃至可以使一组字符串情势的数字ID。但是Users的前缀system:是系统保留的,集群管理员应该确保普通用户不会利用这个前缀格式
Group誊写格式与Users相同,都为同一个字符串,并且没有特定的格式要求;同样system:前缀为系统保留
4、开始实行
前面认证和鉴权一大堆理论,现在将理论化为实践。过程比力繁琐
创建一个用户并且只能管理dev命名空间,流程如下
创建证书》转换为kubeconfig文件》创建命名空间》角色绑定
下载证书天生工具cfssl
比openssl更加方便,openssl太复杂了,而且k8s干系的证书天生都是用这个
- wget https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssljson_1.6.5_linux_amd64
- 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/cfssl-certinfo_1.6.5_linux_amd64
- mv cfssl_1.6.5_linux_amd64 /usr/local/bin/cfssl
- mv cfssl-certinfo_1.6.5_linux_amd64 /usr/local/bin/cfssl-certinfo
- mv cfssljson_1.6.5_linux_amd64 /usr/local/bin/cfssljson
- chmod a+x /usr/local/bin/cfssl
复制代码 天生证书
最好是在/etc/kubernetes/pki/目次下,比力方便
- #创建证书文件,内容是定义证书生成所需的参数,更加的直观
- vim devuser.json
- {
- "CN": "devuser", // CN 表示证书的通用名称 (Common Name),通常是用户名或域名
- "hosts": [], // 适用主机列表,空数组表示不限定主机或 IP 地址
- "key": { // 定义密钥的相关参数
- "algo": "rsa", // 指定密钥的加密算法,这里使用 RSA
- "size": 2048 // 指定密钥的长度,2048 位是常见的安全选择
- },
- "names": [ // 证书的组织信息列表
- {
- "C": "CN", // 国家代码,CN 表示中国
- "ST": "BeiJing", // 省份,这里填写北京
- "L": "BeiJing", // 城市,这里填写北京
- "O": "k8s", // 组织名称,例如 k8s
- "OU": "System" // 组织单位名称,例如 System
- }
- ]
- }
- #生成证书
- cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes devuser.json |cfssljson -bare devuser
- #cfssl gencert:调用 cfssl 生成证书。
- #-ca=ca.crt:指定根证书(CA 证书)。
- #-ca-key=ca.key:指定 CA 的私钥,用来签发证书。
- #-profile=kubernetes:指定 Kubernetes 配置文件,以定义证书的策略。
- #devuser.json:提供证书请求的 JSON 文件,包含 CN 和组织信息等。
- #| cfssljson -bare devuser:将生成的证书输出转换为 .pem 文件,文件名为 devuser
- #执行该命令将得到一个新的证书(devuser.pem)、私钥(devuser-key.pem)和可能的 CSR 文件,所有文件的名称以 devuser 为前缀
复制代码 设置集群参数
- #这个命令设置了一个环境变量 KUBE_APISERVER,其值为 Kubernetes API 服务器的URL。192.168.176.101:6443 是 Kubernetes API 服务器的地址和端口。这个地址用于访问集群的控制平面。
- 这一步是为了便于后续的命令中引用 API 服务器地址。
- export KUBE_APISERVER="https://192.168.176.101:6443"
- kubectl config set-cluster kubernetes \
- --certificate-authority=ca.crt \
- --embed-certs=true \
- --server=${KUBE_APISERVER} \
- --kubeconfig=devuser.kubeconfig
- #kubectl config set-cluster kubernetes
- kubectl config set-cluster 是 kubectl 命令中的一个子命令,用于设置集群的配置信息。kubernetes 是集群的名称。这个名称将在 kubeconfig 文件中引用该集群。
- # --certificate-authority=ca.crt
- 这个选项指定了一个证书文件 ca.crt,该文件包含 Kubernetes API 服务器的根证书。ca.crt 是用于验证 Kubernetes API 服务器的证书。它确保客户端与 API 服务器的通信是安全的。
- # --embed-certs=true
- 这个选项告诉 kubectl 将证书嵌入到 kubeconfig 文件中,而不是单独引用文件。这意味着 ca.crt 的内容将被直接嵌入 devuser.kubeconfig 文件,而不需要单独的证书文件。
- # --server=${KUBE_APISERVER}
- 这个选项指定了 Kubernetes API 服务器的地址。这里使用的是前面设置的环境变量 ${KUBE_APISERVER},即 https://192.168.176.101:6443。该 URL 用于与 Kubernetes API 服务器通信。
- # --kubeconfig=devuser.kubeconfig
- 这个选项指定了配置文件的路径,即 devuser.kubeconfig。kubectl 将在这个文件中保存集群的配置信息。
- 总结:
- 这条命令的目的是为 devuser 创建一个新的 kubeconfig 文件(devuser.kubeconfig),配置与 Kubernetes 集群的连接。它包括以下内容:
- 集群名称:kubernetes
- API 服务器的地址:https://172.20.0.113:6443
- CA 证书:ca.crt(嵌入到 kubeconfig 文件中)
- 执行此命令后,devuser.kubeconfig 将包含访问 Kubernetes 集群所需的配置信息,包括证书、服务器地址等。
复制代码
图中各种信息问问gpt吧,描述的很具体
设置客户端认证参数
- #这条命令会在指定的 devuser.kubeconfig中更新user部分
- kubectl config set-credentials devuser \
- --client-certificate=devuser.pem \
- --client-key=devuser-key.pem \
- --embed-certs=true \
- --kubeconfig=devuser.kubeconfig
- #kubectl config set-credentials devuser
- 含义设置用户 devuser 的认证信息。
- 上下文:在 Kubernetes 的配置文件(kubeconfig)中创建或更新一个名为 devuser 的用户条目。
- #--client-certificate=devuser.pem
- 含义:指定用户 devuser 的客户端证书文件。客户端证书通常是一个 .pem 文件,证明用户的身份。
- 用途:当用户 devuser 通过 kubectl 访问 Kubernetes 集群时,会使用该证书进行身份认证。
- #--client-key=devuser-key.pem
- 含义:指定用户 devuser 的私钥文件。
- 用途:配合客户端证书,用于完成双向 TLS(双向身份认证),确保通信安全并验证用户身份。
- # --embed-certs=true
- 含义:将证书和私钥的内容直接嵌入到 kubeconfig 文件中,而不是以文件路径的形式引用它们。
- 优势:提高了配置的独立性和可移植性,因为 kubeconfig 文件中已经包含了所有必要的认证信息。
- 避免因证书文件丢失或路径不正确导致的问题。
- # --kubeconfig=devuser.kubeconfig
- 含义:指定操作的 kubeconfig 文件为 devuser.kubeconfig。
- 用途:将用户的认证信息写入或更新到指定的配置文件中,而不是默认的 ~/.kube/config 文件。
- 总结
- 这条命令的主要功能是为 devuser 配置基于客户端证书的认证信息,并将其写入到指定的 kubeconfig 文件(devuser.kubeconfig)中。这是 Kubernetes 用户管理中配置认证的重要步骤之一,尤其是在多用户、多角色的场景下
复制代码 可以看到用户证书信息被添加进来了
设置上下文参数
- #命令执行后,devuser.kubeconfig 文件中的 contexts 部分会更新或新增一个名为 kubernetes 的上下文
- kubectl config set-context kubernetes \
- --cluster=kubernetes \
- --user=devuser \
- --namespace=dev \
- --kubeconfig=devuser.kubeconfig
- #kubectl config set-context kubernetes
- 含义:设置一个名为 kubernetes 的上下文。
- 上下文(context):Kubernetes 的 kubeconfig 文件中,context 是一个逻辑配置项,用于关联:
- 集群(cluster)
- 用户(user)
- 命名空间(namespace)
- 用途:通过上下文快速切换集群、用户和命名空间的组合。
- #--cluster=kubernetes
- 含义:指定上下文中关联的集群,名称为 kubernetes。
- 上下文作用:告诉 kubectl 使用配置文件中定义的 kubernetes 集群(在 clusters 部分定义)。
- #--user=devuser
- 含义:指定上下文中关联的用户,名称为 devuser。
- 上下文作用:告诉 kubectl 使用配置文件中定义的 devuser 用户(在 users 部分定义)。
- 用户配置示例(来自 devuser.kubeconfig 文件的 users 部分):
- #--namespace=dev
- 含义:指定上下文中关联的命名空间,名称为 dev。
- 上下文作用:告诉 kubectl 默认在 dev 命名空间中执行操作。
- 优点:
- 如果省略 --namespace,kubectl 命令会默认作用于 default 命名空间。
- 通过设置上下文,避免每次运行 kubectl 命令时都指定 --namespace=dev。
- #--kubeconfig=devuser.kubeconfig
- 含义:指定将上下文配置写入的 kubeconfig 文件为 devuser.kubeconfig。
- 用途:避免修改默认的 ~/.kube/config 文件,保持独立性和可移植性。
复制代码 可以看到上下文信息被添加进来了

至此,devuser用户的kubeconfig文件配置结束了,只要拿着这个文件交给kubectl去毗连集群,集群就能帮助用户完成认证
创建kubeconfig文件过程就像系统中创建用户。因为k8s没有创建用户的功能,以是通过创建kubeconfig文件,并且在文件中表明用户及它的访问方式,等同于创建用户。但是k8s中用户权限是累加的,不存在开始就有默认权限然后对它进行限定 (个人理解)
权限绑定
上面提到权限是累加的,现在devuser用户没有和Role/ClusterRole进行任何RoleBinding/ClusterRoleBinding的绑定,也就意味着devuser是没有任何权限的,现在进行权限的绑定操纵;并且在上下文参数中规定了要在dev的命名空间下操纵
- #创建dev命名空间
- kubectl create ns dev
- #创建rolebinding
- apiVersion: rbac.authorization.k8s.io/v1
- kind: RoleBinding
- metadata:
- name: devuser-admin-binding
- namespace: dev
- roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: admin
- subjects:
- - apiGroup: rbac.authorization.k8s.io
- kind: User
- name: devuser
复制代码 先在default命名空间下创建几个pod,等下有效
kubectl create deployment default-deploy --image=nginx --replicas=3
然后设置默认上下文
- kubectl config use-context kubernetes --kubeconfig=devuser.kubeconfig
- #kubectl config use-context:
- 这是 kubectl 的一个子命令,用于切换当前的上下文(context)。
- Kubernetes 的上下文是一个配置集,包括了 集群(cluster)、用户(user) 和 命名空间(namespace),它定义了 kubectl 的默认行为,例如操作哪个集群,使用哪个用户身份,以及默认命名空间。
- kubernetes
- 这是目标上下文的名称。此命令会将当前的上下文切换为名为 kubernetes 的上下文。
- 具体的上下文名字是根据 kubeconfig 文件中定义的配置而定,kubernetes 是这里的示例名称。
- --kubeconfig=devuser.kubeconfig:
- 指定了 kubeconfig 文件的路径(此处为 devuser.kubeconfig)。
- 默认情况下,kubectl 使用位于 ~/.kube/config 的配置文件。如果你有多个 kubeconfig 文件,并想使用特定的文件,可以通过这个选项指定。
- 在这里,kubectl 将使用 devuser.kubeconfig 文件中的内容,而不是默认的配置文件。
- mv /root/.kube/config /root/
- cp -a /etc/kubernetes/pki/devuser.kubeconfig /root/.kube/config
复制代码 这个步骤就相当于切换到devuser用户了,在来验证用户的权限
看上图, 检察全部pod是没有权限的,上面提到过权限是累加的,没有累加之前权限为空。以是devuser只给了它dev命名空间下的干系管理员权限,并没有给default空间的权限
- #在dev名字空间下创建个控制器
- kubectl create deployment test-deploy --image=nginx --replicas=10
复制代码 再将初始kubeconfig放回原位
看上图,全部pod都能看到了
现在有两个kubeconfig文件了,一个admin,一个devuser。假设A要在集群内进行操纵
管理员和A说:有两个文件,一个是dev空间操纵管理,一个是集群内任意操纵,你看想要实现什么样的功能,再去拿对应文件。
那A想了,为什么不拿集群文件呢?谁来直接拿集群文件不就行了,为什么我要被限定权限?
那么基于这个想法,用户的划分还有什么意义呢?以是,能不能配合当前linux系统用户,去做到用户级别的隔离?
基于系统用户的权限隔离(非必须,一个扩展)
现在有devuser这个用户,而它就是管理dev命名空间的管理员,然后和它说要毗连的服务器地址是192.168.176.101;用户是dev,密码是123。就可以毗连到linxu服务器中,它默认的权限就是devuser,这才是最惬意的状态。怎样做到?
kubectl会默认探求当前用户家目次的.kube/confg文件。如果在linux中创建一个dev用户,它也有本身的家目次,只要把刚才创建的那个config放在这个家目次下就可以了
试一下
- useradd dev
- passwd dev
- mkdir /home/dev/.kube
- mv dev-config /home/dev/.kube/config
- chown -R dev:dev /home/dev/.kube/
复制代码 再开个终端,用dev用户进行登录
完全没有问题
补充-资源与角色类型的匹配
访问的资源 | 利用的角色类型 | 利用的绑定类型 | 集群级别资源
(Nodes、PersistentVolumes...) | ClusterRole | ClusterRoleBinding | 非资源型URL
(/api、/healthz...) | ClusterRole | ClusterRoleBinding | 在任何命名空间中的资源
(和跨全部命名空间的资源) | ClusterRole | ClusterRoleBinding | 在具体命名空间中的资源
(在多个命名空间中重复利用ClusterRole RoleBinding) | ClusterRole | RoleBinding | 在具体命名空间中的资源
(Role必须在每个命名空间中定义好) | Role | RoleBinding | 不管是集群角色照旧角色,都可以本身去编写创建。还有许多底子类型的权限角色,官方给我们预备好了,用kubectl get clusterrole可以查一下。“system:“”开头的都是集群用的
除此以外还有一些没有“system:”开头的,这些就可以理解为是官方给我们预备的,公共可以利用的
具体先容一下
补充-常见的预定义角色
view ClusterRole
- 允许读取一个命名空间中的大多数资源,除了Role、RoleBinding和Secret
edit ClusterRole
- 允许读取和修改Secret。但是,它也不允许检察或修改Role和RoleBinding,防止权限扩散
admin ClusterRole
- 一个命名空间中资源的完全控制权是由admin ClusterRole赋予的。有这个ClusterRole的主体可以读取和修改命名空间中的任何资源,除了ResourceQuota和命名空间资源本身。edit和admin集群角色之前的重要区别是:能否在命名空间中检察和修改Role和RoleBinding
cluster-admin ClusterRole
- 通过将cluster-admin集群角色赋予给主体,主体可以得到k8s集群完全控制的权限,谁有了cluster-admin就相当于是这个集群的创造人,它是最大的
5、准入控制
准入控制是API Server的插件集合,通过添加差别的插件实现额外的准入控制规则。乃至于API Server的一些重要的功能都必要通过Admission Controllers实现,比如ServerAccount
kube-apiserver | Kuberneteshttps://kubernetes.io/zh-cn/docs/reference/command-line-tools-reference/kube-apiserver/这是官方的准入控制器保举列表,太多了。有必要各位本身按需查找吧
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |