在 Kubernetes 中,User和Service Account各自扮演着不同的角色,用于管理集群和工作负载的身份验证与授权(这个是 ChanGPT 给的答案)。

上面这句话,好像是句废话,说了和没说没啥区别。

定义

User(用户)

在 k8s 中我翻阅了一遍源码,User 没有找到。

源码位置:https://github.com/kubernetes/kubernetes/blob/246d363ea4bab2ac99a938d0cee73d72fc44de45/staging/src/k8s.io/api/core/v1/types.go

翻阅了 openshift 的用户的 yaml 文件。

关于K8S中User与Service Account的了解_ServiceAccount

kind: User
apiVersion: user.openshift.io/v1   
metadata:
  name: kubeadmin
  uid: 91eee909-638f-4d12-8f21-bfde203517b5
  resourceVersion: '233408'
  creationTimestamp: '2023-11-16T01:36:22Z'
  managedFields:
    - manager: oauth-server
      operation: Update
      apiVersion: user.openshift.io/v1
      time: '2023-11-16T01:36:22Z'
      fieldsType: FieldsV1
      fieldsV1:
        'f:identities': {}
identities:
  - 'developer:kubeadmin'
groups: null

apiVersion : user.openshift.io/v1 说明此资源是有 openshift 提供的,非 k8s 的资源(k8s 的资源一般都是 v1 这种没有带域名的 ),下面是 ServiceAccount 的 yaml 描述。

关于K8S中User与Service Account的了解_User_02

kind: ServiceAccount
apiVersion: v1
metadata:
  name: default
  namespace: nfs-external-provisioner
  uid: 89513e6c-fde3-4bed-aa16-c14cee0e5b49
  resourceVersion: '17471371'
  creationTimestamp: '2023-12-20T01:16:46Z'
secrets:
  - name: default-token-lk4wn
  - name: default-dockercfg-fmxdr
imagePullSecrets:
  - name: default-dockercfg-fmxdr

再问一下 ChanGPT

关于K8S中User与Service Account的了解_User_03

结论

可以确认了,k8s 中是没有 user 这个资源的。

Service Account (服务账号)

源码位置:https://github.com/kubernetes/kubernetes/blob/246d363ea4bab2ac99a938d0cee73d72fc44de45/staging/src/k8s.io/api/core/v1/types.go

// ServiceAccount binds together:
// * a name, understood by users, and perhaps by peripheral systems, for an identity
// * a principal that can be authenticated and authorized
// * a set of secrets
type ServiceAccount struct {
   metav1.TypeMeta `json:",inline"`
   // Standard object's metadata.
   // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
   // +optional
   metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`

   // Secrets is a list of the secrets in the same namespace that pods running using this ServiceAccount are allowed to use.
   // Pods are only limited to this list if this service account has a "kubernetes.io/enforce-mountable-secrets" annotation set to "true".
   // This field should not be used to find auto-generated service account token secrets for use outside of pods.
   // Instead, tokens can be requested directly using the TokenRequest API, or service account token secrets can be manually created.
   // More info: https://kubernetes.io/docs/concepts/configuration/secret
   // +optional
   // +patchMergeKey=name
   // +patchStrategy=merge
   Secrets []ObjectReference `json:"secrets,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,2,rep,name=secrets"`

   // ImagePullSecrets is a list of references to secrets in the same namespace to use for pulling any images
   // in pods that reference this ServiceAccount. ImagePullSecrets are distinct from Secrets because Secrets
   // can be mounted in the pod, but ImagePullSecrets are only accessed by the kubelet.
   // More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
   // +optional
   ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" protobuf:"bytes,3,rep,name=imagePullSecrets"`

   // AutomountServiceAccountToken indicates whether pods running as this service account should have an API token automatically mounted.
   // Can be overridden at the pod level.
   // +optional
   AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" protobuf:"varint,4,opt,name=automountServiceAccountToken"`
}

ServiceAccount 将以下内容绑定在一起:

  • 名称
  • 可以验证和授权的主体
  • 一组凭证

对比

名称

相同点

不同点

User

  • 在 Kubernetes 中,User 通常指的是集群外部的用户或管理员,用于管理整个集群,具有权限执行管理操作,比如创建、更新或删除资源对象。
  • 他们通过身份验证系统(比如 LDAP、Active Directory)进行管理,用于访问 Kubernetes 集群的 API 或执行管理操作。

ServiceAccount

  • 在 Kubernetes 中,ServiceAccount 是用于代表运行在集群中的工作负载(如 Pod)与 Kubernetes API 进行交互的实体。
  • 每个 Namespace 都有自己的默认服务账户,用于代表该 Namespace 中运行的 Pod,允许它们访问 Kubernetes API,以及执行特定的操作或访问特定的资源。

存在的意义

看完对比后,是不是有点懵呢?不瞒您,我写的时候都有点懵。

我个人理解,user 是一个人身份,它是你在平台中的一个映射。ServiceAccount 则是一个平台中虚拟存在的管理者,管理着它自己的服务,比如 pod 扩缩容等。至于为什么有多个 ServiceAccount,我们就需要去了解 RBAC 这个策略了。

扩展

Role-Based Access Control (RBAC) 是 Kubernetes 中用于控制对资源的访问权限的一种策略。RBAC 通过定义角色(Role)和角色绑定(RoleBinding)来管理用户、服务账户和组对资源的访问权限。

在 Kubernetes 中,您可以通过以下方式使用 RBAC:

创建角色(Role)
通过定义角色来指定一组权限,例如读取、写入或执行特定资源的权限。角色是针对单个 Namespace 的。

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: <namespace>
  name: <role-name>
rules:
- apiGroups: [""]
  resources: ["pods", "services", "deployments"]
  verbs: ["get", "list", "watch", "create", "update", "delete"]

创建角色绑定(RoleBinding)
通过定义角色绑定将角色绑定到用户、服务账户或组上,从而赋予它们相应的权限。

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: <role-binding-name>
  namespace: <namespace>
subjects:
- kind: User
  name: <username>
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: <role-name>
  apiGroup: rbac.authorization.k8s.io

在上述示例中,<username> 是您要授予权限的用户的名称,<role-name> 是您之前创建的角色的名称。

检查权限
您可以使用 kubectl auth can-i 命令来检查特定用户或服务账户是否具有执行特定操作的权限,例如:

kubectl auth can-i create pods --as <username>

这将检查特定用户是否具有在指定 Namespace 中创建 Pods 的权限。

RBAC 是 Kubernetes 中非常重要的安全机制,通过 RBAC,您可以精确控制用户和服务账户对集群中资源的访问权限。


资源来源