【Kubernetes】多用户管理身份认证,RBAC授权及准入控制

一,身份认证

1-1,账户分类

所有 Kubernetes 集群有两类用户:

第1类:ServiceAccounts(服务账户,简写sa)

用于对集群内服务设置账户验证。
ServiceAccount是Pod使用的账号。
Pod容器的进程需要访问API Server时,用的就是ServiceAccount账户。
ServiceAccount仅局限它所在的namespace,每个namespace创建时,都会自动创建一个default service account
创建Pod时,如果没有指定Service Account,Pod则会使用default Service Account。

# 创建一个ServiceAccounts用户new-user
kubectl create sa new-user
第2类: UsersAccounts (普通账户)

用于用户的登录,管理集群。
UserAccount是给kubernetes集群外部用户使用的。
例如:
kubectl访问k8s集群要用useraccount用户。
kubeadm安装的k8s,默认的useraccount用户是kubernetes-admin

APIServer需要对客户端做认证,使用kubeadm安装的K8s,会在用户家目录下创建一个认证配置文件 .kube/config 这里面保存了客户端访问API Server的密钥相关信息,这样当用kubectl访问k8s时,它就会自动读取该配置文件,向API Server发起认证,然后完成操作请求。

1-2,认证方式

  • 客户端认证。也叫双向TLS认证。kubectl和apiserver,两者通过ca根证书来进行验证。
  • Bearertoken。通过将一个密码通过了非对称加密的方式,达到互访。
  • Serviceaccount。是内部访问pod和apiserver交互时候采用的一种方式。
    它包括了namespace、token、ca,且通过目录挂载的方式给予pod,当pod运行起来的时候,就会读取到这些信息,从而使用该方式和apiserver进行通信。

1-3,kubeconfig文件

kubectl config view
显示如下:
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://192.168.40.180:6443     # apiserver的地址
  name: kubernetes                          # 集群的名字
contexts:
- context:
    cluster: kubernetes                     
    user: kubernetes-admin   
  name: kubernetes-admin@kubernetes           # 上下文的名字
current-context: kubernetes-admin@kubernetes  # 当前上下文的名字
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

二,RBAC授权

RBAC 是基于角色的访问控制(Role-Based Access Control )

2-1,四种角色

一个角色(或集群角色),包含一组权限,没有拒绝规则,只是附加允许。
作用:针对哪些资源,做哪些操作。

(1)角色:Role

它是 Namespace 级别的资源,只能作用于Namespace之内。

# 定义一个角色用来读取Pod的权限

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: rbac
  name: pod-read
rules:
- apiGroups: [""]
  resources: ["pods"]
  resourceNames: []
  verbs: ["get","watch","list"]

rules中的参数说明:
1、apiGroups:支持的API组列表,例如:"apiVersion: apps/v1"等
2、resources:支持的资源对象列表,例如pods、deployments、jobs等
3、resourceNames: 指定resource的名称
4、verbs:对资源对象的操作方法列表。

(2)集群角色:ClusterRole

它是集群内资源类型,可以作用于不同Namespace之间

# 定义一个集群角色可让用户访问任意secrets

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: secrets-clusterrole
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get","watch","list"]

还可用于以下特殊元素的授权:
1、集群范围的资源,例如Node
2、非资源型的路径,例如:/healthz
3、包含全部命名空间的资源,例如Pods

(3)角色绑定:RoleBinding

用于对服务账户和角色(Role 或 ClusterRole)的绑定。
作用于 Namespace 内。

(4) 集群角色绑定:ClusterRoleBinding

用于对服务账户和角色(仅限于ClusterRole)的绑定。
作用于集群内不同 Namespace之间 。

2-2,绑定对象

可以将UserGroupservice Account ,与角色Role集群角色ClusterRole进行绑定。

总共3中方案:

  • 基于rolebinding绑定到role上
  • 基于rolebinding绑定到clusterrole上
  • 基于clusterrolebinding绑定到clusterrole上

