K8S - Access Control 机制介绍

作为开发人员, 我们通常会直接用root 帐号操作 k8s master node 里的kubectl 命令,并不能感知k8s 多用户权限管理存在。

即使自动化, 我们也会考虑用ansible 来远程操作master node...

所以大部分开发人员默认上是不用深入研究k8s的Access control的

但是作为SRE 或者 DevOps 开发, 理解一下还是有好处, 当然本文也只是介绍个基本概念,也不会深入。

K8S 权限认证机制介绍

Kubernetes(K8s)的权限认证机制主要涉及认证(Authentication)和授权(Authorization)两个方面:

Authentication 包括用户验证与 服务帐号(SA) 认证

至于Authorization 授权方面, 就是我们常见的RBAC (Role-based Access Control)

如下图, 其实一切对k8s集群的管理操作都是通过api service 去调用nodes 的kubelet 去完成

而认证和授权是在api service 里完成的, 任何调用 api service 里的api之前都必须pass 认证和授权

K8S 的用户帐号

在 Kubernetes 中,用户账户(User Account)通常不是直接管理的资源,而是由身份验证插件和身份提供者处理的。这些身份提供者可以包括基本身份验证、证书认证、令牌认证、OpenID Connect 等。当用户成功进行身份验证后,Kubernetes 将使用其提供的身份信息调用集群中的授权插件来确定用户是否有权限执行请求的操作。

要创建用户账户,您通常需要依赖外部的身份提供者,比如 LDAP、Active Directory、OpenID Connect 等。这些身份提供者负责验证用户身份,并将验证成功的用户映射到 Kubernetes 中的特定用户账户。

总之, 一般情况下我们用不上它, 除非大型企业下的k8s 平台会考虑使用User 帐号。

K8S 的Service account 服务帐号

反而, k8s的sa 我们更应该重点关注, 因为sa 可以被k8s 本身管理, 包括sa 的创建和授权

通常1个namespace 被创建, 该namespace 会被自动创建1个名字叫default的 sa

我们可以下面命令来查看某个namespace 的sa

bash 复制代码
gateman@MoreFine-S500: conf$ kubectl get sa -n default
NAME      SECRETS   AGE
default   1         206d

K8S 的Service account 和 用户帐号的对比

  1. User 帐号是针对人的, 服务帐号针对POD 进程
  2. User 帐号是全局的, 在所有的namespace中 必须唯一, 而sa 是属于某个namespace的, 多个namespace 可以有同名的sa
  3. 通常User帐号与企业的用户数据库(例如LDAP)同步, 而sa 的创建和使用更加轻量化, 允许集群用户为特定任务创建sa
  4. 对于复杂系统的配置包(helm chart), 可以包括对该系统的各种组建的sa的定义

Service Account Admission Controller

这个控制器主要是管理POD 的sa 设置

