kubernetes为何需要默认的serviceaccount?

简介: 在 Kubernetes 中,ServiceAccount 是一种用于身份验证和授权的对象。它为 Pod 提供了一种身份,以便它们可以与 Kubernetes API 交互,并且可以通过 Role 和 RoleBinding 为它们分配特定的权限。

什么是k8s的serviceAccount?

在 Kubernetes 中,ServiceAccount 是一种用于身份验证和授权的对象。它为 Pod 提供了一种身份,以便它们可以与 Kubernetes API 交互,并且可以通过 Role 和 RoleBinding 为它们分配特定的权限。

–update 2023年4月28日11:08:44 如果是一个普通的业务pod就不需要访问kube-apiserver,也没有必要额外创建对应的sa. 没有创建都会使用该ns下默认的sa.


ServiceAccount 是 Kubernetes 中的一种重要概念,它的实际使用场景包括:

  • 访问 Kubernetes API:ServiceAccount 为 Pod 提供了访问 Kubernetes API 的凭据,使得它们可以查询和修改 Kubernetes 中的资源。例如,一个 Pod 可以使用 ServiceAccount 访问 Kubernetes API 获取其他 Pod 的信息,或者创建、更新、删除其他资源。

  • 认证和授权:ServiceAccount 为 Pod 提供了一种身份,使得 Kubernetes 可以对其进行认证和授权。例如,Kubernetes 可以使用 ServiceAccount 来验证 Pod 是否有权限访问某个资源,并根据 Role 和 RoleBinding 为其分配特定的权限。

  • 安全性:ServiceAccount 可以帮助提高 Kubernetes 集群的安全性。通过为每个 Pod 分配一个独立的 ServiceAccount,并为其分配最小特权的权限,可以降低潜在的安全风险。

  • 多租户:ServiceAccount 可以帮助实现 Kubernetes 中的多租户。通过为每个 Namespace 创建一个独立的 ServiceAccount,并为其分配特定的权限,可以实现不同 Namespace 之间的隔离和安全性。

为什么每一个ns下都有默认的sa?

创建ns的时候ns controller就会创建一个默认的sa。

在 Kubernetes 中,每个 namespace 下都有一个默认的 ServiceAccount,原因如下:


简化配置:默认的 ServiceAccount 使得用户无需为每个 Pod 创建一个新的 ServiceAccount,从而简化了配置。如果 Pod 没有指定 ServiceAccount,它将自动关联到默认的 ServiceAccount。


容器运行时身份:ServiceAccount 提供了一种将身份信息(如 API 访问凭据)与 Pod 关联的方法。默认的 ServiceAccount 为 Pod 提供了基本的身份信息,以便它们可以与 Kubernetes API 交互。


安全性:默认的 ServiceAccount 通常具有较少的权限,这有助于遵循最小特权原则。这意味着,如果 Pod 不需要访问 Kubernetes API 的特定资源,它可以使用默认的 ServiceAccount,从而降低潜在的安全风险。


易于管理:默认的 ServiceAccount 使得集群管理员可以更轻松地管理和控制对 Kubernetes API 的访问。例如,管理员可以通过修改默认 ServiceAccount 的权限来限制或扩展某个 namespace 下所有 Pod 的访问权限。


总之,默认的 ServiceAccount 是 Kubernetes 中的一种设计,旨在简化配置、提供基本的身份信息、增强安全性并便于管理。然而,在实际应用中,根据需要创建特定的 ServiceAccount 并为其分配适当的权限是一种更好的做法。

default sa yaml

k get secret default-token-lnzs9 -oyaml
apiVersion: v1
data:
  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR2akNDQXFhZ0F3SUJBZ0lVVFZZeWZ0VDFBdnQ1ZHlORmM4WUN...
  HU4NkZ0bTNyRkNaNUY3N1FmTVpCNU9hYXE2TkRDRwp3ems9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
  namespace: ZGVmYXVsdA==
  token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNkltcEdjRkkwWlRSRU55MW1NeTF4YWt0U1pYQm9Sems0U1dJd2RHMTV
。。。
  xQUJsdVlnSGJva3ZB
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: default
    kubernetes.io/service-account.uid: b90818be-0587-4a7a-8abb-c0b214cdaba0
  creationTimestamp: "2022-06-26T07:04:38Z"
  name: default-token-lnzs9
  namespace: default
  resourceVersion: "11436"
  uid: 37c38aaa-bd9d-4beb-abf9-cdc94bcc697a
