在 Kubernetes 中,User和Service Account各自扮演着不同的角色,用于管理集群和工作负载的身份验证与授权(这个是 ChanGPT 给的答案)。
上面这句话,好像是句废话,说了和没说没啥区别。
定义
User(用户)
在 k8s 中我翻阅了一遍源码,User 没有找到。
翻阅了 openshift 的用户的 yaml 文件。
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 描述。
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 (服务账号)
// 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 将以下内容绑定在一起:
- 名称
- 可以验证和授权的主体
- 一组凭证
- apiVersion: v1
- kind: ServiceAccount
- metadata (ObjectMeta)
标准对象的元数据,更多信息: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - automountServiceAccountToken (boolean)
AutomountServiceAccountToken 指示作为此服务帐户运行的 Pod 是否应自动挂载 API 令牌, 可以在 Pod 级别覆盖。 - imagePullSecrets ([]LocalObjectReference)
imagePullSecrets 是对同一命名空间中 Secret 的引用列表,用于拉取引用此 ServiceAccount 的 Pod 中的任何镜像。 imagePullSecrets 与 Secret 不同,因为 Secret 可以挂载在 Pod 中,但 imagePullSecrets 只能由 kubelet 访问。更多信息: https://kubernetes.io/zh-cn/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod - secrets ([]ObjectReference)
补丁策略:基于键name
合并
secrets 是允许使用此 ServiceAccount 运行的 Pod 使用的同一命名空间中的秘密列表。 仅当此服务帐户的 “kubernetes.io/enforce-mountable-secrets” 注释设置为 “true” 时,Pod 才限于此列表。 此字段不应用于查找自动生成的服务帐户令牌机密以在 Pod 之外使用。 相反,可以使用 TokenRequest API 直接请求令牌,或者可以手动创建服务帐户令牌 Secret。 更多信息: https://kubernetes.io/zh-cn/docs/concepts/configuration/secret
对比
名称 | 相同点 | 不同点 |
User | 无 |
|
ServiceAccount |
|
存在的意义
看完对比后,是不是有点懵呢?不瞒您,我写的时候都有点懵。
我个人理解,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,您可以精确控制用户和服务账户对集群中资源的访问权限。
资源来源
- k8s gitlab: https://github.com/kubernetes/kubernetes
- 统信有雀平台: https://baijiahao.baidu.com/s?id=1748375472975019664&wfr=spider&for=pc
- k8s 官网: https://kubernetes.io/