k8s的认证和鉴权

认证和授权

环境准备

[root@master30 ~]# kubectl create ns auth
[root@master30 ~]# kubectl config set-context --current --namespace auth
鉴权概述

Kubernetes API 服务器对 API 请求进行鉴权。 它根据所有策略评估所有请求属性来决定允许或拒绝请求。 一个 API 请求的所有部分都必须被某些策略允许才能继续。 这意味着默认情况下拒绝权限。

当系统配置了多个鉴权模块时,Kubernetes 将按顺序使用每个模块。

如果任何鉴权模块批准或拒绝请求,则立即返回该决定,并且不会与其他鉴权模块协商。

如果所有模块对请求没有意见,则拒绝该请求。 被拒绝响应返回 HTTP 状态代码 403。

鉴权模式

鉴权模式定义认证成功的用户对集群的操作权限,由kube-apiserver配置文件指定:

[root@master30 ~]# cat /etc/kubernetes/manifests/kube-apiserver.yaml |grep mode
    - --authorization-mode=Node,RBAC

我们这里使用RBAC和Node模式。

支持的模式:

  • Node,是节点专用的鉴权模式,根据调度到 kubelet 上运行的 Pod 为 kubelet 授予权限。 要了解有关使用节点鉴权模式的更多信息,请参阅节点鉴权
  • ABAC,基于属性的访问控制(ABAC)定义了一种访问控制范型,通过使用将属性组合在一起的策略, 将访问权限授予用户。策略可以使用任何类型的属性(用户属性、资源属性、对象,环境属性等)。 要了解有关使用 ABAC 模式的更多信息,请参阅 ABAC 模式
  • RBAC,基于角色的访问控制(RBAC) 是一种基于企业内个人用户的角色来管理对计算机或网络资源的访问的方法。要了解有关使用 RBAC 模式的更多信息,请参阅 RBAC 模式
    • 被启用之后,RBAC(基于角色的访问控制)使用 rbac.authorization.k8s.io API 组来驱动鉴权决策,从而允许管理员通过 Kubernetes API 动态配置权限策略。
    • 要启用 RBAC,请使用 --authorization-mode = RBAC 启动 API 服务器。
  • Webhook —— WebHook 是一个 HTTP 回调:发生某些事情时调用的 HTTP POST; 通过 HTTP POST 进行简单的事件通知。 实现 WebHook 的 Web 应用程序会在发生某些事情时将消息发布到 URL。 要了解有关使用 Webhook 模式的更多信息,请参阅 Webhook 模式
  • AlwaysAllow,允许用户所有请求。
