写在开篇
在之前的两篇文章中提到,有4种方式使用 ConfigMap 配置 Pod 中的容器,关于之前的两篇可参考:
本篇的实战场景就以访问API的方式读取 ConfigMap,也就是编写代码在 Pod 中运行,然后使用 K8S API 来读取 ConfigMap的内容。但是,这个场景涉及到服务账号、K8S集群内身份验证的相关知识点。为了控制篇幅(主要是文章太长,担心没人看到最后),打算再拆分两篇。本篇尽力先把涉及到的知识点搞清楚,下一篇再真正进入实战环节,例如写代码,制作镜像等等。
其实,这个实战场景,也刚好弥补了在之前分享过的 下篇(开始写代码):运维开发人员不得不看的K8S API实战》 中缺少的 “集群内进行身份验证” 的内容。
在继续之前,如果对K8S API的使用套路还一无所知,可结合参考:
K8S的账号类型
在K8S中,主要有两种账号类型:
- User Accounts(用户账号):用户账号用于标识和验证 Kubernetes 集群的用户。用户账号通常由集群管理员创建,并与相应的身份验证凭据(如用户名和密码、令牌等)关联。用户账号用于进行集群管理操作,如创建、删除和更新资源,以及访问集群中的敏感信息。
- Service Accounts(服务账号):服务账号是用于身份验证和授权 Pod 内的应用程序的一种机制。每个 Pod 都可以与一个 Service Account 相关联,并使用该 Service Account 进行与 Kubernetes API Server 的通信。服务账号通常用于在 Pod 内的应用程序与集群中的其他资源进行交互,如读取 ConfigMap、访问 Secrets 等。
更多信息可参考官方文档:authentication
关于ServiceAccount和在K8S集群内身份验证
上次的实战场景 《下篇(开始写代码):运维开发人员不得不看的K8S API实战》 主要是在K8S集群外进行身份验证,因为调用K8S API的代码是运行在集群外部。而这次的场景是:调用K8S API的代码运行在POD容器里,也就是要在K8S集群内部进行身份验证。
当调用K8S API的代码(应用程序代码)运行在POD里的容器时,Pod中的应用程序可以使用其关联的 ServiceAccount 去访问 API Server 中的 Kubernetes 资源(比如访问ConfigMap资源)。在访问资源时,ServiceAccount 会使用其所分配的 RBAC 角色来确定它有哪些权限。为了方便理解,我简单画了个图,如下:
- 身份认证:应用程序可以使用与之关联的 ServiceAccount 进行身份认证,以证明其对 Kubernetes 集群中的资源的合法访问权限。
- 访问授权:通过与访问控制策略(如 Role、ClusterRole)结合使用,可以为 ServiceAccount 分配特定的角色和权限,从而限制应用程序对资源的访问范围和操作权限。
关于ServiceAccount的更多信息可参考官方文档:service-accounts
关于每个命名空间下默认的服务账号:default
官方文档提到:默认服务账户是Kubernetes在创建集群时自动为每个命名空间创建的一个ServiceAccount对象。每个命名空间中的服务账户默认情况下没有任何权限,除非启用了基于角色的访问控制(RBAC),此时Kubernetes会授予所有经过身份验证的主体默认的API发现权限。如果在一个命名空间中删除了ServiceAccount对象,控制平面会自动替换为一个新的ServiceAccount对象。如果在一个命名空间中部署一个Pod,并且没有手动为Pod分配一个ServiceAccount,Kubernetes会将该命名空间的默认ServiceAccount分配给该Pod。
接下来,查看一下默认命名空间(default)下的serviceaccount:
[root@k8s-b-master ~]# kubectl get serviceaccount
NAME SECRETS AGE
default 0 16d
[root@k8s-b-master ~]# kubectl get serviceaccount default -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2023-04-30T03:24:16Z"
name: default
namespace: default
resourceVersion: "359"
uid: 47c8dccd-2d91-47cf-b0b7-ce4d02b610a8
[root@k8s-b-master ~]#
创建一个名为goweb的自定义命名空间,创建后,在该命名空间下已经自动创建了一个名为default的serviceaccount对象:
[root@k8s-b-master ~]# kubectl create ns goweb
namespace/goweb created
[root@k8s-b-master ~]# kubectl get serviceaccount -n goweb
NAME SECRETS AGE
default 0 8s
[root@k8s-b-master ~]# kubectl get serviceaccount default -n goweb -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2023-05-17T03:26:41Z"
name: default
namespace: goweb
resourceVersion: "284809"
uid: c0254d59-c625-4ef9-a619-1c51fdcfeef6
[root@k8s-b-master ~]#
到了这里,可能会提出这样的问题:创建自定义的命名空间后,为什么会自动创建一个名为default的ServiceAccount?
这是因为ServiceAccount是用于身份验证和授权的一种机制,每个Pod都需要与一个ServiceAccount关联,以确定Pod在集群中的身份和权限。
默认的ServiceAccount是为了确保在创建Pod时不会发生错误。如果没有显式地指定Pod要使用的ServiceAccount,Kubernetes会自动将命名空间的默认ServiceAccount分配给该Pod。这样,Pod就能够获得基本的权限和凭据,以便与集群中的其他组件进行通信。
默认的ServiceAccount通常没有具体的权限,除非通过其他方式为其分配了角色和权限。默认情况下,它只拥有基本的API发现权限,允许Pod发现集群中的其他API资源。
可以通过为Pod显式指定不同的ServiceAccount来覆盖默认行为,以满足特定的安全需求和访问控制策略,这也就是下篇要做的事情:为 Pod配置ServiceAccount。
为Pod配置ServiceAccount的步骤
为控制篇幅,为Pod配置ServiceAccount,以及编写使用Go调用K8S API的代码、制作镜像等等均放到下篇分享。
为Pod配置ServiceAccount的步骤很简单,下面仅给出步骤,如下:
- 创建ServiceAccount
- 创建Role:定义所需的权限
- 创建RoleBinding,将ServiceAccount和Role关联起来
- 将ServiceAccount对象分配给Pod
更多信息可参考官方文档:configure-service-account
本文转载于WX公众号:不背锅运维(喜欢的盆友关注我们):https://mp.weixin.qq.com/s/1BbBLr4E564b6OdIpXjMjw
标签:default,ServiceAccount,API,集群,Pod,K8S From: https://www.cnblogs.com/ttropsstack/p/17433583.html