2-3,常用参数取值

Role和ClusterRole 的 rule下

  • apiGroups值:
"","apps", "autoscaling", "batch"
  • resources值:
"services", "endpoints", "pods","secrets","configmaps","crontabs","deployments","jobs","nodes","rolebindings","clusterroles","daemonsets","replicasets","statefulsets","horizontalpodautoscalers","replicationcontrollers","cronjobs"
  • verbs值:
"get", "list", "watch", "create", "update", "patch", "delete", "exec"

三,准入控制

对认证、鉴权后用户的操作,做规范的限制和变更验证。

3-1,常用准入控制器的模块

  • LimitRanger
  • ResourceQuota
  • ServiceAccount
  • PodSecurityPolicy (k8s1.25废弃了)

3-2,如何启用

LimitRanger、ResourceQuota、ServiceAccount 默认系统开启。
如何开启其他控件?

# cat /etc/kubernetes/manifests/kube-apiserver.yaml 

spec:
  containers:
  - command:
    - kube-apiserver
    - --advertise-address=192.168.40.180
    ...
    - --enable-admission-plugins=NodeRestriction  # 加入此配置, “NodeRestriction”
    ...

--enable-admission-plugins 选项来指定要启用的准入控制插件,该选项可以使用多个值,用逗号隔开。
在这里插入图片描述

3-3,ResourceQuota准入控制器的使用

该控制器是k8s上内置的准入控制器,默认是启用状态。
作用:
用来在名称空间级别,限制用户的资源使用。

示例:限制cpu、内存、pod、deployment数量
# 创建命名空间 ns-quota
kubectl create ns ns-quota

# cat ns-quota.yaml 
apiVersion: v1
kind: ResourceQuota     # 指定资源类型
metadata:
  name: rq-quota
  namespace: quota      # 指定命名空间
spec:
  hard:                          		# 定义资源限制规则
    pods: "6"                   		# 限制pod的数量
    requests.cpu: "2"           		# 限制所有pod的cpu下限总和
    requests.memory: "2Gi"        		# 限制所有pod的内存下限总和
    requests.storage: "5Gi"      		# 限制所有pod的存储下限总和
    requests.ephemeral-storage: "1Gi"   # 限制使用本地临时存储的下限总容量
    limits.cpu: "4"                     # 限制所有pod的cpu上限总和
    limits.memory: "10Gi"               # 限制所有pod的内存上限总和
    limits.ephemeral-storage: "2Gi"     # 限制使用本地临时存储的上限总容量
    count/deployments.apps: "6"  		# 限制apps群组下的deployments个数不超过6个
    persistentvolumeclaims: "6"  		# 限制pvc个数不能超过6个   

3-4,LimitRanger准入控制器的使用

该控制器是k8s上内置的准入控制器,默认是启用状态。是k8s上的一个标准资源。
作用:
定义在某个名称空间下创建pod时使用的cpu和内存的上限和下限以及默认cpu、内存的上下限。

示例:设置默认cpu、内存、pod、deployment资源使用
# 创建命名空间 ns-limit
kubectl create ns ns-limit

# cat limitrange.yaml 
apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-memory
  namespace: ns-limit
spec:
  limits:
  - default:           		# 指定默认容器资源上限值
      cpu: 1000m
      memory: 1000Mi
    defaultRequest:    		# 指定默认容器资源下限值
      cpu: 500m
      memory: 500Mi
    min:               		# 指定限制用户指定的资源下限不能小于对应资源的值
      cpu: 500m
      memory: 500Mi
    max:                    # max是用来限制用户指定资源上限值不能大于该值
      cpu: 2000m
      memory: 2000Mi
    maxLimitRequestRatio:   # 指定资源的上限和下限的比值
      cpu: 4
      memory: 4
    type: Container         # 用来描述对应资源限制的级别,取值 pod 或 container。