type: kubernetes.io/service-account-token

默认的sa下都会挂一个secret,这个secret是从哪里来的?

在 Kubernetes 中创建一个新的 Namespace 时,系统会自动为该 Namespace 下的默认 ServiceAccount 创建一个关联的 Secret。这个 Secret 是用于存储访问 Kubernetes API 的凭据的,通常包含一个 token 和一个 CA 证书。这个 Secret 的来源如下:


Kubernetes 控制平面的 Token Controller 自动创建并管理这个 Secret。当创建一个新的 ServiceAccount 时,Token Controller 会生成一个新的 token,并将其存储在一个新的 Secret 中。


该 Secret 会被自动关联到对应的 ServiceAccount。Secret 的类型为 kubernetes.io/service-account-token,并且在 Secret 的 annotations 字段中包含了关联的 ServiceAccount 信息

这个sercet的token是一个jwt(json web token)

经过base64解码后以点分隔有三部分

$ echo "ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNkltcEdjRkkwWlRSRU55MW1NeTF4YWt0U1pYQm9Sems0U1dJd2RHMTVjMHRoWm04MlRtczJOSEozV0hNaWZRLmV5SnBjM01pT2lKcmRXSmxjbTVsZEdWekwzTmxjblpwWTJWaFkyTnZkVzUwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXVZVzFsYzNCaFkyVWlPaUprWlhZaUxDSnJkV0psY201bGRHVnpMbWx2TDNObGNuWnBZMlZoWTJOdmRXNTBMM05sWTNKbGRDNXVZVzFsSWpvaVpHVm1ZWFZzZEMxMGIydGxiaTFuWW5Cd09TSXNJbXQxWW1WeWJtVjBaWE11YVc4dmMyVnlkbWxqWldGalkyOTFiblF2YzJWeWRtbGpaUzFoWTJOdmRXNTBMbTVoYldVaU9pSmtaV1poZFd4MElpd2lhM1ZpWlhKdVpYUmxjeTVwYnk5elpYSjJhV05sWVdOamIzVnVkQzl6WlhKMmFXTmxMV0ZqWTI5MWJuUXVkV2xrSWpvaU5qazVPRGd4WlRFdFlXRXlZeTAwTjJNd0xXSm1Oell0WmpWbE9ESm1ZbVEwTmpnMElpd2ljM1ZpSWpvaWMzbHpkR1Z0T25ObGNuWnBZMlZoWTJOdmRXNTBPbVJsZGpwa1pXWmhkV3gwSW4wLnBHU2F0TVdpbTR1NFZHT3JkUTZrSU1Bam9HMmRhVmdaVWw0T2RSMk45RlM1SmZQQ0ZOUUxWdWYydU4tTE5aTjdscWNOSmtwVU9pZ2FmbnpNYUozVWZhUVpVeXpKR3J1RFQ2V1VCOWhFM2tQSDRONXFNUDRKRVJoRS1neFVObTUwUUNsZUpTN3FKQk9USGllSnVTLVBWdFo2SnRqbWczd2UxZ1BZd0V5Z05vRzRGcHBZVHZVMk1tbGF0YjRuVjZvTnZnWWFnUnBjMnhDRFozd3ZOdnFGQVN6WnpFeVJHQkJ3QWpEZHROeDVTUWpKY2Zwc1VJX01VTVVXUUFWTlZCWDBJR3hMdnI3b1hYeDFZc01tQTNncjc4Ti05dVp3Q3NIVlNWbFlwdjgzb0dtUm1aLXRIbUsxb3VtSnkwaHFKajdtRVliU095R2JVR2RINzZQZHg1LTR0dw==" | base64 -d
eyJhbGciOiJSUzI1NiIsImtpZCI6ImpGcFI0ZTRENy1mMy1xaktSZXBoRzk4SWIwdG15c0thZm82Tms2NHJ3WHMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZXYiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoiZGVmYXVsdC10b2tlbi1nYnBwOSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNjk5ODgxZTEtYWEyYy00N2MwLWJmNzYtZjVlODJmYmQ0Njg0Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRldjpkZWZhdWx0In0.pGSatMWim4u4VGOrdQ6kIMAjoG2daVgZUl4OdR2N9FS5JfPCFNQLVuf2uN-LNZN7lqcNJkpUOigafnzMaJ3UfaQZUyzJGruDT6WUB9hE3kPH4N5qMP4JERhE-gxUNm50QCleJS7qJBOTHieJuS-PVtZ6Jtjmg3we1gPYwEygNoG4FppYTvU2Mmlatb4nV6oNvgYagRpc2xCDZ3wvNvqFASzZzEyRGBBwAjDdtNx5SQjJcfpsUI_MUMUWQAVNVBX0IGxLvr7oXXx1YsMmA3gr78N-9uZwCsHVSVlYpv83oGmRmZ-tHmK1oumJy0hqJj7mEYbSOyGbUGdH76Pdx5-4tw