# 前面我们删除了用户laoma权限,更改为AlwaysAllow模式,测试laoma用户权限。
[root@master30 ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml
......
# 在spec.containers下的command中添加参数- --basic-auth-file=/etc/kubernets/pki/aa.csv
spec:
  containers:
  - command:
    - --authorization-mode=AlwaysAllow
......

# 更改完成后,kubernetes会自动重启pod/kube-apiserver,等该pod状态为running再次验证。
[root@client ~]# kubectl get nodes
NAME                   STATUS   ROLES           AGE   VERSION
master30.laoma.cloud   Ready    control-plane   12d   v1.30.2
worker31.laoma.cloud   Ready    <none>          12d   v1.30.2
worker32.laoma.cloud   Ready    <none>          12d   v1.30.2
  • AlwaysDeny,拒绝用户所有请求,不管用户是否具有权限,但不限制admin用户。

role 管理

kubernetes 方便管理权限,将一组特定权限赋予角色,然后将角色赋予用户,那么用户将继承该角色具有的权限。

角色分类
  • role,namespace 角色,限定用户访问特定namespace。role绑定给用户,称之为rolebinding

  • clusterrole,cluster 角色,可以管理集群,包括所有namespace中资源。clusterrole绑定给用户,称之为clusterrolebinding

权限由kubernetes系统预定义的,clusterroles/admin中包涵系统中全部权限列表。

[root@master30 ~]# kubectl describe clusterroles admin
Name:         admin
Labels:       kubernetes.io/bootstrapping=rbac-defaults
Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
  Resources                                       Non-Resource URLs  Resource Names  Verbs
  ---------                                       -----------------  --------------  -----
  rolebindings.rbac.authorization.k8s.io          []                 []              [create delete deletecollection get list patch update watch]
  roles.rbac.authorization.k8s.io                 []                 []              [create delete deletecollection get list patch update watch]
  configmaps                                      []                 []              [create delete deletecollection patch update get list watch]
  endpoints                                       []                 []              [create delete deletecollection patch update get list watch]
......

输出说明:

  • Resources:代表系统中资源类型,例如Secret,Configmap等。

  • Resource Names:代表特定资源。如果Resources是Secret,那么这里就指特定Secret。

  • Non-Resource URLs: 被称为非资源URL或虚拟URL对象,是k8s中所需要的特殊动作(不需要关注)。

  • Verbs:代表针对资源执行的动作,包括操作get、list、create、delete、update、edit、watch、exec。

    • get,用于获得特定资源信息,例如,针对pod,可以执行GET /api/v1/namespaces/{namespace}/pods/{podname}
[root@client ~]# kubectl get pod -n kube-system 
Error from server (Forbidden): pods is forbidden: User "laoma" cannot list resource "pods" in API group "" in the namespace "kube-system"

[root@client ~]# kubectl get pod kube-proxy-8kp8w -n kube-system 
NAME               READY   STATUS    RESTARTS   AGE
kube-proxy-8kp8w   1/1     Running   4          52d

list,用户查看某一类型资源清单,例如针对pod,可以执行GET /api/v1/namespaces/{namespace}/pods

[root@client ~]# kubectl get pod -n kube-system 
NAME                                        READY   STATUS    RESTARTS   AGE
calico-kube-controllers-6dfcd885bf-lq4n5    1/1     Running   4          52d
calico-node-44cf4                           1/1     Running   4          52d
calico-node-48sm4                           1/1     Running   4          52d
.....

[root@client ~]# kubectl get pod kube-proxy-8kp8w -n kube-system 
Error from server (Forbidden): pods "kube-proxy-8kp8w" is forbidden: User "laoma" cannot get resource "pods" in API group "" in the namespace "kube-system"
创建 role
[root@master30 ~]# kubectl create role -h
Create a role with single rule.

Usage:
  kubectl create role NAME --verb=verb --resource=resource.group/subresource
[--resource-name=resourcename] [--dry-run=server|client|none] [options]

示例1:可以对项目中所有pods执行get、list、watch操作

[root@master30 ~]# kubectl create role pod-role --verb=get,list,watch --resource=pods -n default --dry-run=client -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: pod-role
  namespace: default
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
[root@master30 ~]# kubectl create role pod-role --verb=get,list,watch --resource=pods -n default

[root@master30 ~]# kubectl get roles pod-role -n default
NAME         CREATED AT
pod-role   2021-08-24T10:24:36Z

[root@master30 ~]# kubectl describe roles pod-role -n default
Name:         pod-role
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get list watch]

示例2:访问特定资源pods/readablepod

[root@master30 ~]# kubectl create role pod-role --verb=get --resource=pods \
--resource-name=readablepod --resource-name=anotherpod

示例3:可以对项目中所有replicasets执行get list watch操作

[root@master30 ~]# kubectl create role foo --verb=get,list,watch --resource=replicasets
修改 role
# 增加create权限
[root@master30 ~]# kubectl edit roles -n default pod-role
......
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
# 在verbs下添加相应权限
  - list
  - get
  - watch
  - creat

apiGroups

  • 角色的 rules 属性中 apiGroups 默认为空

  • pod、service 资源的 apiVersion 是v1,apiGroups为""。

  • Deployment、DaemonSet 资源的 apiVersion 是apps/v1,apiGroups为"apps"。如下:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      creationTimestamp: null
      name: deployments-role
      namespace: default
    rules:
    - apiGroups:
      - "apps"
      resources:
      - deployments
      verbs:
      - get
      - list
      - watch
    

**示例1:**定义角色,无法操作deployments,因为apiGroups未指定apps

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: deployments-role
  namespace: default
rules:
- apiGroups:
  - ""
  resources:
  - deployments
  verbs:
  - get
  - list
  - watch

