美文网首页
ServiceAccount & RBAC

ServiceAccount & RBAC

作者: 会倒立的香飘飘 | 来源:发表于2021-04-08 09:49 被阅读0次

    简介

    Service account 是为了方便 Pod 里面的进程调用 Kubernetes API 或其他外部服务而设计的。它与 User account 不同

    • User account 是为人设计的,而 service account 则是为 Pod 中的进程调用 Kubernetes API 而设计;
    • User account 是跨 namespace 的,而 service account 则是仅局限它所在的 namespace;
    • 每个 namespace 都会自动创建一个 default service account
    • Token controller 检测 service account 的创建,并为它们创建 secret
    • 开启 ServiceAccount Admission Controller 后
      • 每个 Pod 在创建后都会自动设置 spec.*serviceAccount*Name 为 default(除非指定了其他 ServiceAccout)
      • 验证 Pod 引用的 service account 已经存在,否则拒绝创建
      • 如果 Pod 没有指定 ImagePullSecrets,则把 service account 的 ImagePullSecrets 加到 Pod 中
      • 每个 container 启动后都会挂载该 service account 的 token 和 ca.crt/var/run/secrets/kubernetes.io/*serviceaccount*/
    [root@k8s-master ~]#  kubectl exec web-0 -it --  ls -l /var/run/secrets/kubernetes.io/serviceaccount/
    total 0
    lrwxrwxrwx    1 root     root            13 Apr  1 08:34 ca.crt -> ..data/ca.crt
    lrwxrwxrwx    1 root     root            16 Apr  1 08:34 namespace -> ..data/namespace
    lrwxrwxrwx    1 root     root            12 Apr  1 08:34 token -> ..data/token
    
    

    创建一个serviceaccount

    [root@k8s-master ~]# kubectl create sa admin 
    serviceaccount/admin created
    

    查看serviceaccount

    [root@k8s-master ~]# kubectl get sa
    NAME      SECRETS   AGE
    admin     1         37s
    default   1         25d
    [root@k8s-master ~]# kubectl describe sa admin 
    Name:                admin
    Namespace:           default
    Labels:              <none>
    Annotations:         <none>
    Image pull secrets:  <none>
    Mountable secrets:   admin-token-vcjv6
    Tokens:              admin-token-vcjv6
    Events:              <none>
    

    创建一个serviceaccount会自动创建一个secret

    [root@k8s-master ~]# kubectl get secret
    NAME                    TYPE                                  DATA   AGE
    admin-token-vcjv6       kubernetes.io/service-account-token   3      11m
    

    RBAC

    Kubernetes 从 1.6 开始支持基于角色的访问控制机制(Role-Based Access Control,RBAC),集群管理员可以对用户或服务账号的角色进行更精确的资源访问控制。在 RBAC 中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。
    Kubernetes 1.6 中的一个亮点时 RBAC 访问控制机制升级到了 beta 版本(版本为 *rbac*.authorization.k8s.io/v1beta1 )。RBAC,基于角色的访问控制机制,是用来管理 kubernetes 集群中资源访问权限的机制。使用 RBAC 可以很方便的更新访问授权策略而不用重启集群。
    从 Kubernetes 1.8 开始,RBAC 进入稳定版,其 API 为 *rbac*.authorization.k8s.io/v1
    在使用 RBAC 时,只需要在启动 kube-apiserver 时配置 --authorization-mode=*RBAC* 即可。

    RBAC VS ABAC

    目前 kubernetes 中已经有一系列 l 鉴权机制。鉴权的作用是,决定一个用户是否有权使用 Kubernetes API 做某些事情。它除了会影响 kubectl 等组件之外,还会对一些运行在集群内部并对集群进行操作的软件产生作用,例如使用了 Kubernetes 插件的 Jenkins,或者是利用 Kubernetes API 进行软件部署的 Helm。ABAC 和 RBAC 都能够对访问策略进行配置。

    ABAC(Attribute Based Access Control)本来是不错的概念,但是在 Kubernetes 中的实现比较难于管理和理解,而且需要对 Master 所在节点的 SSH 和文件系统权限,而且要使得对授权的变更成功生效,还需要重新启动 API Server。

    RBAC 的授权策略可以利用 kubectl 或者 Kubernetes API 直接进行配置。RBAC 可以授权给用户,让用户有权进行授权管理,这样就可以无需接触节点,直接进行授权管理。RBAC 在 Kubernetes 中被映射为 API 资源和操作。

    因为 Kubernetes 社区的投入和偏好,相对于 ABAC 而言,RBAC 是更好的选择。

    创建私钥
    [root@k8s-master pki]# cd /etc/kubernetes/pki/
    [root@k8s-master ~]# (umask 077; openssl genrsa -out piaopiao.key 2048)
    [root@k8s-master pki]# ll
    total 60
    -rw-r--r-- 1 root root 1269 Mar 10 14:55 apiserver.crt
    -rw-r--r-- 1 root root 1135 Mar 10 14:55 apiserver-etcd-client.crt
    -rw------- 1 root root 1679 Mar 10 14:55 apiserver-etcd-client.key
    -rw------- 1 root root 1675 Mar 10 14:55 apiserver.key
    -rw-r--r-- 1 root root 1143 Mar 10 14:55 apiserver-kubelet-client.crt
    -rw------- 1 root root 1679 Mar 10 14:55 apiserver-kubelet-client.key
    -rw-r--r-- 1 root root 1066 Mar 10 14:55 ca.crt
    -rw------- 1 root root 1675 Mar 10 14:55 ca.key
    drwxr-xr-x 2 root root  162 Mar 10 14:55 etcd
    -rw-r--r-- 1 root root 1078 Mar 10 14:55 front-proxy-ca.crt
    -rw------- 1 root root 1679 Mar 10 14:55 front-proxy-ca.key
    -rw-r--r-- 1 root root 1103 Mar 10 14:55 front-proxy-client.crt
    -rw------- 1 root root 1679 Mar 10 14:55 front-proxy-client.key
    -rw------- 1 root root 1679 Apr  7 10:44 piaopiao.key
    -rw------- 1 root root 1675 Mar 10 14:55 sa.key
    -rw------- 1 root root  451 Mar 10 14:55 sa.pub
    
    
    生成证书签署请求&签署证书
    [root@k8s-master pki]# openssl req -new -key piaopiao.key -out piaopiao.csr -subj "/CN=xiaofang"
    [root@k8s-master pki]# openssl  x509 -req -in piaopiao.csr  -CA ca.crt  -CAkey ca.key -CAcreateserial -out piaopiao.crt -days 365
    
    
    创建k8s用户
    [root@k8s-master pki]# kubectl config set-credentials xiaofang --client-certificate=./piaopiao.crt --client-key=./piaopiao.key --embed-certs=true
    
    
    添加用户到集群
    [root@k8s-master pki]# kubectl config set-context  xiaofang@kubernetes --cluster=kubernetes --user=xiaofang
    
    [root@k8s-master pki]# kubectl config view 
    apiVersion: v1
    clusters:
    - cluster:
        certificate-authority-data: DATA+OMITTED
        server: https://10.0.0.11:6443
      name: kubernetes
    contexts:
    - context:
        cluster: kubernetes
        user: kubernetes-admin
      name: kubernetes-admin@kubernetes
    - context:
        cluster: kubernetes
        user: xiaofang
      name: xiaofang@kubernetes
    current-context: kubernetes-admin@kubernetes
    kind: Config
    preferences: {}
    users:
    - name: kubernetes-admin
      user:
        client-certificate-data: REDACTED
        client-key-data: REDACTED
    - name: xiaofang
      user:
        client-certificate-data: REDACTED
        client-key-data: REDACTED
    
    

    Role & ClusterRole RoleBinding & ClusterRoleBinding

    Role(角色)是一系列权限的集合,例如一个角色可以包含读取 Pod 的权限和列出 Pod 的权限。Role 只能用来给某个特定 namespace 中的资源作鉴权,对多 namespace 和集群级的资源或者是非资源类的 API(如 /healthz)使用 ClusterRole。
    RBAC 的 RoleClusterRole 中包含一组代表相关权限的规则。 这些权限是纯粹累加的(不存在拒绝某操作的规则)。

    Role 总是用来在某个名字空间 内设置访问权限;在你创建 Role 时,你必须指定该 Role 所属的名字空间。
    与之相对,ClusterRole 则是一个集群作用域的资源。这两种资源的名字不同(Role 和 ClusterRole)是因为 Kubernetes 对象要么是名字空间作用域的,要么是集群作用域的, 不可两者兼具。

    ClusterRole 有若干用法。你可以用它来:

    1. 定义对某名字空间域对象的访问权限,并将在各个名字空间内完成授权;
    2. 为名字空间作用域的对象设置访问权限,并跨所有名字空间执行授权;
    3. 为集群作用域的资源定义访问权限。
      如果你希望在名字空间内定义角色,应该使用 Role; 如果你希望定义集群范围的角色,应该使用 ClusterRole。
    1,Role

    一个Role内类型的角色只能访问他所在的namesoace下的资源

    创建一个role
    1,使用kubectl create创建
    [root@k8s-master ~]# kubectl create role app-role --verb=get,list,create,delete  --resource=pods
    
    2,使用yaml创建
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      creationTimestamp: null
      name: app-role
    rules:
    - apiGroups:
      - ""
      resources:
      - pods
      verbs:
      - get
      - list
      - create
      - delete
    
    
    查看role
    [root@k8s-master ~]# kubectl describe role app-role  
    Name:         app-role
    Labels:       <none>
    Annotations:  <none>
    PolicyRule:
      Resources  Non-Resource URLs  Resource Names  Verbs
      ---------  -----------------  --------------  -----
      pods       []                 []              [get list create delete]
    
    
    使用Rolebinding绑定role
    命令创建
    [root@k8s-master ~]# kubectl create rolebinding  app-rolebinding --role=app-role --user=xiaofang 
    
    使用yaml创建
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: app-rolebinding
      namespace: default
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: app-role
    subjects:
    - apiGroup: rbac.authorization.k8s.io
      kind: User
      name: xiaofang
    
    
    查看rolebinding
    [root@k8s-master ~]# kubectl describe rolebindings.rbac.authorization.k8s.io app-rolebinding 
    Name:         app-rolebinding
    Labels:       <none>
    Annotations:  <none>
    Role:
      Kind:  Role
      Name:  app-role
    Subjects:
      Kind  Name      Namespace
      ----  ----      ---------
      User  xiaofang  
    
    验证
    [root@k8s-master ~]# kubectl config use-context xiaofang@kubernetes 
    Switched to context "xiaofang@kubernetes".
    [root@k8s-master ~]# kubectl get pods 
    NAME    READY   STATUS        RESTARTS   AGE
    web-0   0/1     Terminating   0          5d23h
    web-2   0/1     Terminating   0          5d23h
    web-4   0/1     Terminating   0          5d23h
    [root@k8s-master ~]# kubectl get pods -n kube-system
    Error from server (Forbidden): pods is forbidden: User "xiaofang" cannot list resource "pods" in API group "" in the namespace "kube-system"
    
    #这里切换用户后,查看default的名称空间的pod是可以的而查看其他的namespace中是没有权限的
    

    2,clusterrole

    创建clusterrole时不能使用名称空间,因为clusterrole属于集群级别资源

    创建一个clusterrole

    1,命令创建

    [root@k8s-master ~]# kubectl create clusterrole app-clusterrole --verb=get,list,watch,create,delete --resource=pods
    

    2,yaml创建

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: app-clusterrole
    rules:
    - apiGroups:
      - ""
      resources:
      - pods
      verbs:
      - get
      - list
      - watch
      - create
      - delete
    
    
    查看clusterrole
    [root@k8s-master ~]# kubectl describe clusterrole app-clusterrole 
    Name:         app-clusterrole
    Labels:       <none>
    Annotations:  <none>
    PolicyRule:
      Resources  Non-Resource URLs  Resource Names  Verbs
      ---------  -----------------  --------------  -----
      pods       []                 []              [get list watch create delete]
    
    
    使用clusterrolebinding绑定
    命令创建
    [root@k8s-master ~]# kubectl create clusterrolebinding app-clusterrolebinding --clusterrole=app-clusterrole --user=xiaofang
    
    yaml创建
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      creationTimestamp: null
      name: app-clusterrolebinding
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: app-clusterrole
    subjects:
    - apiGroup: rbac.authorization.k8s.io
      kind: User
      name: xiaofang
    
    查看clusterrolebinding
    [root@k8s-master ~]# kubectl get clusterrolebindings.rbac.authorization.k8s.io app-clusterrolebinding 
    NAME                     ROLE                          AGE
    app-clusterrolebinding   ClusterRole/app-clusterrole   113s
    [root@k8s-master ~]# kubectl describe clusterrolebindings.rbac.authorization.k8s.io app-clusterrolebinding 
    Name:         app-clusterrolebinding
    Labels:       <none>
    Annotations:  <none>
    Role:
     Kind:  ClusterRole
     Name:  app-clusterrole
    Subjects:
     Kind  Name      Namespace
     ----  ----      ---------
     User  xiaofang 
    
    切换用户验证
    [root@k8s-master ~]# kubectl config use-context xiaofang@kubernetes 
    Switched to context "xiaofang@kubernetes".
    [root@k8s-master ~]# kubectl get pods 
    NAME    READY   STATUS        RESTARTS   AGE
    web-0   0/1     Terminating   0          6d
    web-2   0/1     Terminating   0          6d
    web-4   0/1     Terminating   0          6d
    
    [root@k8s-master ~]# kubectl get pods -n kube-system
    NAME                                 READY   STATUS    RESTARTS   AGE
    coredns-6d56c8448f-htht4             1/1     Running   4          28d
    coredns-6d56c8448f-m78cl             1/1     Running   4          28d
    etcd-k8s-master                      1/1     Running   4          28d
    kube-apiserver-k8s-master            1/1     Running   8          28d
    kube-controller-manager-k8s-master   1/1     Running   28         28d
    kube-flannel-ds-kvzz6                1/1     Running   4          28d
    kube-flannel-ds-rwlhk                1/1     Running   8          28d
    kube-flannel-ds-x6hdm                1/1     Running   15         28d
    kube-proxy-7g68v                     1/1     Running   10         28d
    kube-proxy-9zxx6                     1/1     Running   7          28d
    kube-proxy-mnqql                     1/1     Running   4          28d
    kube-scheduler-k8s-master            1/1     Running   24         28d
    
    #验证现实可以查看其他namespace中的pods,clusterrolebinding不限制在单个的namespace中,是授权在整个集群范围类
    
    
    使用Rolebinding绑定ClusterRole

    使用Rolebinding绑定ClusterRole这种方式会让clusterrole的权限降级,绑定后clusterrole只能对rolebinding的namespace中的资源进行操作,

    使用命令创建
    [root@k8s-master ~]# kubectl create rolebinding rolebinding-cluster --clusterrole=app-clusterrole --user=xiaofang 
    
    
    使用yaml创建
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      creationTimestamp: null
      name: rolebinding-cluster
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: app-clusterrole
    subjects:
    - apiGroup: rbac.authorization.k8s.io
      kind: User
      name: xiaofang
    
    查看rolebinding
    [root@k8s-master ~]# kubectl describe rolebindings.rbac.authorization.k8s.io rolebinding-cluster 
    Name:         rolebinding-cluster
    Labels:       <none>
    Annotations:  <none>
    Role:
      Kind:  ClusterRole
      Name:  app-clusterrole
    Subjects:
      Kind  Name      Namespace
      ----  ----      ---------
      User  xiaofang 
    
    切换用户验证
    [root@k8s-master ~]# kubectl config use-context xiaofang@kubernetes 
    Switched to context "xiaofang@kubernetes".
    [root@k8s-master ~]# kubectl get pods 
    NAME    READY   STATUS        RESTARTS   AGE
    web-0   0/1     Terminating   0          6d1h
    web-2   0/1     Terminating   0          6d1h
    web-4   0/1     Terminating   0          6d1h
    [root@k8s-master ~]# kubectl get pods -n kube-system
    Error from server (Forbidden): pods is forbidden: User "xiaofang" cannot list resource "pods" in API group "" in the namespace "kube-system",
    
    ps:

    如果集群中有多个namespace分配给不同的管理员,但是他们的权限是一样的,那么这样可以先定义一个ClusterRole,然后通过RoleBinding将不同namespace的管理员做绑定,这样可以解决多次定义Role的问题。

    相关文章

      网友评论

          本文标题:ServiceAccount & RBAC

          本文链接:https://www.haomeiwen.com/subject/tyjskltx.html