【说明】:
该资源清单表示在该名称空间下创建pod时,默认不指定其容器的资源限制,就限制对应容器最少要有0.5个核心的cpu和500M的内存;最大为1个核心cpu,1g内存;如果我们手动定义了容器的资源限制,那么对应资源限制最小不能小于cpu为0.5个核心,内存为500M,最大不能超过cpu为2个核心,内存为2000M;
如果我们在创建pod时,只指定了容器的资源上限或下限,那么上限最大是下限的的4倍,如果指定cpu上限为2000m那么下限一定不会小于500m,如果只指定了cpu下限为500m那么上限最大不会超过2000m,对于内存也是同样的逻辑。

四,应用示例

4-1,常见角色(role)授权的示例

(1)允许读取核心API组的Pod资源
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get","list","watch"]
(2)允许读写apps API组中的deployment资源
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get","list","watch","create","update","patch","delete"]
(3)允许读取Pod以及读写job信息
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get","list","watch"]
- apiGroups: [""]
  resources: ["jobs"]
  verbs: ["get","list","watch","create","update","patch","delete"]
(4)允许读取一个名为my-config的ConfigMap

(必须绑定到一个RoleBinding来限制到一个Namespace下的ConfigMap):

rules:
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["my-configmap"]
  verbs: ["get"]
(5)读取核心组的Node资源

(Node属于集群级的资源,所以必须存在于ClusterRole中,并使用ClusterRoleBinding进行绑定):

rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get","list","watch"]
(6)允许对非资源端点“/healthz”及其所有子路径进行GET和POST操作

(必须使用ClusterRole和ClusterRoleBinding):

rules:
- nonResourceURLs: ["/healthz","/healthz/*"]
  verbs: ["get","post"]

4-2,常见的角色绑定示例

(1)用户名alice
subjects:
- kind: User
  name: alice
  apiGroup: rbac.authorization.k8s.io
```  
#### (2)组名alice	

```yaml
subjects:
- kind: Group # 指定组名
  name: alice
  apiGroup: rbac.authorization.k8s.io
(3)kube-system命名空间中默认Service Account
subjects:
- kind: ServiceAccount
  name: default
  namespace: kube-system

4-3,常见的角色绑定(命令行)示例

(1)名称空间namespace中服务账户Service Account(mysa)授予只读权限
kubectl create rolebinding [rolebinding名称] --clusterrole=view --serviceaccount=[namespace名称]:mysa --namespace=[namespace名称]

【注意】:
--clusterrole=view:view 为系统自带“只读”角色。

k8s 内置集群角色: cluster-admin,admin ,edit ,view

  • cluster-admin 超级管理员,对集群所有权限,和linux下面root一样(在部署dashboard的时候,先创建sa,然后将sa绑定到角色cluster-admin,最后获取到token,这就使用了内置的cluster-admin )
  • admin 主要用于授权命名空间所有读写权限(针对于某个命名空间)
  • edit 允许对命名空间大多数对象读写操作,不允许查看或者修改角色、角色绑定。
  • view 允许对命名空间大多数对象只读权限,不允许查看角色、角色绑定和Secret。
(2)为一个命名空间中名为default的Service Account授权

如果一个应用没有指定 serviceAccountName,则会使用名为default的Service Account。
注意:赋予Service Account “default”的权限会让所有没有指定serviceAccountName的Pod都具有这些权限。

例如:在命名空间[namespace名称]中为Service Account“default”授予只读权限:

kubectl create rolebinding [rolebinding名称] --clusterrole=view --serviceaccount=[namespace名称]:default --namespace=[namespace名称]
(3)为命名空间中所有Service Account都授予一个角色

指定命名空间中,任何Service Account应用都具有一个角色,则可以为这一命名空间的Service Account群组进行授权