**示例2:**定义一个可以 scale deployments 的角色

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: deployments-role
  namespace: default
rules:
- apiGroups:
  - "apps"
  resources:
  - deployments
  # 额外添加以下资源
  - deployments/scale
  verbs:
  - get
  - list
  - watch
  # 额外添加以下权限
  - patch

**示例3:**定义一个对不同类型资源赋予不同权限的角色。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: all-role
  namespace: default
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - "apps"
  resources:
  - deployments
  - deployments/scale
  verbs:
  - get
  - list
  - watch
  - patch
常见apiGroups
TypeapiVersionapiGroups
Pod、Service、PersistentVolume、PersistentVolumeClaimv1“”
Deployment、DaemonSet、StatefulSetsapps/v1apps
Jobbatch/v1batch
CronJobbatch/v1beta1batch
Role RoleBinding ClusterRole ClusterRoleBindingrbac.authorization.k8s.io/v1rbac.authorization.k8s.io
NetworkPolicynetworking.k8s.io/v1networking.k8s.io

每种类型资源的 apiVersion 都可以通过以下命令查询:

[root@master30 ~]# kubectl explain deployment|grep VERSION
VERSION:  apps/v1

[root@master30 ~]# kubectl explain networkpolicy|grep VERSION
VERSION:  networking.k8s.io/v1
# 或者
root@master30:~/auth# kubectl api-resources |grep -i deploy
deployments                       deploy       apps/v1                                true         Deployment

role 绑定

将 role 绑定给用户。

[root@master30 ~]# kubectl create rolebinding default-pod-laoma -n default --role=pod-role --user=laoma --dry-run=client -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  creationTimestamp: null
  name: default-pod-laoma
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pod-role
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: laoma
# 绑定 ns/default 中角色 pod-role 给 laoma
[root@master30 ~]# kubectl create rolebinding default-pod-laoma -n default --role=pod-role --user=laoma
# 角色绑定完成后,角色的权限发生变化,用户获得的权限也会跟着动态变化。

[root@master30 ~]# kubectl get rolebindings -n default default-pod-laoma 
NAME                    ROLE              AGE
default-pod-laoma   Role/pod-role   2m15s

[root@master30 ~]# kubectl describe rolebindings -n default default-pod-laoma 
Name:         default-pod-laoma
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  Role
  Name:  pod-role
Subjects:
  Kind  Name   Namespace
  ----  ----   ---------
  User  laoma 

验证

[root@client ~]# kubectl run web --image=docker.io/library/httpd --image-pull-policy=IfNotPresent -n default

[root@client ~]# kubectl get pod -n default
NAME   READY   STATUS    RESTARTS   AGE
web    1/1     Running   0          2m30s


[root@client ~]# kubectl get pod -n default -w
NAME   READY   STATUS    RESTARTS   AGE
web    1/1     Running   0          2m42s

role 回收

[root@master30 ~]# kubectl delete rolebindings default-pod-laoma -n kube-system 
rolebinding.rbac.authorization.k8s.io "default-pod-laoma" deleted

# 再次验证
[root@client ~]# kubectl get pod -n default
Error from server (Forbidden): pods is forbidden: User "laoma" cannot list resource "pods" in API group "" in the namespace "default"

role 删除

[root@master30 ~]# kubectl delete roles pod-role -n default

clusterrole 管理

常见 clusterrole

kubernetes系统中已经预定义了很多clusterrole,常见的clusterrole如下:

  • view,对系统中几乎所有的对象都有get、list和watch权限。
  • edit,对系统中几乎所有的对象都有get、list和watch权限。其中部分对象额外具有 create、delete、deletecollection、patch、update 权限。
  • admin,对系统中大部分的对象具有所有权限。
  • cluster-admin,对系统中所有的对象具有所有权限。

创建 clusterrole

[root@master30 ~]# kubectl create clusterrole -h
Usage:
  kubectl create clusterrole NAME --verb=verb --resource=resource.group
[--resource-name=resourcename] [--dry-run=server|client|none] [options]

示例1:创建一个可以get、list、watch所有项目中pods的clusterrole