当创建一个使用该 ServiceAccount 的 Pod 时,Kubernetes 会自动将这个 Secret 挂载到 Pod 的容器中。默认情况下,Secret 会被挂载到 /var/run/secrets/kubernetes.io/serviceaccount 目录下。容器内的应用程序可以使用这个 token 和 CA 证书与 Kubernetes API 交互。


要查看默认 ServiceAccount 关联的 Secret,可以使用以下命令:

kubectl get serviceaccounts default -o jsonpath='{.secrets[0``].name}' -n <namespace>

将 替换为实际的 Namespace 名称。然后,使用以下命令查看 Secret 的详细信息:

kubectl get secret <secret_name> -o yaml -n <namespace>

将 <secret_name> 替换为上一步获取到的 Secret 名称,将 替换为实际的 Namespace 名称。

一道关于RBAC的CKA考题

假设我们有一个运行在 Kubernetes 中的 Web 应用程序,它需要访问 Kubernetes API 来获取其他 Pod 的信息。

为了实现这个功能,我们可以创建一个 ServiceAccount,并为其分配访问 Kubernetes API 的权限。具体步骤如下:

1、创建一个新的 ServiceAccount

kubectl create serviceaccount myapp-sa

2、创建一个新的 Role

用于授予 ServiceAccount 访问 Kubernetes API 的权限:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: myapp-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"] # 注意只有get和list的权限,并不需要update的权限

3、创建一个新的 RoleBinding

将 ServiceAccount 和 Role 关联起来:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: myapp-rolebinding
subjects:
- kind: ServiceAccount
  name: myapp-sa
roleRef:
  kind: Role
  name: myapp-role
  apiGroup: rbac.authorization.k8s.io

4、在 Pod 中使用 ServiceAccount

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
spec:
  serviceAccountName: myapp-sa
  containers:
  - name: myapp-container
    image: myapp-image
kind:

在这个例子中,我们创建了一个名为 myapp-sa 的 ServiceAccount,并为其分配了访问 Kubernetes API 的权限。然后,我们创建了一个名为 myapp-role 的 Role,并将其与 ServiceAccount 关联起来。最后,我们在 Pod 中使用了这个 ServiceAccount。


这样,我们的 Web 应用程序就可以使用这个 ServiceAccount 访问 Kubernetes API,获取其他 Pod 的信息。同时,由于我们为 ServiceAccount 分配了最小特权的权限,可以降低潜在的安全风险。

role和rolebinding的核心

role是定义一组权限列表

rolebinding有两个obj:

  • roleRef : 绑定哪个role?
  • subjects: 给谁绑定的问题 可以是user、可以是sa也可以是group

如果遇到不懂怎么写就是explain。acab54d6ad714aea9a45873d1faf6036.png

练习一

只能使用官网的情况下,完成下面和这个需求:

Create a new ServiceAccount processor in Namespace project-hamster. Create a Role and RoleBinding, both named processor as well. These should allow the new SA to only create Secrets and ConfigMaps in that Namespace.


提示; 可以使用kubectl 命令create role、create rolebinding

练习二

让alice这个用户可以创建sa:

创建一个新的 Role,用于控制 ServiceAccount 的创建:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: serviceaccount-creator
rules:
- apiGroups: [""]
  resources: ["serviceaccounts"]
  verbs: ["create"]

创建一个新的 RoleBinding,将 Role 和用户或组关联起来:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: serviceaccount-creator-binding
subjects:
- kind: User
  name: alice
