为Pod配置服务账号

一、介绍ServiceAccount

1.1、官方介绍

Kubernetes提供两种完全不同的方式来为客户端提供支持,这些客户端可能运行在你的集群中,也能与你的集群的控制平面有关,需要向API(提供Kubernetes API服务的控制平缅组件),服务器完成身份认证。

服务账号(Service Account)为Pod中运行的进程提供身份标识,并映射到ServiceAccount对象。当你向API服务器执行身份认证时,你会讲自己标识为某个用户(User)。Kubernetes能够识别用户的概念,但是Kubernetes自身并不提供User API。

1.2、博客介绍

ServiceAccount为Pod的进程提供身份信息。当用户访问集群时(例如使用kubectl 命令的时候),apiserver会将用户认证为一个特定的User Account(目前通常是admin,除非系统管理员自定义了集群配置)。Pod容器中的进程也可以与apiserver联系,当它们在连接apiserver的时候,它们会被认证为一个特定的service account(例如默认default)。

User account是为人设计的,service account是为Pod中的进程调用Kubernetes API而设计的。
  • User account是夸跨namespace的,而service account则是局限于它所在的namespace。
  • 每个namespace都会创建一个default默认的serviceaccount
  • token controller检测service account的创建,并为他们创建secret。
  • 开启ServiceAccount Adminission Controller后
    • 每个Pod在创建后都会自动设置spec.serviceAccount为default(除非指定了其他ServiceAccount)
    • 验证Pod引用的service account已经存在,否则拒绝创建。
    • 如果没有指定imagePullSecrets,则把service account的imagePullPsecrets加到Pod中。

二、使用默认的服务账号访问API服务器

2.1、查看默认挂载的服务账号

当Pod与API服务器联系时,Pod会被认证为某个特定的ServiceAccount(例如:default)。在每个名称空间中,至少存在一个ServiceAccount。

每个Kubernetes名称空间至少包含一个ServiceAccount:也就是该名称空间的默认服务账号,名为default。如果你在创建Pod时没有指定ServiceAccount,Kubernetes会自动将该名称空间中名为default的ServiceAccount分配给该Pod。

# 通过此命令可以查看名称空间中默认的ServiceAccount
# 查看的是默认的名称空间,你也可以通过-n <namespace>来查看别的名称空间中也存在的默认serviceaccount
[root@master ~]# kubectl get serviceaccount
NAME      SECRETS   AGE
default   1         17d

你可以监视你刚刚创建的Pod的细节。例如:

# 在此之前你需要创建一个Pod
# 直接通过命令行的方式创建一个Pod,使用的是Nginx的镜像
[root@master ~]# kubectl run test --image=nginx:latest --restart=Never
pod/test created
[root@master ~]# kubectl get pod test -o yaml | grep serviceAccount:
  serviceAccount: default

在输出中,你可以看到字段spec.serviceAccountName。当你在创建Pod时未设置该字段时,Kubernetes自动为Pod设置这一属性的取值。

Pod中运行的应用可以使用这一自动挂载的服务账号凭据来访问Kubernetes API

当Pod呗身份认证为某个ServiecAccount时,其访问能力取决于所使用的签权(RBAC权限设置)

2.2、放弃API凭据的自动挂载

如果你不希望kubelet(一个集群中每个节点上运行的代理。它保证容器都运行在Pod中),自动挂载某ServiceAccount对象上设置的automountServiceAccount: false,可以放弃在/var/run/secrets/kubernetes.io/serviceaccount/token处自动挂载服务账号的API凭据。

例如:

[root@master ~]# vim sa-1.yaml
apiVersion: "v1"
kind: ServiceAccount
metadata:
  name: build-robot
automountServiceAccountToken: false
[root@master ~]# kubectl apply -f sa-1.yaml 
serviceaccount/build-robot created

你也可以选择不给特定Pod自动挂载API凭据:

[root@master ~]# vim pod.yaml
apiVersion: "v1"
kind: Pod
metadata:
  name: nginx
spec:
  serviceAccountName: build-robot
  automountServiceAccountToken: false
  containers:
  - name: nginx
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
[root@master ~]# kubectl apply -f pod.yaml 
pod/nginx created
# 通过以下命令来验证是否放弃API凭据的自动挂载
# 通过下面命令可以看到的确是放弃了主动挂载
[root@master ~]# kubectl exec -it nginx -- ls /var/run/secrets/kubernetes.io/serviceaccount/token
ls: cannot access '/var/run/secrets/kubernetes.io/serviceaccount/token': No such file or directory
command terminated with exit code 2
# 第一个test pod没有放弃挂载,可以ls到token文件
[root@master ~]# kubectl exec -it test -- ls /var/run/secrets/kubernetes.io/serviceaccount/token
/var/run/secrets/kubernetes.io/serviceaccount/token