[root@master30 ~]# kubectl create clusterrole pod-role --verb=get,list,watch --resource=pods --dry-run=client -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  creationTimestamp: null
  name: pod-role
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
[root@master30 ~]# kubectl create clusterrole pod-role --verb=get,list,watch --resource=pods

[root@master30 ~]# kubectl get clusterrole pod-role
NAME       CREATED AT
pod-role   2021-08-25T14:31:21Z

[root@master30 ~]# kubectl describe clusterrole pod-role
Name:         pod-role
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get list watch]
[root@master30 ~]# kubectl create clusterrole pod-role --verb=get,list,watch --resource=pods

[root@master30 ~]# kubectl get clusterrole pod-role
NAME       CREATED AT
pod-role   2021-08-25T14:31:21Z

[root@master30 ~]# kubectl describe clusterrole pod-role
Name:         pod-role
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get list watch]

示例2:创建一个可以get、list、watch所有项目中pods/readablepod和pods/anotherpod的clusterrole

[root@master30 ~]# kubectl create clusterrole pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod

示例3:创建一个可以get、list、watch所有项目中pods和pods/status的clusterrole

[root@master30 ~]# kubectl create clusterrole foo --verb=get,list,watch --resource=pods,pods/status
修改 clusterrole
[root@master30 ~]# kubectl edit clusterrole pod-role
......
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
  # 添加create权限
  - create
clusterrole 绑定

将clusterrole绑定给用户。

[root@master30 ~]# kubectl create clusterrolebinding laoma-pod-role --clusterrole=pod-role --user=laoma --dry-run=client -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  creationTimestamp: null
  name: laoma-pod-role
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: pod-role
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: laoma
[root@master30 ~]# kubectl create clusterrolebinding laoma-pod-role --clusterrole=pod-role --user=laoma

[root@master30 ~]# kubectl get clusterrolebinding laoma-pod-role
NAME             ROLE                   AGE
laoma-pod-role   ClusterRole/pod-role   35s

[root@master30 ~]# kubectl describe clusterrolebinding laoma-pod-role
Name:         laoma-pod-role
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  pod-role
Subjects:
  Kind  Name   Namespace
  ----  ----   ---------
  User  laoma

# client节点使用laoma用户测试权限
[root@client ~]# kubectl get pod -n kube-system
NAME                                        READY   STATUS    RESTARTS   AGE
calico-kube-controllers-6dfcd885bf-lq4n5    1/1     Running   6          53d
calico-node-44cf4                           1/1     Running   6          53d
......

[root@client ~]# kubectl get pod -n default 
NAME   READY   STATUS    RESTARTS   AGE
web    1/1     Running   1          15h
clusterrole 回收
[root@master30 ~]# kubectl delete clusterrolebinding laoma-pod-role
删除 clusterrole
[root@master30 ~]# kubectl delete clusterrole pod-reader
实践 1:角色管理
  1. 在 auth 命名空间,创建角色 pod-reader,针对pod,具备权限get、list、watch
  2. 赋予 laoma 用户 auth 命名空间 角色 pod-reader
  3. 管理员身份在 auth 命名空间创建 deployment
  4. 回收laoma 用户 集群管理员角色 cluster-admin(如果存在)
  5. laoma 用户验证:查看deployment和pod
  6. 清理资源:回收用户角色,删除 deployment
实践 2:使用现有集群角色
  1. 赋予 laoma 用户集群角色 admin,指定在auth命名空间
  2. laoma 用户在 auth 命名空间:创建、查看和删除 deployment
  3. laoma 用户在 default 命名空间:创建、查看和删除 deployment
  4. 回收 laoma 用户权限

结果:绑定集群角色的时候,限定特定命名空间是没有意义的,仍然针对集群级别所有命名空间生效。

实践 3:自定义集群角色
  1. 创建 clusterrole 名称 cluster-pod-deploy-reader,能够查看pod和deployment
  2. 赋予给 laoma 用户
  3. laoma 用户在 auth 命名空间中:查看pod、deployment
  4. laoma 用户在 kube-system 命名空间中:查看pod、deployment
  5. 删除集群角色绑定和集群角色

更多推荐