【云原生】Kubernetes----RBAC用户资源权限

目录

引言

一、Kubernetes安全机制概述

二、认证机制

(一)认证方式

1.HTTPS证书认证

[1.1 证书颁发](#1.1 证书颁发)

[1.2 config文件](#1.2 config文件)

[1.3 认证类型](#1.3 认证类型)

[1.4 Service Account](#1.4 Service Account)

[1.4.1 作用](#1.4.1 作用)

[1.4.2 包含内容](#1.4.2 包含内容)

[1.4.3 与Secret的关系](#1.4.3 与Secret的关系)

[2.Bearer Tokens](#2.Bearer Tokens)

3.基本认证

三、鉴权

(一)鉴权机制

1.基于RBAC

2.其它鉴权机制

(二)RBAC的API资源对象

1.Role(角色)

2.ClusterRole(集群角色)

3.RoleBinding(角色绑定)

4.ClusterRoleBinding(集群角色绑定)

[5. 主体(subject)类型](#5. 主体(subject)类型)

[5.1 User](#5.1 User)

[5.2 Group](#5.2 Group)

[5.3 ServiceAccount](#5.3 ServiceAccount)

(三)创建角色及绑定

1.创建服务账号

2.创建Role

3.创建RoleBinding

4.创建pod

5.示例总结

四、准入控制

(一)准入控制器的工作流程

(二)准入控制器的类型

五、对用户的权限设置

(一)创建证书

1.获取工具

2.创建生成证书的配置文件

3.生成证书

(二)生成config文件

(三)RBAC授权

1.创建Role资源

2.Role绑定

(四)切换用户使用

1.创建pod

2.其它权限

3.获取管理员权限


引言

随着云计算和容器技术的蓬勃发展,Kubernetes(K8s)作为容器编排的领头羊,其安全性成为了众多企业和开发者关注的焦点。本文将详细解析Kubernetes的安全机制,包括认证、鉴权和准入控制,以确保集群的稳定性和数据的安全。

一、Kubernetes安全机制概述

Kubernetes的安全机制主要围绕三个核心组件:认证、鉴权和准入控制。认证是安全机制的第一道防线,负责确认请求者的身份;鉴权则是根据用户的身份和权限策略,确定其是否有权执行特定操作;最后,准入控制对API资源对象的修改和校验进行把关。

二、认证机制

(一)认证方式

1.HTTPS证书认证

HTTPS证书认证:基于CA(证书颁发机构)证书签名的数字证书认证。

适用于kube-apiserver、etcd、kubelet等组件之间的连接,确保通信的安全性。

当Pod在Kubernetes集群中启动时,Service Account通常会使用客户端证书进行身份验证。

1.1 证书颁发

手动签发:使用二进制部署时,需要先手动跟 CA 进行签发 HTTPS 证书

自动签发:kubelet 首次访问 API Server 时,使用 token 做认证,通过后,Controller Manager 会为 kubelet 生成一个证书, 以后的访问都是用证书做认证了

1.2 config文件
[root@master01 ~]#ll ~/.kube/config
-rw------- 1 root root 5565 5月  16 15:19 /root/.kube/config
#家目录下的.kube/config文件,用于存储用户的认证信息
#kubectl通过该文件的令牌信息,确定使用的用户,以及对应的权限
1.3 认证类型

Kubernetes 组件对 API Server 的访问,如kubelet、kubectl、kube-proxy,由于这些组件是在node节点上,所以需要证书进行HTTPS双向认证,端口号使用6443端口

Kubernetes 管理的 Pod 对 API Server 的访问

注释:访问安全性要求

kubernetes中,API Server会启动8080端口(非安全端口)与6443端口(安全端口)

安全性:8080端口没有认证和授权检查,存在安全风险;而6443端口有TLS保护,更加安全。

用途:8080端口主要用于调试或内部通信;而6443端口是Kubernetes集群的官方通信端口,用于与外部工具和组件进行交互。

配置:两个端口的配置都可以通过apiserver的启动参数进行修改。在生产环境中,通常建议只开启6443端口,并确保其安全性。

1.4 Service Account
1.4.1 作用

Service Account是Kubernetes中的一种资源对象,用于定义Pod中应用程序的身份。

主要作用是为Pod提供身份,使得Pod可以在Kubernetes集群中被唯一标识,并通过身份验证和授权机制获取访问API Server的权限

因为 Pod 的创建、销毁是动态的,所以要为每一个 Pod 手动生成证书就不可行了。 Kubenetes 使用了 Service Account 来循环认证。Service Account提供了一个在Pod内部使用的身份令牌,用于在Pod与Kubernetes API之间进行交互。

1.4.2 包含内容

●Token:是使用 API Server 私钥签名的 Token 字符串序列号,用于访问 API Server 时,Server 端认证

●ca.crt:ca 根证书,用于 Client 端验证 API Server 发送来的证书

●namespace:标识这个 service-account-token 的作用域名空间

每个命名空间都有一个默认的ServiceAccount,如果用户不指定ServiceAccount,Pod将自动关联到该默认的ServiceAccount上。

1.4.3 与Secret的关系

当Service Account创建时,Kubernetes会自动为每个ServiceAccount创建一个与之关联的Secret,其中包含了ServiceAccount的身份令牌。

[root@master01 opt]#kubectl describe pod nginx
...... 
  Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-vgx6f (ro)
......

2.Bearer Tokens

令牌认证:用户或服务可以通过获取一个令牌(Token)并在请求中携带该令牌来进行身份验证。

HTTP Token 的认证是用一个很长的特殊编码方式的并且难以被模仿的 Token 字符串来表达客户的一种方式。Token 是一个很长的很复杂的字符串,每一个 Token 对应一个用户名存储在 API Server 能访问的文件中。当客户端发起 API 调用请求时,需要在 HTTP Header 里放入 Token。

在node节点加入master时,就需要令牌来进行连接

3.基本认证

HTTP Basic Auth:使用用户名和密码进行基本的HTTP认证。

在Kubernetes中,这种认证方式相对较少使用,因为它不如其他方式安全。

注释:Token 认证和 Base 认证方式只能进行服务端对客户端的单向认证,而客户端不知道服务端是否合法;而 HTTPS 证书认证方式 则可以实现双向认证。

三、鉴权

(一)鉴权机制

1.基于RBAC

Kubernetes的鉴权机制主要基于Role-Based Access Control(RBAC)实现。RBAC允许管理员定义角色(Role)和角色绑定(RoleBinding),以控制用户对资源的访问权限。角色定义了用户可以执行的操作和可以访问的资源,而角色绑定则将角色与用户或用户组进行关联。通过这种方式,管理员可以灵活地配置权限策略,确保只有授权用户才能执行特定操作。

2.其它鉴权机制

●AlwaysDeny:表示拒绝所有的请求,一般用于测试
●AlwaysAllow:允许接收所有请求,如果集群不需要授权流程,则可以采用该策略,一般用于测试
●ABAC(Attribute-Based Access Control):基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制。也就是说定义一个访问类型的属性,用户可以使用这个属性访问对应的资源。此方式设置较为繁琐,每次设置需要定义一长串的属性才可以。
●Webhook:通过调用外部 REST 服务对用户进行授权,即可在集群外部对K8S进行鉴权

(二)RBAC的API资源对象

1.Role(角色)

定义:Role 是一个针对单个命名空间的权限控制对象,包含了若干的rules,这些rules代表了一组的permissions(准入、权限)。这些准入是叠加起作用的,并且RBAC在Kubernetes中是一种白名单机制,即都是"允许干xxx",而不是"不允许干xxx"。

使用:Role属于某个特定的namespace,所以在创建Role时需要指定其所属的namespace。

2.ClusterRole(集群角色)

定义:ClusterRole 是一个集群范围的概念,用于定义对Kubernetes资源(集群级别,包含全部命名空间)的访问规则。ClusterRole 不属于某个特定的namespace,它可以定义跨所有命名空间的资源权限,也可以定义集群级别的资源权限。

使用:ClusterRole 可以像Role一样使用,用于对cluster-scoped resources(如nodes)和非资源端点(如/healthz)进行权限的赋予。

3.RoleBinding(角色绑定)

定义:RoleBinding 定义了"Role"和"Subject"(如User、Group或ServiceAccount)的绑定关系,即将用户以及操作权限进行绑定。

使用:使用RoleBinding可以将User和某个Role进行绑定,这样User就拥有了Role所定义的权限,但只能操作RoleBinding所在的命名空间。

4.ClusterRoleBinding(集群角色绑定)

定义:ClusterRoleBinding 定义了用户和集群角色的关系,即通过ClusterRoleBinding将User和ClusterRole进行绑定。

使用:通过ClusterRoleBinding,User可以获得ClusterRole所定义的权限,从而拥有操作所有命名空间的权限。

5. 主体(subject)类型

在Kubernetes中,User、Group 和 ServiceAccount 都是安全认证和授权模型中的主体(subject)类型。这些主体代表了可以执行操作的实体,并且与特定的权限相关联

5.1 User

用户通常代表一个真实的或虚拟的人。在Kubernetes中,用户可能是一个集群外部的实体,如一个开发者或管理员,他们使用kubectl或其他客户端工具与集群交互。

用户的身份验证可以通过多种方式进行,包括静态令牌、OAuth令牌、OpenID Connect(OIDC)等。

一旦通过身份验证,用户的身份会与一个或多个Group关联,以进一步简化授权。

5.2 Group

用户组是用户的集合,通常用于简化权限管理。例如,你可能有一个名为"developers"的用户组,并为该组分配特定的权限。

用户的组成员资格可以静态定义,也可以通过身份验证机制(如OIDC)动态确定。

授权策略可以基于用户组进行定义,从而允许或拒绝整个组的访问。

5.3 ServiceAccount

服务账号(ServiceAccount)是Kubernetes内部的一个实体,用于给Pods中的进程提供访问集群API的凭据。

每个Pod都可以与一个ServiceAccount关联,该ServiceAccount包含了一个API令牌,该令牌允许Pod中的容器以Pod的身份对Kubernetes API发起请求。

ServiceAccount是Pod的安全上下文的一部分,通常与特定的命名空间相关联。

与User和Group不同,ServiceAccount是专为集群内部的服务和工作负载设计的。

(三)创建角色及绑定

1.创建服务账号

首先创建一个服务账号(Service Account)

cs 复制代码
[root@master01 rbac]#vim sa.yaml
[root@master01 rbac]#cat sa.yaml
apiVersion: v1
kind: Namespace          #创建命名空间
metadata:
  name: web              #指定命名空间名称
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: rbac-sa          #服务账号名称
  namespace: web         #所在命名空间
[root@master01 rbac]#kubectl apply -f sa.yaml 
namespace/web created
serviceaccount/rbac-sa created
[root@master01 rbac]#kubectl get serviceaccounts rbac-sa -n web 
NAME      SECRETS   AGE
rbac-sa   1         26s

2.创建Role

cs 复制代码
[root@master01 rbac]#cat role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: rbac-role
  namespace: web
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "watch", "list"]
[root@master01 rbac]#kubectl apply -f role.yaml
role.rbac.authorization.k8s.io/rbac-role created
[root@master01 rbac]#kubectl get role rbac-role -n web
NAME        CREATED AT
rbac-role   2024-06-05T16:07:54Z
------------------------------------------------------------------------------
apiGroups
apiGroups字段指定了资源所属的API群组。常用apiGroups的有

""(空字符串):核心API群组,例如Pods、Services、Endpoints等。
"apps":包含Deployments、StatefulSets、DaemonSets等应用相关的资源。
"batch":包含Jobs、CronJobs等资源。
"extensions":在旧版Kubernetes中用于某些beta API,但在新版中很多资源已经移至其他群组。
"networking.k8s.io":网络相关的资源,如Ingress。
"rbac.authorization.k8s.io":RBAC相关的资源,如Role、RoleBinding等。
----------------------------------------------------------------------------------
resources
resources字段列出了该角色可以访问的具体资源类型。这些资源类型必须是Kubernetes API中定义的。
以下是一些常见的资源类型示例:
pods
services
deployments
configmaps
secrets
ingresses
nodes(对于ClusterRole)
roles 或 rolebindings(对于ClusterRole,允许管理RBAC资源)
-----------------------------------------------------------------------------------
verbs
verbs字段定义了可以对资源执行的操作。以下是一些常用的verbs示例:

get:读取资源。
list:列出所有资源。
watch:观察资源的更改。
create:创建资源。
update:更新资源。
patch:部分更新资源。
delete:删除资源。
deletecollection:删除资源集合。
exec:在Pod中执行命令(通常与Pod资源一起使用)
------------------------------------------------------------------------------------

3.创建RoleBinding

cs 复制代码
[root@master01 rbac]#cat rolebind.yaml
apiVersion: rbac.authorization.k8s.io/v1  
kind: RoleBinding  
metadata:  
  name: rbac-rolebind
  namespace: web      #RoleBinding所属的命名空间(RoleBinding也是命名空间作用域的,必须指定)
subjects:               #定义主体类型
- kind: ServiceAccount  #主体类型为ServiceAccount
  name: rbac-sa         #ServiceAccount名称
  namespace: web        #指定的ServiceAccount所在命名空间
roleRef:                #引用Role或者ClusterRole
  kind: Role            #引用的资源类型为Role
  name: rbac-role       #引用的Role的名称
  apiGroup: rbac.authorization.k8s.io  #表示RBAC API群组
[root@master01 rbac]#kubectl apply -f rolebind.yaml 
rolebinding.rbac.authorization.k8s.io/rbac-rolebind created
[root@master01 rbac]#kubectl get rolebindings rbac-rolebind -n web -owide
NAME            ROLE             AGE   USERS   GROUPS   SERVICEACCOUNTS
rbac-rolebind   Role/rbac-role   35s                    web/rbac-sa

4.创建pod

创建pod是为了验证角色绑定后的权限效果

cs 复制代码
[root@master01 rbac]#cat rbac-pod.yaml
apiVersion: v1  
kind: Pod  
metadata:  
  name: rbac-centos 
  namespace: web
spec:  
  serviceAccountName: rbac-sa
  containers:  
  - name: centos
    image: centos:7
    command: ["/bin/sh","-c","sleep 36000"]
[root@master01 rbac]#kubectl apply -f rbac-pod.yaml 
pod/rbac-centos created

在pod内部,使用curl命令的方式,获取到pod的信息,类似于执行了get权限

curl -k -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://<API_SERVER_ADDRESS>:<API_SERVER_PORT>/api/v1/namespaces/default/pods


<API_SERVER_ADDRESS>:APIServer的地址,也就是master的地址

<API_SERVER_PORT>:APIServer的监听端口,也就是6443

default:指定命名空间

创建一个不指定serviceaccount的pod,它就不具备权限,使用curl命令访问会出现403报错,表示权限拒绝

cs 复制代码
[root@master01 rbac]#vim rbac-pod.yaml 
[root@master01 rbac]#cat rbac-pod.yaml 
apiVersion: v1  
kind: Pod  
metadata:  
  name: rbac-centos-test
  namespace: web
spec:  
#  serviceAccountName: rbac-sa    #注释serviceAccountName字段信息
  containers:  
  - name: centos
    image: centos:7
    command: ["/bin/sh","-c","sleep 36000"]
[root@master01 rbac]#kubectl apply -f rbac-pod.yaml 
pod/rbac-centos-test created
[root@master01 rbac]#kubectl get pod rbac-centos-test -n web
NAME               READY   STATUS    RESTARTS   AGE
rbac-centos-test   1/1     Running   0          25s

5.示例总结

通过上面的示例,我们创建了一个名为rbac-sa 的ServiceAccount,一个名为rbac-role 的Role(允许在web 命名空间中读取Pod资源),以及一个名为rbac-rolebind 的RoleBinding(将rbac-role Role绑定到rbac-sa ServiceAccount上)。

效果是:任何使用rbac-sa ServiceAccount的Pod都将具有在web命名空间中读取Pod资源的权限。这允许Pod中的进程通过Kubernetes API获取Pod列表、读取Pod详细信息或监视Pod更改,但不允许它们创建、更新或删除Pod(除非Role中明确允许这些操作)

四、准入控制

准入控制是Kubernetes安全机制的最后一道防线,对API资源对象的修改和校验进行把关。Kubernetes提供了一个插件列表,所有请求都需要经过这个列表中的每个准入控制插件进行处理。这些插件可以对请求进行各种检查和修改,如检查请求是否符合特定的规范、限制请求的资源配额等。通过启用不同的准入控制插件,管理员可以实现对集群的细粒度控制和管理。一般建议直接采用官方默认的准入控制器

(一)准入控制器的工作流程

当向Kubernetes API服务器提交一个请求(如创建、更新或删除资源)时,API服务器会将请求传递给一系列注册的准入控制器进行检查。每个控制器都会根据其配置的规则来决定是否允许请求继续。如果任何一个控制器拒绝了请求,那么整个操作将不会被执行。

(二)准入控制器的类型

Kubernetes提供了多种内置的准入控制器,包括但不限于:

NamespaceAutoProvision: 自动创建请求的命名空间,如果它还不存在。

ResourceQuota: 检查资源配额,确保请求的资源不会超过限定。

ServiceAccount: 确保Pod自动关联一个ServiceAccount。

NodeRestriction: 限制Node上可执行的操作。

PodSecurityPolicy: 应用Pod安全策略,控制Pod的运行方式。

MutatingAdmissionWebhook: 执行自定义的HTTP请求,允许修改请求体。

ValidatingAdmissionWebhook: 类似于MutatingAdmissionWebhook,但仅用于验证,不允许修改请求。

五、对用户的权限设置

平时我们都是默认的root用户进行操作,因为在~/.kube/config的配置文件中进行了令牌认证,它与k8s的admin用户进行了绑定,所以,它会有k8s的所有操作权限。如果使用其它用户进行操作就无法使用

cs 复制代码
[root@master01 ~]#useradd rbac        #创建一个普通用户
[root@master01 pki]#passwd rbac
更改用户 rbac 的密码 。
新的 密码:
无效的密码: 密码少于 8 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
[root@master01 ~]#su - rbac
[rbac@master01 ~]$ kubectl get pod    #以普通用户的身份执行kubectl命令
The connection to the server localhost:8080 was refused - did you specify the right host or port?
[rbac@master01 ~]$ ls ~/.kube/config
ls: 无法访问/home/rbac/.kube/config: 没有那个文件或目录
#错误信息表示kubectl命令试图连接到默认的Kubernetes API服务器地址(localhost:8080),但连接被拒绝了
#因为APIServer的监听端口是6443,而使用kubectl命令在没有kubeconfig文件的指定情况下
#连接的是8080端口(非安全端口),所以需要进行证书认证并访问644端口

比如现在的需求是创建一个用户只能管理指定的命名空间,首先要做的就是创建用户用于连接到 API Server 所需的证书和 kubeconfig 文件

(一)创建证书

下载生成TSL证书工具并上传到系统当中

下载地址

https://pkg.cfssl.org/R1.2/cfssl_linux-amd64

https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64

https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64

1.获取工具

cs 复制代码
[root@master01 cfssl]#ls
cfssl  cfssl-certinfo  cfssljson
[root@master01 cfssl]#chmod +x ./*
[root@master01 cfssl]#ll
总用量 18808
-rwxr-xr-x 1 root root 10376657 2月  17 2021 cfssl
-rwxr-xr-x 1 root root  6595195 2月  17 2021 cfssl-certinfo
-rwxr-xr-x 1 root root  2277873 2月  17 2021 cfssljson
[root@master01 cfssl]#mv * /usr/local/sbin/

2.创建生成证书的配置文件

以下JSON文件是一个CFSSL(Cloudflare's PKI/TLS toolkit)的配置文件,用于生成一个TLS证书和私钥

cs 复制代码
[root@master01 cfssl]#mkdir -p /k8s/rbac
[root@master01 cfssl]#vim /k8s/rbac/rbac-csr.json
[root@master01 cfssl]#cat /k8s/rbac/rbac-csr.json
{
  "CN": "rbac",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
	  "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
	  "OU": "System"
    }
  ]
}

"CN": "rbac": 这指定了证书的Common Name(CN),即证书的主题名。在这里,它被设置为"rbac",但在实际应用中,这个值应该反映证书将被用于的服务或组件的实际名称。

"hosts": []: 这定义了证书应该覆盖的主机名列表。在这个例子中,列表是空的,意味着证书不会为任何特定的主机名提供验证。在Kubernetes中,这通常不是必需的,因为证书验证通常是通过其他方式(如证书颁发机构或内部CA)进行的。

"key": 这个部分定义了私钥的生成参数。

"algo": "rsa": 指定了密钥算法为RSA。

"size": 2048: 指定了密钥的大小为2048位。

"names": 这个部分定义了证书的主题(Subject)信息。

"C": "CN": 指定了国家代码(Country Code),这里是"CN"代表中国。

"ST": "BeiJing": 指定了州/省(State/Province),这里是"BeiJing"代表北京。

"L": "BeiJing": 指定了城市/地区(Locality),同样是"BeiJing"。

"O": "k8s": 指定了组织(Organization),这里是"k8s"代表Kubernetes。

"OU": "System": 指定了组织单位(Organizational Unit),这里是"System"。

#API Server 会把客户端证书的 CN 字段作为 User,把 names.O 字段作为 Group

3.生成证书

cs 复制代码
[root@master01 pki]#cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes /k8s/rbac/rbac-csr.json | cfssljson -bare rbac
2024/06/06 08:51:45 [INFO] generate received request
2024/06/06 08:51:45 [INFO] received CSR
2024/06/06 08:51:45 [INFO] generating key: rsa-2048
2024/06/06 08:51:45 [INFO] encoded CSR
2024/06/06 08:51:45 [INFO] signed certificate with serial number 6178924093556289309011739985572884710402992043
2024/06/06 08:51:45 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
[root@master01 pki]#ls rbac*
rbac.csr  rbac-key.pem  rbac.pem
-----------------------------------------------------------------------------------------

cfssl gencert:这是 CFSSL 的一个子命令,用于生成证书。

-ca=ca.crt:指定了 CA(证书颁发机构)的证书文件。

-ca-key=ca.key:指定了 CA 的私钥文件。

-profile=kubernetes:指定了一个配置文件中的签名配置(profile)。这个配置文件通常定义了证书的签名算法、有效期等参数。

/k8s/rbac/rbac-csr.json:这是 CSR(证书签名请求)文件的路径。这个文件包含了要生成的证书的请求信息,如 CN(Common Name)、hosts、密钥算法等。

cfssljson -bare rbac:这是 CFSSL 的另一个子命令 cfssljson,用于解析 CFSSL 生成的 JSON 格式的输出,并将其转换为 PEM 格式的证书和私钥文件。

-bare rbac 表示输出的文件名将以 "rbac" 为前缀,因此你会得到 rbac.pem(证书文件)和 rbac-key.pem(私钥文件)。

综上所述,这条命令的作用是:使用指定的 CA 证书和私钥,以及 "kubernetes" profile,根据/k8s/rbac/rbac-csr.json 文件中的请求信息来生成一个 TLS 证书和私钥,并将结果保存为 rbac.pem和 rbac-key.pem 文件。

(二)生成config文件

cs 复制代码
[root@master01 pki]#cd  /k8s/rbac/
[root@master01 rbac]#vim rbac-config.sh
[root@master01 rbac]#cat rbac-config.sh
#!/bin/bash
APISERVER=$1
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=rbac.kubeconfig
kubectl config set-credentials rbac \
  --client-key=/etc/kubernetes/pki/rbac-key.pem \
  --client-certificate=/etc/kubernetes/pki/rbac.pem \
  --embed-certs=true \
  --kubeconfig=rbac.kubeconfig
kubectl config set-context kubernetes \
  --cluster=kubernetes \
  --user=rbac \
  --namespace=kgc \
  --kubeconfig=rbac.kubeconfig
kubectl config use-context kubernetes --kubeconfig=rbac.kubeconfig
-----------------------------------------------------------------------------------
#以脚本的形式创建,或者以命令的方式,分别执行

APISERVER=$1

这是一个 Bash 脚本变量赋值语句,它将脚本的第一个参数(1)赋值给变量 APISERVER。这个参数是 Kubernetes API 服务器的地址。 **export KUBE_APISERVER="https://APISERVER:6443"**

设置环境变量,引用$1的参数生成的变量


设置集群参数

使用 kubectl config set-cluster 命令设置 kubeconfig 文件中的集群信息。

--certificate-authority=/etc/kubernetes/pki/ca.crt: 指定 CA 证书的路径,用于验证 API 服务器的 TLS 证书。

--embed-certs=true: 将 CA 证书嵌入到 kubeconfig 文件中,而不是仅引用文件路径。

--server={KUBE_APISERVER}: 设置 API 服务器的 URL。{KUBE_APISERVER} 是之前通过 $1 设置的变量。

--kubeconfig=rbac.kubeconfig: 指定要修改的 kubeconfig 文件的名称。


设置客户端认证参数

使用 kubectl config set-credentials 命令设置 kubeconfig 文件中的用户认证信息。

--client-key=/etc/kubernetes/pki/rbac-key.pem: 指定客户端私钥的路径。

--client-certificate=/etc/kubernetes/pki/rbac.pem: 指定客户端证书的路径。

--embed-certs=true: 类似于集群设置,这也会将证书嵌入到 kubeconfig 文件中。

--kubeconfig=rbac.kubeconfig: 指定要修改的 kubeconfig 文件的名称。


设置上下文参数

使用 kubectl config set-context 命令设置 kubeconfig 文件中的上下文信息。

--cluster=kubernetes: 指定要使用的集群名称(这必须与 kubectl config set-cluster 命令中使用的名称相匹配)。

--user=rbac: 指定要使用的用户名称(这必须与 kubectl config set-credentials 命令中使用的名称相匹配)。

--namespace=rbac-ns: 设置默认的命名空间为rbac-ns。

--kubeconfig=rbac.kubeconfig: 指定要修改的 kubeconfig 文件的名称。

使用上下文参数生成 rbac.kubeconfig 文件

使用 kubectl config use-context 命令将指定的上下文设置为 kubeconfig 文件中的当前上下文。

--kubeconfig=rbac.kubeconfig: 指定要修改的 kubeconfig 文件的名称。

cs 复制代码
[root@master01 rbac]#kubectl create ns rbac-ns
namespace/rbac-ns created
#创建默认的命名空间,与上述文件中指定命名空间一致
[root@master01 rbac]#chmod +x rbac-config.sh
[root@master01 rbac]#./rbac-config.sh 192.168.83.30
Cluster "kubernetes" set.
User "rbac" set.
Context "kubernetes" created.
Switched to context "kubernetes".

查看config文件

这样看起来是不是与~/.kube/config文件很相似,而后将文件移动到用户的目录下,改名为config

cs 复制代码
[root@master01 rbac]#mkdir -p /home/rbac/.kube
[root@master01 rbac]#mv rbac.kubeconfig /home/rbac/.kube/config
[root@master01 rbac]#chown -R rbac:rbac /home/rbac/.kube/
[root@master01 rbac]#ls /home/rbac/.kube/
config

(三)RBAC授权

1.创建Role资源

cs 复制代码
[root@master01 rbac]#vim role.yaml
[root@master01 rbac]#cat role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role                  #创建Role资源
metadata:
  namespace: rbac-ns
  name: rbac-pod
rules:                      #定义授权的信息
- apiGroups: [""]           #指定资源核心组,例如Pod、Service等
  resources: ["pods"]       #指定对pod资源进行授权
  verbs: ["get", "watch", "list", "create"]
#授与get(获取)、watch(监听)、list(列出)、create(创建)权限
[root@master01 rbac]#kubectl apply -f role.yaml 
role.rbac.authorization.k8s.io/rbac-pod created
[root@master01 rbac]#kubectl get role -n rbac-ns 
NAME       CREATED AT
rbac-pod   2024-06-06T01:30:44Z
[root@master01 rbac]#kubectl describe role rbac-pod -n rbac-ns 
Name:         rbac-pod
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get watch list create]

2.Role绑定

cs 复制代码
[root@master01 rbac]#vim rolebind.yaml 
[root@master01 rbac]#cat rolebind.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding             #创建角色绑定资源
metadata:
  name: rolebind-pod
  namespace: rbac-ns
subjects:                     #定义了哪些用户、组或服务账户可以被这个RoleBinding授权
- kind: User                  #指定授权的主体类型是User(用户)
  name: rbac                  #指定用户的名称
  apiGroup: rbac.authorization.k8s.io  #指定API组,对于用户而言,不需要指定,可省略
roleRef:                      #引用Role或者ClusterRole
  kind: Role                  #定义了被引用的资源的类型为Role
  name: rbac-pod              #被引用的角色的名称
  apiGroup: rbac.authorization.k8s.io   #表示它们来自RBAC API组
[root@master01 rbac]#kubectl apply -f rolebind.yaml 
rolebinding.rbac.authorization.k8s.io/rolebind-pod created
[root@master01 rbac]#kubectl get rolebindings -n rbac-ns 
NAME           ROLE            AGE
rolebind-pod   Role/rbac-pod   9s
[root@master01 rbac]#kubectl describe rolebindings rolebind-pod -n rbac-ns 
Name:         rolebind-pod
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  Role
  Name:  rbac-pod
Subjects:
  Kind  Name  Namespace
  ----  ----  ---------
  User  rbac

(四)切换用户使用

在rbac用户指定操作内容

1.创建pod

cs 复制代码
[root@master01 ~]#su - rbac
上一次登录:四 6月  6 08:01:29 CST 2024pts/5 上
[rbac@master01 ~]$ kubectl get pod
No resources found in rbac-ns namespace. 
#默认的命名空间为rbac-ns
[rbac@master01 ~]$ kubectl run nginx --image=nginx:1.18.0
pod/nginx created
[rbac@master01 ~]$ kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          6s
--------------------------------------------------------------------------------------
#可以看到,rbac用于经过授权之后,可以进行查看以及创建pod的操作

2.其它权限

cs 复制代码
[rbac@master01 ~]$ kubectl get ns
Error from server (Forbidden): namespaces is forbidden: User "rbac" cannot list resource "namespaces" in API group "" at the cluster scope
#查看命名空间被权限拒绝
[rbac@master01 ~]$ kubectl get svc
Error from server (Forbidden): services is forbidden: User "rbac" cannot list resource "services" in API group "" in the namespace "rbac-ns"
#查看service资源被权限拒绝
[rbac@master01 ~]$ kubectl delete pod nginx
Error from server (Forbidden): pods "nginx" is forbidden: User "rbac" cannot delete resource "pods" in API group "" in the namespace "rbac-ns"
#同样的,没有对pod资源授予删除权限,所以无法删除
[rbac@master01 ~]$ kubectl get pod nginx
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          4m

-------------------------------------------------------------------------------------[root@master01 rbac]#kubectl get pod -n rbac-ns 
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          5m40s
#在root用户,同样可以查看到新建的pod

3.获取管理员权限

cs 复制代码
//在root用户中操作
[root@master01 rbac]#kubectl create rolebinding rbac-admin-binding --clusterrole=admin --user=rbac -n rbac-ns
#将rbac用户与admin集群角色进行绑定,并指定rbac-ns命名空间
#执行此命令后,rbac用户会拥有rbac-ns命名空间中所有的资源的管理权限
rolebinding.rbac.authorization.k8s.io/rbac-admin-binding created
[root@master01 rbac]#kubectl get rolebindings rbac-admin-binding -n rbac-ns 
NAME                 ROLE                AGE
rbac-admin-binding   ClusterRole/admin   20s

//在rbac用户中操作
[rbac@master01 ~]$ kubectl get service
No resources found in rbac-ns namespace.
[rbac@master01 ~]$ kubectl expose pod nginx --port=80 --target-port=80 --name=nginx-svc --type=NodePort
service/nginx-svc exposed
[rbac@master01 ~]$ kubectl get service -owide
NAME        TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE   SELECTOR
nginx-svc   NodePort   10.96.211.179   <none>        80:30309/TCP   8s    run=nginx
#可以看到,rbac用于拥有对其它资源的同样拥有操作权限

但是该管理员权限,仅限于指定的命名空间,无法所其它命名空间进行操作

在工作环境中,对于不同的层次,可以对指定的命令空间有不同的权限,负责人或领导也可能需要一个命名空间的所有权限,类似于一个项目,每个人都有不同的职责,一个人负责pod创建,一个人负责对外发布,各司其职,所有需要不同的权限,但是在赋权时一定要谨慎

声明式删除资源

cs 复制代码
[rbac@master01 ~]$ kubectl delete svc nginx-svc
service "nginx-svc" deleted
[rbac@master01 ~]$ kubectl delete pod nginx
pod "nginx" deleted
[rbac@master01 ~]$ kubectl get svc,pod
No resources found in rbac-ns namespace.
相关推荐
景天科技苑40 分钟前
【云原生开发】K8S多集群资源管理平台架构设计
云原生·容器·kubernetes·k8s·云原生开发·k8s管理系统
wclass-zhengge1 小时前
K8S篇(基本介绍)
云原生·容器·kubernetes
颜淡慕潇1 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
jjyangyou3 小时前
物联网核心安全系列——物联网安全需求
物联网·算法·安全·嵌入式·产品经理·硬件·产品设计
AltmanChan4 小时前
大语言模型安全威胁
人工智能·安全·语言模型
马船长4 小时前
红帆OA iorepsavexml.aspx文件上传漏洞
安全
昌sit!10 小时前
K8S node节点没有相应的pod镜像运行故障处理办法
云原生·容器·kubernetes
hikktn11 小时前
如何在 Rust 中实现内存安全:与 C/C++ 的对比分析
c语言·安全·rust
A ?Charis12 小时前
Gitlab-runner running on Kubernetes - hostAliases
容器·kubernetes·gitlab
茶馆大橘13 小时前
微服务系列五:避免雪崩问题的限流、隔离、熔断措施
java·jmeter·spring cloud·微服务·云原生·架构·sentinel