kubectl create rolebinding [rolebinding名称] --clusterrole=view --group=system:serviceaccounts:[namespace名称]  --namespace=[namespace名称]
(4)为集群范围内所有Service Account都授予“只读”角色

如果不想为每个命名空间管理授权,则可以把一个集群级别的角色赋给所有Service Account。

kubectl create clusterrolebinding [clusterrolebinding名称] --clusterrole=view --group=system:serviceaccounts

【注意】:
--group=system:serviceaccounts 代表集群范围内所有Service Account组

(5)为集群范围内所有Service Account授予“超级用户”权限
kubectl create clusterrolebinding [clusterrolebinding名称] --clusterrole=cluster-admin  --group=system:serviceaccounts

4-4,使用kubectl命令行工具创建资源对象

(1)在命名空间[namespace名称]中为用户mdy授权admin ClusterRole:
kubectl create rolebinding [rolebinding名称] --clusterrole=admin --user=mdy --namespace=[namespace名称]

(2)在命名空间rbac中为名为myapp的Service Account授予view ClusterRole:
kubctl create rolebinding [rolebinding名称] --clusterrole=view --serviceaccount=[namespace名称]:myapp --namespace=[namespace名称]

(3)在全集群范围内为用户root授予cluster-admin ClusterRole:
kubectl create clusterrolebinding [clusterrolebinding名称] --clusterrole=cluster-admin --user=root

(4)在全集群范围内为名为myapp的Service Account授予view ClusterRole:
kubectl create clusterrolebinding [clusterrolebinding名称] --clusterrole=view --serviceaccount=myapp

五,案例

5-1,RBAC创建服务账户并绑定角色

本案例将通过服务账号serviceAccount ,角色role,rolebinding,命名空间namespace, 创建用户只能访问指定空间下的pod。

第1步:创建命名空间

创建一个命名空间namespace,命名为ns-read-pod

kubectl create ns ns-read-pod
第2步:创建服务账户

在命名空间(ns-read-pod)下,创建一个服务账户serviceAccount ,命名为sa-read-pod

kubectl create sa sa-read-pod -n ns-read-pod
第3步:创建角色

创建一个角色role,命名为role-read-pod,对该命名空间(ns-read-pod)下的pod,仅设置权限。

# cat role-read-pod.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata: 
  name: role-read-pod        # 角色名称
  namespace: ns-read-pod     # 指定命名空间
rules:
- apiGroups: [""]                   # 资源组,为空 代表默认所有
  resources: ["pods","pods/log"]    # 指定资源类型
  resourceNames: [""]               # 不设置,代表多有pod
  verbs: ["get", "watch", "list"]   # 只有读权限
第4步:rolebinding绑定,即授权

创建一个rolebinding,命名为rolebinding-read-pod,将角色(role-read-pod)和服务账号(sa-read-pod)进行绑定。

【命令行】创建:

kubectl create rolebinding rolebinding-read-pod  -n ns-read-pod --role=role-read-pod  --serviceaccount=ns-read-pod:sa-read-pod

【Ymal】创建:

# cat rolebinding-read-pod.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: rolebinding-read-pod2
  namespace: ns-read-pod
subjects:                   # 定义绑定的账号
- kind: ServiceAccount      # 定义账号类型:"User","Group","ServiceAccount"
  name: sa-read-pod         # 具体账号名称
  namespace: ns-read-pod    # 定义账号所在命名空间
  apiGroup: ""
roleRef:                    # 定义绑定的角色
  kind: Role                # 定义角色类型:Role,ClusterRole
  name: role-read-pod       # 具体角色名称
  apiGroup: rbac.authorization.k8s.io
第5步:创建pod,绑定sa账号

创建一个pod,命名为pod-read-pod,在命名空间(ns-read-pod)下,绑定serviceAccount服务账户(sa-read-pod)

# cat pod-read-pod.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: pod-read-pod                  # pod名称
  namespace: ns-read-pod              # 指定命名空间
  labels:
    app: read-pod