如果ServiceAccount和Pod的.spec都设置了automountServiceAccountToken的值,则Pod上spec的设置优先于服务账号的设置。

2.3、使用多个服务账号

每个名称空间都至少有一个ServiceAccount:名为default的默认ServiceAccount资源。你可以用下面的命令列举你当前名称空间中的所有ServiceAccount

[root@master ~]# kubectl get serviceaccount
NAME          SECRETS   AGE
build-robot   1         8m18s
default       1         17d

2.4、创建额外的ServiceAccount对象

你可以像这样来创建额外的ServiceAccount对象:

ServiceAccount对象的名称必须是一个有效的DNS子域名

[root@master ~]# vim sa-1.yaml 
apiVersion: "v1"
kind: ServiceAccount
metadata:
  name: build-robot
[root@master ~]# kubectl apply -f sa-1.yaml 
serviceaccount/build-robot configured

如果你查询服务账号对象的完整信息,如下所示:

[root@master ~]# kubectl get serviceaccounts build-robot -o yaml
apiVersion: v1
automountServiceAccountToken: false
kind: ServiceAccount
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","automountServiceAccountToken":false,"kind":"ServiceAccount","metadata":{"annotations":{},"name":"build-robot","namespace":"default"}}
  creationTimestamp: "2024-08-17T02:49:26Z"
  name: build-robot
  namespace: default
  resourceVersion: "4644"
  uid: 4d8ba3d5-1e62-4f7b-b505-928acea4d5a1
secrets:
- name: build-robot-token-f22sp

2.5、使用非默认服务账号

使用没有添加注解为放弃API凭据的自动挂载(你也可以选择自己重新创建一个ServiceAccount)

要使用非默认的服务账号,将Pod的.spec.serviceAccountName字段设置为你想用的服务账号名称。

你只能在创建Pod时或者为新Pod指定模板时,你才可以设置serviceAccountName。你不能更新已经存在的Pod的.spec.serviceAccountName字段

[root@master ~]# vim pod-1.yaml
apiVersion: "v1"
kind: Pod
metadata:
  name: nginx-1
spec:
  serviceAccountName: build-robot  # 此处可以指定你想用的服务账号的名称(必须提前创建)
  containers:
  - name: nginx
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
[root@master ~]# kubectl apply -f pod-1.yaml 
pod/nginx-1 created
# 通过以下命令可以看出,创建的新Pod使用的不是默认的ServiceAccount
[root@master ~]# kubectl get pod nginx-1 -o yaml | grep serviceAccountName:
  serviceAccountName: build-robot

三、为服务账号添加ImagePullSecrets

3.1、什么时ImagePullSecrets

是k8s中用于拉取私有容器镜像的机制,。当你在集群中部署使用私有容器镜像的Pod时,通常需要提供身份验证凭据以获得访问权限。

ImagePullSecrets是一个或多个凭据的集合,用于访问私有的Dcoekr镜像仓库。这些凭据通常是通过Kubernetes中的Secret对象来存储的,并在Pod配置中应用。Pod使用这些凭据来获取镜像仓库中的镜像,以确保能够成功拉取私有镜像。

  • 为Pod设置ImagePullSecret所描述的,生成一个镜像拉取Secret:
[root@master ~]# kubectl create secret docker-registry myregistrykey --docker-server=DUMMY_SERVER --docker-username=DUMMY_USERNAME --docker-password=DUMMY_DOCKER_PASSWORD --docker-email=DUMMY_DOCKER_EMAIL
  • 检查该Secret已经被创建
[root@master ~]# kubectl get secrets myregistrykey 
NAME            TYPE                             DATA   AGE
myregistrykey   kubernetes.io/dockerconfigjson   1      88s

3.2、镜像镜像拉取Secret添加到服务账号

接下来更改名称空间的默认服务账号,将该Secret用作imagePullSecret

[root@master ~]# kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}'
serviceaccount/default patched

3.3、检查imagePullSecrets已经被设置到新Pod上

  • 现在,在当前名称空间中创建新Pod并使用默认ServiceAccount时,新Pod的spec.imagePullSecrets会被自动设置
[root@master ~]# kubectl run nginx-3 --image=nginx:latest --restart=Never
pod/nginx-3 created
[root@master ~]# kubectl get pod nginx-3 -o=jsonpath='{.spec.imagePullSecrets[0].name}{"\n"}'
myregistrykey

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部