roleRef:
  kind: Role
  name: serviceaccount-creator
  apiGroup: rbac.authorization.k8s.io

在这个例子中,我们创建了一个名为 serviceaccount-creator 的 Role,用于控制 ServiceAccount 的创建。然后,我们创建了一个名为 serviceaccount-creator-binding 的 RoleBinding,将 Role 和用户 alice 关联起来。


这样,用户 alice 就可以使用 kubectl create serviceaccount 命令创建新的 ServiceAccount。其他用户或组如果没有被授权,将无法创建新的 ServiceAccount。


需要注意的是,RBAC 可以用于控制 ServiceAccount 的创建和使用,但不能直接控制 ServiceAccount 的访问权限。要为 ServiceAccount 分配访问权限,需要使用 Role 和 RoleBinding。

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
Kubernetes API 数据安全/隐私保护
k8s学习-CKS真题-Pod指定ServiceAccount
k8s学习-CKS真题-Pod指定ServiceAccount
270 0
|
Kubernetes API 容器
k8s使用ServiceAccount Token的方式访问apiserver
在实际应用中经常会需要访问apiserver,下面介绍如何使用token方便访问apiserver。
7109 0
|
10月前
|
人工智能 算法 调度
阿里云ACK托管集群Pro版共享GPU调度操作指南
本文介绍在阿里云ACK托管集群Pro版中,如何通过共享GPU调度实现显存与算力的精细化分配,涵盖前提条件、使用限制、节点池配置及任务部署全流程,提升GPU资源利用率,适用于AI训练与推理场景。
750 1
|
10月前
|
弹性计算 监控 调度
ACK One 注册集群云端节点池升级:IDC 集群一键接入云端 GPU 算力,接入效率提升 80%
ACK One注册集群节点池实现“一键接入”,免去手动编写脚本与GPU驱动安装,支持自动扩缩容与多场景调度,大幅提升K8s集群管理效率。
533 89
|
资源调度 Kubernetes 调度
从单集群到多集群的快速无损转型:ACK One 多集群应用分发
本文介绍如何利用阿里云的分布式云容器平台ACK One的多集群应用分发功能,结合云效CD能力,快速将单集群CD系统升级为多集群CD系统。通过增加分发策略(PropagationPolicy)和差异化策略(OverridePolicy),并修改单集群kubeconfig为舰队kubeconfig,可实现无损改造。该方案具备多地域多集群智能资源调度、重调度及故障迁移等能力,帮助用户提升业务效率与可靠性。
|
资源调度 Kubernetes 调度
从单集群到多集群的快速无损转型:ACK One 多集群应用分发
ACK One 的多集群应用分发,可以最小成本地结合您已有的单集群 CD 系统,无需对原先应用资源 YAML 进行修改,即可快速构建成多集群的 CD 系统,并同时获得强大的多集群资源调度和分发的能力。
1129 9
|
存储 Kubernetes 监控
K8s集群实战:使用kubeadm和kuboard部署Kubernetes集群
总之,使用kubeadm和kuboard部署K8s集群就像回归童年一样,简单又有趣。不要忘记,技术是为人服务的,用K8s集群操控云端资源,我们不过是想在复杂的世界找寻简单。尽管部署过程可能遇到困难,但朝着简化复杂的目标,我们就能找到意义和乐趣。希望你也能利用这些工具,找到你的乐趣,满足你的需求。
1306 33
|
Kubernetes 开发者 Docker
集群部署:使用Rancher部署Kubernetes集群。
以上就是使用 Rancher 部署 Kubernetes 集群的流程。使用 Rancher 和 Kubernetes,开发者可以受益于灵活性和可扩展性,允许他们在多种环境中运行多种应用,同时利用自动化工具使工作负载更加高效。
874 19
|
人工智能 分布式计算 调度
打破资源边界、告别资源浪费:ACK One 多集群Spark和AI作业调度
ACK One多集群Spark作业调度,可以帮助您在不影响集群中正在运行的在线业务的前提下,打破资源边界,根据各集群实际剩余资源来进行调度,最大化您多集群中闲置资源的利用率。
|
Prometheus Kubernetes 监控
OpenAI故障复盘丨如何保障大规模K8s集群稳定性
OpenAI故障复盘丨如何保障大规模K8s集群稳定性
634 0
OpenAI故障复盘丨如何保障大规模K8s集群稳定性