spec:
  serviceAccountName: sa-read-pod     # 绑定SA账户
  containers:
  - name: container-read-pod
    image: nginx
    imagePullPolicy: IfNotPresent
第6步:进入pod,用证书访问k8s资源
# 进入pod
kubectl exec -it pod-read-pod -n ns-read-pod -- /bin/bash

# 进入指定目录
cd /var/run/secrets/kubernetes.io/serviceaccount/

# 通过证书,访问kubernets资源
curl --cacert ./ca.crt  -H "Authorization: Bearer $(cat ./token)"  https://kubernetes.default/api/v1/namespaces/ns-read-pod/pods

在这里插入图片描述
至此,成功访问集群内的pods!!

如果有以下提示(403错误),代表授权失败:
在这里插入图片描述

5-2,限制不同普通用户,操作k8s集群

应用场景:
针对刚入职新的运维员工,开设服务器账号:yunwei,密码:123456
权限:
新员工k8s账号,只能有访问命名空间(k8s-test)内的资源。

第1步:ssl认证

针对普通用户k8s-admin,做ssl认证后,已被APIserver信任,该用户可以访问apiServer,但是还没有任何操作权限。

# 进入pki目录
cd /etc/kubernetes/pki/

# 生成一个私钥
(umask 077; openssl genrsa -out k8s-admin.key 2048) 

# 生成一个账号名为 k8s-admin 的证书请求
openssl req -new -key k8s-admin.key -out k8s-admin.csr -subj "/CN=k8s-admin"

# 生成一个证书 k8s-admin.crt
openssl x509 -req -in k8s-admin.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out k8s-admin.crt -days 3650
第2步:在kubeconfig下新增加用户k8s-admin
# 对config文件备份,以免出差恢复
cp /root/.kube/config /root/.kube/config.backup

# 把用户k8s-admin添加到kubernetes集群中(用来认证apiserver的连接)
kubectl config set-credentials k8s-admin --client-certificate=./k8s-admin.crt --client-key=./k8s-admin.key --embed-certs=true

# 把用户k8s-admin添加到kubernetes集群中的“上下文”中
kubectl config set-context k8s-admin@kubernetes --cluster=kubernetes --user=k8s-admin

执行以上命令后,关于k8s-admin的用户,已经加入到kubernetes配置文件(config)的**“用户”“上下文”**中:
在这里插入图片描述
在这里插入图片描述

kubectl配置相关命令,可以通过 kubectl config --help 查看具体操作。

第3步:对k8s内,普通用户k8s-admin授权

对用户授权:仅仅对命名空间k8s-test下有管理员cluster-admin权限。

# 创建名称空间k8s-test
kubectl create ns k8s-test

# 将用户k8s-admin通过rolebinding绑定到clusterrole上,限制在命名空间k8s-test里有效。
kubectl create rolebinding k8s-admin-rolebinding  --clusterrole=cluster-admin --user=k8s-admin -n k8s-test

# 切换到k8s-admin这个用户
kubectl config use-context k8s-admin@kubernetes

# 测试是否仅仅在命名空间(k8s-test)内,有权限访问pod
kubectl get pods -n k8s-test
第4步:更改config配置,增加linux服务账号
# 将配置文件拷贝到root下(其他位置也可以)进行更改
cp /root/.kube/config  /root/

删除’/root/config’ 文件内容:
在这里插入图片描述
在这里插入图片描述
config文件已经改好,放到linux新账号的“家目录”即可。

# 在contos服务器创建新的登录账号:yunwei  密码:123456
useradd yunwei
passwd yunwei
第5步:更改config配置路径,测试访问kubernetes
mkdir -p /home/yunwei/.kube/
cp -ar /root/config /home/yunwei/.kube/
chown -R yunwei:yunwei /home/yunwei/

在这里插入图片描述
至此,整个账号权限开设完毕!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一直奔跑在路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值