它是 apiserver 的一部分。当1个POD 被创建和修改时

  1. 如果POD 没有被设置sa, 那么它会将POD 的sa 设为 default (default 是1个sa)
  2. 确保POD 引用的sa 存在, 否则会拒绝POD的创建和修改请求
  3. 如果POD 不包含任何 ImagePullSecret, 则将SA 的imagePullSecret 添加到POD中(前提是该SA 配置了ImagePullSecret
  4. 为包含API访问的token的POD添加了1个Volume, 挂载在/var/run/secrets/kubernetes.io/serviceaccount(容器里)

例子, 把default 的 token mount在pod里了

bash 复制代码
gateman@MoreFine-S500: conf$ kubectl exec -it deployment-cloud-order-5f46d97659-2d7nk /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.


bash-4.4# pwd
/var/run/secrets/kubernetes.io/serviceaccount
bash-4.4# ls
ca.crt	namespace  token
bash-4.4# cat namespace 
default

Token Controller

每个sa 都观念1个token 就是 Token Controller 管理的

Service Account Controller

很简单, 这个controller 会管理namespace 的sa

他会确保每个namespace 会存在1个名字叫default的sa

Role

作用范围:Role 专注于特定命名空间(Namespace-specific)。它定义了对特定命名空间内资源的权限。

应用对象:Role 通常用于控制对该命名空间内资源的访问权限。

示例用途:可以为特定命名空间内的用户或 ServiceAccount 分配 Role,以限制其对该命名空间内资源的操作权限。

可以用下面命令来查看分别每个namespace 的role

bash 复制代码
gateman@MoreFine-S500: conf$ kubectl get role --all-namespaces
NAMESPACE       NAME                                             CREATED AT
ingress-nginx   ingress-nginx                                    2024-06-24T18:17:27Z
kube-public     kubeadm:bootstrap-signer-clusterinfo             2024-02-23T20:44:20Z
kube-public     system:controller:bootstrap-signer               2024-02-23T20:44:19Z
kube-system     extension-apiserver-authentication-reader        2024-02-23T20:44:19Z
kube-system     kube-proxy                                       2024-02-23T20:44:20Z
kube-system     kubeadm:kubelet-config-1.23                      2024-02-23T20:44:19Z
kube-system     kubeadm:nodes-kubeadm-config                     2024-02-23T20:44:19Z
kube-system     system::leader-locking-kube-controller-manager   2024-02-23T20:44:19Z
kube-system     system::leader-locking-kube-scheduler            2024-02-23T20:44:19Z
kube-system     system:controller:bootstrap-signer               2024-02-23T20:44:19Z
kube-system     system:controller:cloud-provider                 2024-02-23T20:44:19Z
kube-system     system:controller:token-cleaner                  2024-02-23T20:44:19Z

可以见default namespace 是没有role 定义的

查看具体Role的权限,

我们就查看上面的ingress-nginx

bash 复制代码
gateman@MoreFine-S500: conf$ kubectl get role ingress-nginx -n ingress-nginx -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  annotations:
    meta.helm.sh/release-name: ingress-nginx
    meta.helm.sh/release-namespace: ingress-nginx
  creationTimestamp: "2024-06-24T18:17:27Z"
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
    helm.sh/chart: ingress-nginx-4.10.1
  name: ingress-nginx
  namespace: ingress-nginx
  resourceVersion: "3038700"
  uid: f27340df-0f11-448d-8591-baaca1b28989
rules:
- apiGroups:
  - ""
  resources:
  - namespaces
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - configmaps
  - pods
  - secrets
  - endpoints
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - services
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses/status
  verbs:
  - update
- apiGroups:
  - networking.k8s.io
  resources:
  - ingressclasses
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - coordination.k8s.io
  resourceNames:
  - ingress-nginx-leader
  resources:
  - leases
  verbs:
  - get
  - update
- apiGroups:
  - coordination.k8s.io
  resources:
  - leases
  verbs:
  - create
- apiGroups:
  - ""
  resources:
  - events
  verbs:
  - create
  - patch
- apiGroups:
  - discovery.k8s.io
  resources:
  - endpointslices
  verbs:
  - list
  - watch
  - get

ClusterRole

作用范围:ClusterRole 跨越整个集群,即集群范围(Cluster-wide)。它定义了对整个集群中资源的权限。

应用对象:ClusterRole 用于控制对集群级资源的访问权限,例如节点、命名空间等。

示例用途:可以为具有全局职责的用户或 ServiceAccount 分配 ClusterRole,以允许他们对整个集群的资源进行操作。

由于ClusterRole 是for all namespaces的, 我们可以下面命令来查看所有namespace的clusterrole

bash 复制代码
gateman@MoreFine-S500: conf$ kubectl get clusterrole
NAME                                                                   CREATED AT
admin                                                                  2024-02-23T20:44:18Z
cluster-admin                                                          2024-02-23T20:44:18Z
edit                                                                   2024-02-23T20:44:18Z
flannel                                                                2024-03-08T18:25:29Z
ingress-nginx                                                          2024-06-24T18:17:26Z
kubeadm:get-nodes                                                      2024-02-23T20:44:20Z
system:aggregate-to-admin                                              2024-02-23T20:44:18Z
system:aggregate-to-edit                                               2024-02-23T20:44:18Z
system:aggregate-to-view                                               2024-02-23T20:44:18Z
system:auth-delegator                                                  2024-02-23T20:44:18Z
system:basic-user                                                      2024-02-23T20:44:18Z
system:certificates.k8s.io:certificatesigningrequests:nodeclient       2024-02-23T20:44:18Z
system:certificates.k8s.io:certificatesigningrequests:selfnodeclient   2024-02-23T20:44:18Z
system:certificates.k8s.io:kube-apiserver-client-approver              2024-02-23T20:44:18Z
system:certificates.k8s.io:kube-apiserver-client-kubelet-approver      2024-02-23T20:44:18Z
system:certificates.k8s.io:kubelet-serving-approver                    2024-02-23T20:44:18Z
system:certificates.k8s.io:legacy-unknown-approver                     2024-02-23T20:44:18Z
system:controller:attachdetach-controller                              2024-02-23T20:44:18Z
system:controller:certificate-controller                               2024-02-23T20:44:19Z
system:controller:clusterrole-aggregation-controller                   2024-02-23T20:44:18Z
system:controller:cronjob-controller                                   2024-02-23T20:44:18Z
system:controller:daemon-set-controller                                2024-02-23T20:44:18Z
system:controller:deployment-controller                                2024-02-23T20:44:18Z
system:controller:disruption-controller                                2024-02-23T20:44:18Z
system:controller:endpoint-controller                                  2024-02-23T20:44:18Z
system:controller:endpointslice-controller                             2024-02-23T20:44:18Z
system:controller:endpointslicemirroring-controller                    2024-02-23T20:44:18Z
system:controller:ephemeral-volume-controller                          2024-02-23T20:44:18Z
system:controller:expand-controller                                    2024-02-23T20:44:18Z
system:controller:generic-garbage-collector                            2024-02-23T20:44:18Z
system:controller:horizontal-pod-autoscaler                            2024-02-23T20:44:18Z
system:controller:job-controller                                       2024-02-23T20:44:18Z
system:controller:namespace-controller                                 2024-02-23T20:44:18Z
system:controller:node-controller                                      2024-02-23T20:44:18Z
system:controller:persistent-volume-binder                             2024-02-23T20:44:18Z
system:controller:pod-garbage-collector                                2024-02-23T20:44:19Z
system:controller:pv-protection-controller                             2024-02-23T20:44:19Z
system:controller:pvc-protection-controller                            2024-02-23T20:44:19Z
system:controller:replicaset-controller                                2024-02-23T20:44:19Z
system:controller:replication-controller                               2024-02-23T20:44:19Z
system:controller:resourcequota-controller                             2024-02-23T20:44:19Z
system:controller:root-ca-cert-publisher                               2024-02-23T20:44:19Z
system:controller:route-controller                                     2024-02-23T20:44:19Z
system:controller:service-account-controller                           2024-02-23T20:44:19Z
system:controller:service-controller                                   2024-02-23T20:44:19Z
system:controller:statefulset-controller                               2024-02-23T20:44:19Z
system:controller:ttl-after-finished-controller                        2024-02-23T20:44:19Z
system:controller:ttl-controller                                       2024-02-23T20:44:19Z
system:coredns                                                         2024-02-23T20:44:20Z
system:discovery                                                       2024-02-23T20:44:18Z
system:heapster                                                        2024-02-23T20:44:18Z
system:kube-aggregator                                                 2024-02-23T20:44:18Z
system:kube-controller-manager                                         2024-02-23T20:44:18Z
system:kube-dns                                                        2024-02-23T20:44:18Z
system:kube-scheduler                                                  2024-02-23T20:44:18Z
system:kubelet-api-admin                                               2024-02-23T20:44:18Z
system:monitoring                                                      2024-02-23T20:44:18Z
system:node                                                            2024-02-23T20:44:18Z
system:node-bootstrapper                                               2024-02-23T20:44:18Z
system:node-problem-detector                                           2024-02-23T20:44:18Z
system:node-proxier                                                    2024-02-23T20:44:18Z
system:persistent-volume-provisioner                                   2024-02-23T20:44:18Z
system:public-info-viewer                                              2024-02-23T20:44:18Z
system:service-account-issuer-discovery                                2024-02-23T20:44:18Z
system:volume-scheduler                                                2024-02-23T20:44:18Z
view                                                                   2024-02-23T20:44:18Z

同样我们可以用下命令来查看某个clusterrole的具体权限

bash 复制代码
gateman@MoreFine-S500: conf$ kubectl get clusterrole cluster-admin -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  creationTimestamp: "2024-02-23T20:44:18Z"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: cluster-admin
  resourceVersion: "87"
  uid: 64f8f954-d9bc-41a0-b4a2-d1a28eaacdda
rules:
- apiGroups:
  - '*'
  resources:
  - '*'
  verbs:
  - '*'
- nonResourceURLs:
  - '*'
  verbs:
  - '*'

权限基本都有!

Rolebinding 和 ClusterRoleBinding

这两个都容易理解了, 就是role 和 sa/User的mapping

bash 复制代码
gateman@MoreFine-S500: conf$ kubectl get rolebinding --all-namespaces
NAMESPACE       NAME                                                ROLE                                                  AGE
ingress-nginx   ingress-nginx                                       Role/ingress-nginx                                    85d
kube-public     kubeadm:bootstrap-signer-clusterinfo                Role/kubeadm:bootstrap-signer-clusterinfo             206d
kube-public     system:controller:bootstrap-signer                  Role/system:controller:bootstrap-signer               206d
kube-system     kube-proxy                                          Role/kube-proxy                                       206d
kube-system     kubeadm:kubelet-config-1.23                         Role/kubeadm:kubelet-config-1.23                      206d
kube-system     kubeadm:nodes-kubeadm-config                        Role/kubeadm:nodes-kubeadm-config                     206d
kube-system     system::extension-apiserver-authentication-reader   Role/extension-apiserver-authentication-reader        206d
kube-system     system::leader-locking-kube-controller-manager      Role/system::leader-locking-kube-controller-manager   206d
kube-system     system::leader-locking-kube-scheduler               Role/system::leader-locking-kube-scheduler            206d
kube-system     system:controller:bootstrap-signer                  Role/system:controller:bootstrap-signer               206d
kube-system     system:controller:cloud-provider                    Role/system:controller:cloud-provider                 206d
kube-system     system:controller:token-cleaner                     Role/system:controller:token-cleaner                  206d

具体例子

参考:
K8S - 用service account 登陆kubectl

相关推荐
魏 无羡3 小时前
linux CentOS系统上卸载docker
linux·kubernetes·centos
Karoku0664 小时前
【k8s集群应用】kubeadm1.20高可用部署(3master)
运维·docker·云原生·容器·kubernetes
凌虚5 小时前
Kubernetes APF(API 优先级和公平调度)简介
后端·程序员·kubernetes
探索云原生9 小时前
在 K8S 中创建 Pod 是如何使用到 GPU 的: nvidia device plugin 源码分析
ai·云原生·kubernetes·go·gpu
启明真纳9 小时前
elasticache备份
运维·elasticsearch·云原生·kubernetes
jwolf211 小时前
基于K8S的微服务:一、服务发现,负载均衡测试(附calico网络问题解决)
微服务·kubernetes·服务发现
nangonghen11 小时前
在华为云通过operator部署Doris v2.1集群
kubernetes·华为云·doris·operator
会飞的土拨鼠呀13 小时前
chart文件结构
运维·云原生·kubernetes
自在的LEE15 小时前
当 Go 遇上 Windows:15.625ms 的时间更新困局
后端·kubernetes·go
云川之下19 小时前
【k8s】访问etcd
kubernetes·etcd