K8s ServiceAccount和RBAC

作者: 伊凡的一天 | 来源:发表于2020-02-17 17:46 被阅读0次

    Service Account

    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为default(除非指定了其他ServiceAccout)
    • 验证Pod引用的service account已经存在,否则拒绝创建
    • 如果Pod没有指定ImagePullSecrets,则把service account的ImagePullSecrets加到Pod中
    • 每个container启动后都会挂载该service account的token和ca.crt到/var/run/secrets/kubernetes.io/serviceaccount/

    创建一个Service Account

    通过create命令或者资源定义文件创建一个ServiceAccount:

    $ kubectl create serviceaccount jenkins
    serviceaccount "jenkins" created
    $ kubectl get serviceaccounts jenkins -o yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      creationTimestamp: 2017-05-27T14:32:25Z
      name: jenkins
      namespace: default
      resourceVersion: "45559"
      selfLink: /api/v1/namespaces/default/serviceaccounts/jenkins
      uid: 4d66eb4c-42e9-11e7-9860-ee7d8982865f
    secrets:
    - name: jenkins-token-l9v7v
    

    自动创建的secret:

    $ kubectl get secret jenkins-token-l9v7v -o yaml
    apiVersion: v1
    data:
      ca.crt: (APISERVER CA BASE64 ENCODED)
      namespace: ZGVmYXVsdA==
      token: (BEARER TOKEN BASE64 ENCODED)
    kind: Secret
    metadata:
      annotations:
        kubernetes.io/service-account.name: jenkins
        kubernetes.io/service-account.uid: 4d66eb4c-42e9-11e7-9860-ee7d8982865f
      creationTimestamp: 2017-05-27T14:32:25Z
      name: jenkins-token-l9v7v
      namespace: default
      resourceVersion: "45558"
      selfLink: /api/v1/namespaces/default/secrets/jenkins-token-l9v7v
      uid: 4d697992-42e9-11e7-9860-ee7d8982865f
    type: kubernetes.io/service-account-token
    

    RBAC

    Service Account为服务提供了一种方便的认证机制,但它不关心授权的问题。可以配合RBAC(Role Based Access Control)来为Service Account鉴权。如果要启用RBAC,请使用--authorization-mode=RBAC参数启动API Server。

    Role和ClusterRole

    在RBAC API中,一个角色包含了一套表示一组权限的规则。 权限以纯粹的累加形式累积(没有”否定”的规则)。 角色可以由namespace内的Role对象定义,而整个Kubernetes集群范围内有效的角色则通过ClusterRole对象实现。

    一个Role对象只能用于授予对某一单一命名空间中资源的访问权限。 以下示例描述了”default”命名空间中的一个Role对象的定义,用于授予对pod的读访问权限:

    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      namespace: default
      name: pod-reader
    rules:
    - apiGroups: [""] # 空字符串""表明使用core API group
      resources: ["pods"]
      verbs: ["get", "watch", "list"]
    

    ClusterRole对象可以授予与Role对象相同的权限,但由于它们属于集群范围对象, 也可以使用它们授予对以下几种资源的访问权限:

    • 集群范围资源(例如节点,即node)
    • 非资源类型endpoint(例如”/healthz”)
    • 跨所有命名空间的命名空间范围资源(例如pod,需要运行命令kubectl get pods --all-namespaces来查询集群中所有的pod)

    下面示例中的ClusterRole定义可用于授予用户对某一特定命名空间或者所有命名空间(取决于其绑定方式)中的secret的读访问权限:

    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      # 鉴于ClusterRole是集群范围对象,所以这里不需要定义"namespace"字段
      name: secret-reader
    rules:
    - apiGroups: [""]
      resources: ["secrets"]
      verbs: ["get", "watch", "list"]
    

    RoleBinding和ClusterRoleBinding

    角色绑定将一个角色中定义的各种权限授予一个或者一组用户。 角色绑定包含了一组相关主体(即subject, 可选的subject包括用户User、用户组Group、或者服务账户Service Account)以及对被授予角色的引用。 在特定namespace中的授权可以通过RoleBinding对象授予权限,而集群范围的权限授予则通过ClusterRoleBinding对象完成。

    RoleBinding只能引用在同一命名空间内定义的Role对象。下面的示例中将允许用户”jane”从”default”命名空间中读取pod。

    # 以下角色绑定定义将允许用户"jane"从"default"命名空间中读取pod。
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      name: read-pods
      namespace: default
    subjects:
    - kind: User
      name: jane
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: pod-reader
      apiGroup: rbac.authorization.k8s.io
    

    RoleBinding对象也可以引用一个ClusterRole对象,用于在RoleBinding所在的命名空间内授予用户对所引用的ClusterRole中 定义的命名空间资源的访问权限。这一点允许管理员在整个集群范围内首先定义一组通用的角色,然后再在不同的命名空间中复用这些角色。

    # 以下角色绑定允许用户"dave"读取"development"命名空间中的secret。
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      name: read-secrets
      namespace: development # 这里表明仅授权读取"development"命名空间中的资源。
    subjects:
    - kind: User
      name: dave
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: ClusterRole
      name: secret-reader
      apiGroup: rbac.authorization.k8s.io
    

    最后,可以使用ClusterRoleBinding在集群级别和所有命名空间中授予权限。下面示例中所定义的ClusterRoleBinding 允许在用户组”manager”中的任何用户都可以读取集群中任何命名空间中的secret。

    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      name: read-secrets-global
    subjects:
    - kind: Group
      name: manager
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: ClusterRole
      name: secret-reader
      apiGroup: rbac.authorization.k8s.io
    

    一些例子

    允许读取core API Group中定义的资源”pods”:

    rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["get", "list", "watch"]
    

    允许读写在”extensions”和”apps” API Group中定义的”deployments”:

    rules:
    - apiGroups: ["extensions", "apps"]
      resources: ["deployments"]
      verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
    

    参考文章

    相关文章

      网友评论

        本文标题:K8s ServiceAccount和RBAC

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