【kubernetes系列】Kubernetes之ServiceAccount

这篇具有很好参考价值的文章主要介绍了【kubernetes系列】Kubernetes之ServiceAccount。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概述

Service Account是什么呢,顾名思义,服务账号,一种给服务使用的账号,它不是给Kubernetes的集群的用户(系统管理员、运维人员、租户用户等)使用,而是给运行在Pod里的进程用的,它为Pod中的进程提供必要的身份证明。

当用户访问集群(例如使用kubectl命令)时,apiserver会将用户认证为一个特定的User Account(目前通常是admin,除非系统管理员自定义了集群配置)。Pod 容器中的进程也可以与apiserver联系,但Pod 中访问 Kubernetes API Server 服务的时候,是以 Service 方式访问服务名为 kubernetes 这个服务的,而kubernetes服务只在 HTTPS 安全端口 443 上提供服务,那么如何进行身份认证呢?其实它们之间是通过一个特定的Service Account(例如default)进行认证访问。

这是在用一种类似HTTP Token的新的认证方式–ServiceAccount Auth,Pod中的服务调用Kubernetes API的时候,在HTTP Header中传递了一个 Token 字符串,这类似于之前提到的HTTP Token认证方式,存在以下几个不同点:

  • 该Token(/run/secrets/kubernetes.io/serviceaccount/token)是动态生成的,确切的说,是由KubernetesController进程用API Server的私钥(–service-account-private-key-file指定的私钥)签名生成的一个JWT Secret。

  • 官方提供的客户端REST框架代码里,通过HTTPS方式与API Server建立链接后,会用Pod里指定路径下的一个CA证书(/run/secrets/kubernetes.io/serviceaccount/ca.crt)验证API Server发来的证书,验证是否是被CA证书签名的合法证书。

  • API Server收到这个Token以后,采用自己的私钥(实际是使用参数service-account-key-file指定的私钥,如果此参数没有设置,则默认采用tls-private-key-file指定的参数,即自己的私钥),对token进行合法性验证。

认证过程中涉及到Pod中的三个文件,如下:
/run/secrets/kubernetes.io/serviceaccount/token
/run/secrets/kubernetes.io/serviceaccount/ca.crt
/run/secrets/kubernetes.io/serviceaccount/namespace(客户端采用这里指定的namespace作为参数调用Kubernetes API)
这三个文件由于参与到Pod进程与API Server认证的过程中,起到了类似Secret(私密凭据)的作用,所以他们被称为Kubernetes Secret对象。Secret从属于ServiceAccount资源对象,属于Service Account的一部分,一个ServiceAccount对象里面可以包括多个不同的Secret对象,分别用于不同目的的认证活动。

user account 和service account的区别:

  • User account是为人设计的,而service account则是为Pod中的进程调用Kubernetes API而设计;
  • User account是跨namespace的,而service account则是仅局限它所在的namespace;
  • 每个namespace都会自动创建一个default service account
  • Token controller检测service account的创建,并为它们创建secret
  • 开启ServiceAccount Admission Controller后
    • 每个Pod在创建后都会自动设置spec.serviceAccount为default(除非单独指定使用其他ServiceAccout)
    • 验证Pod引用的service account已经存在,否则拒绝创建
    • 如果Pod没有指定ImagePullSecrets,则把service account的ImagePullSecrets加到Pod中
    • 每个container启动后都会挂载该Service Account的token和ca.crt到/var/run/secrets/kubernetes.io/serviceaccount/目录下

分析系统自动生成的serviceaccount

查看系统中ServiceAccount对象,可以看到每个命名空间下都有一个名为default的Service Account对象,并且都包含一个名为default-token-xxx的Secret,这个Secret同时是“Mountable secrets”,表明他
是需要被Mount到Pod上的。

[root@k8s-m1 pki]# kubectl describe sa default 
Name:                default
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   default-token-glxls
Tokens:              default-token-glxls
Events:              <none>kubectl describe serviceaccounts
[root@k8s-m1 pki]# kubectl describe secrets default-token-glxls 

default-token-xxx包括三个数据项依次为:
ca.crt
namespace
token

而查看每个命名空间下任意一个没有具体指明使用其他serviceAccount的pod,如下

[root@k8s-m1 pki]# kubectl  get pod  my-nginx-7ff446c4f4-2d9gz  -o yaml|grep -i serviceaccount
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
  serviceAccount: default
  serviceAccountName: default

[root@k8s-m1 pki]# kubectl  get pod  my-nginx-7ff446c4f4-2d9gz  -o yaml|grep -i token
      name: default-token-glxls
  - name: default-token-glxls
      secretName: default-token-glxls

[root@k8s-m1 dashboard]# kubectl exec -it my-nginx-7ff446c4f4-2d9gz -- /bin/bash

root@my-nginx-7ff446c4f4-2d9gz:/# ls /var/run/secrets/kubernetes.io/serviceaccount/ -l
total 0
lrwxrwxrwx 1 root root 13 Jul  1 01:31 ca.crt -> ..data/ca.crt
lrwxrwxrwx 1 root root 16 Jul  1 01:31 namespace -> ..data/namespace
lrwxrwxrwx 1 root root 12 Jul  1 01:31 token -> ..data/token
root@my-nginx-7ff446c4f4-2d9gz:/# 

可以发现使用的 serviceAccount是default,token也是使用的名为defaul-token-***的token,且目录/var/run/secrets/kubernetes.io/serviceaccount/下有我们上面在default-token里面看到的三个数据项(ca.crt、namespace、token)。综上:每个namespace下有一个名为default的默认的ServiceAccount对象,这个ServiceAccount里有一个名为Tokens的可以作作为Volume一样被Mount到Pod里的Secret,当Pod启动时这个Secret会被自动Mount到Pod的指定目录下,可以使用的secret的相关信息让当前名称空间中所有的pod连接至apiserver,从而保证pod与apiserver之间的通信。

  • 一个ServiceAccount可以包括多个Secrets对象:

  • 名为Tokens的Secret用于访问API Server的Secret,也被称为ServiceAccountSecret;

  • 名为Image Pull secrets的Secret用于下载容器镜像时的认证过程,通常镜像库运行在Insecure模式下,所以这个Secret为空;

用户自定义的其他ServiceAccount,用于权限设置

默认的service account 仅仅只能获取当前Pod自身的相关属性,无法观察到其他名称空间Pod的相关属性信息。如果想要扩展Pod,假设有一个Pod需要用于管理其他Pod或者是其他资源对象(例如dashboard),是无法通过自身的名称空间的default service account进行获取其他Pod的相关属性信息的,此时就需要进行手动创建一个serviceaccount,并在创建Pod时进行定义使用。如下在部署kubernetes-dashboard时我们一般就创建了一个叫做kubernetes-dashboard的Service Account,同时还创建了一个与之对应的secret。

  ......
  containers:
    - name: dashboard-metrics-scraper
      image: kubernetesui/metrics-scraper:v1.0.4
      ports:
        - containerPort: 8000
          protocol: TCP
      livenessProbe:
        httpGet:
          scheme: HTTP
          path: /
          port: 8000
        initialDelaySeconds: 30
        timeoutSeconds: 30
      volumeMounts:
      - mountPath: /tmp
        name: tmp-volume
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        runAsUser: 1001
        runAsGroup: 2001
  serviceAccountName: kubernetes-dashboard
.....

service account的创建

可以通过kubectl explain sa查看serviceAccount的yaml文件格式。

#yaml文件
[root@k8s-m1 k8s-serviceaccount]# cat serviceaccount.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin
  namespace: default
#创建
[root@k8s-m1 k8s-serviceaccount]# kubectl apply  -f serviceaccount.yaml 
serviceaccount/admin created
#查看
[root@k8s-m1 k8s-serviceaccount]# kubectl get sa admin 
NAME    SECRETS   AGE
admin   1         21s
[root@k8s-m1 k8s-serviceaccount]# kubectl get secrets 
NAME                                  TYPE                                  DATA   AGE
admin-token-r7w27                     kubernetes.io/service-account-token   3      36s


#查看详细信息
[root@k8s-m1 k8s-serviceaccount]# kubectl get sa admin -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"admin","namespace":"default"}}
  creationTimestamp: "2023-07-12T03:22:21Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:secrets:
        .: {}
        k:{"name":"admin-token-r7w27"}:
          .: {}
          f:name: {}
    manager: kube-controller-manager
    operation: Update
    time: "2023-07-12T03:22:21Z"
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:kubectl.kubernetes.io/last-applied-configuration: {}
    manager: kubectl-client-side-apply
    operation: Update
    time: "2023-07-12T03:22:21Z"
  name: admin
  namespace: default
  resourceVersion: "86037692"
  selfLink: /api/v1/namespaces/default/serviceaccounts/admin
  uid: d4568461-5942-433b-a1c5-228e1b2e8125
secrets:
- name: admin-token-r7w27
#可以看到secret就是上面看到的admin开头的secret

可以发现有一个 secret已经被自动创建(其实secret也可以自己手动创建,可参考部署dashboard时使用的yaml文件),使用时需要在 pod 的spec.serviceAccountName 字段中将name设置为您想要用的 service account 名字即可。在 pod 创建之初 service account 就必须已经存在,否则创建将被拒绝。并且需要注意的是不能更新已创建的 pod 的 service account。

serviceaccount的引用

上面在default名称空间创建了一个serviceaccount为admin,可以看到已经自动生成了一个secret(包含token信息) admin-token-r7w27,下面展示如何使用自定义的serviceaccount

[root@k8s-m1 k8s-serviceaccount]# cat use-sa-pod.yml 
apiVersion: v1
kind: Pod
metadata:
  name: use-sa-pod
  namespace: default
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - name: http
      containerPort: 80
  serviceAccountName: admin

[root@k8s-m1 k8s-serviceaccount]# kubectl apply -f use-sa-pod.yml 
pod/use-sa-pod created

[root@k8s-m1 k8s-serviceaccount]# kubectl describe po use-sa-pod 
......
Volumes:
  admin-token-r7w27:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  admin-token-r7w27
    Optional:    false
......

User Account的定义及使用

在K8S集群当中,每一个用户对资源的访问都是需要通过apiserver进行通信认证才能进行访问的,那么在此机制当中,对资源的访问凭证可以是用token保存,也可以是通过配置文件的方式进行保存,kubectl命令行工具使用kubeconfig文件来查找选择群集并与群集的APIserver进行通信。可以通过kubectl config进行查看编辑kubeconfig配置文件,配置文件路径$HOME/.kube/config文件,eg:/root/.kube/config 如下:

[root@k8s-m1 k8s-serviceaccount]# kubectl config view 
apiVersion: v1
clusters:  #集群列表
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://192.168.2.250:8443
  name: kubernetes
contexts: #上下文列表
- context: #定义哪个集群被哪个用户访问
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
- context:
    cluster: kubernetes
    user: margu
  name: margu@kubernetes
current-context: kubernetes-admin@kubernetes #当前上下文
kind: Config
preferences: {}
users:   #用户列表
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
- name: margu
  user:
    client-certificate-data: REDACTED

在上面的配置文件当中,定义了集群、上下文以及用户。其中Config也是K8S的标准资源之一,在该配置文件当中定义了一个集群列表,指定的集群可以有多个;用户列表也可以有多个,指明集群中的用户;而在上下文列表当中,是进行定义可以使用哪个用户对哪个集群进行访问,以及当前使用的上下文是什么。如图:定义了用户kubernetes-admin可以对kubernetes该集群的访问,用户kubernetes-user1对Cluster1集群的访问。
【kubernetes系列】Kubernetes之ServiceAccount,Kubernetes,kubernetes,算法

自建证书和账号进行访问apiserver演示

可用于对不同群体对集群的访问权限控制。过程请参考https://blog.csdn.net/margu_168/article/details/131564406

关于Service Account与Secret相关的一些运行机制

Controller manager创建了ServiceAccountController与Token Controllerl两个安全相关的控制器。

其中ServiceAccountController一直监听Service Account和Namespace的事件,如果一个Namespace中没有default Service Account,那么Service Account Controller就会为该Namespace创建一个默认的(default)的Service Account,这就是我们之前看到的每个namespace下都有一个名为default的ServiceAccount的原因。

如果Controller manager进程在启动时指定了API Server私钥(service-account-private-key-file)参数,那么Controller manager会创建Token Controller。

Token Controller也监听Service Account的事件,如果发现新建的Service Account里没有对应的Service Account Secret,则会用API Server私钥创建一个Token(JWT Token),并用该Token、CA证书Namespace名称等三个信息产生一个新的Secret对象,然后放入刚才的Service Account中;如果监听到的事件是删除Service Account事件,则自动删除与该Service Account相关的所有Secret。

此外,Token Controller对象同时监听Secret的创建、修改和删除事件,并根据事件的不同做不同的处理。

当我们在API Server的鉴权过程中启用了Service Account类型的准入控制器,即在kube-apiserver的启动参数中包括下面的内容时(kubeadm部署的):

–enable-admission-plugins=ServiceAccount

则针对Pod新增或修改的请求,Service Account准入控制器会验证Pod里Service Account是否合法。

  • 如果spec.serviceAccount域没有被设置,则Kubernetes默认为其制定名字为default的Serviceaccount;
  • 如果Pod的spec.serviceAccount域指定了default以外的ServiceAccount,而该ServiceAccount没有事先被创建,则该Pod将创建失败;
  • 如果在Pod中没有单独指定“ImagePullSecrets”,那么该spec.serviceAccount域指定的ServiceAccount的“ImagePullSecrets”会被加入该Pod;
  • 给Pod添加一个新的Volume,在该Volume中包含ServiceAccountSecret中的Token,并将Volume挂载到Pod中所有容器的指定目录下(/var/run/secrets/kubernetes.io/serviceaccount);

所以,通过上面的介绍我们知道ServiceAccount正常运行需要以下几个控制器:
Admission Controller
Service Account Controller
Token Controller

更多关于kubernetes的知识分享,请前往博客主页。编写过程中,难免出现差错,敬请指出文章来源地址https://www.toymoban.com/news/detail-574917.html

到了这里,关于【kubernetes系列】Kubernetes之ServiceAccount的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【kubernetes系列】Kubernetes中的重要概念

    ​ 在学习k8s之前,必须先了解 Kubernetes 的几个重要概念,它们是组成 Kubernetes 集群的基石。先作大致了解,后续再详细分享。(参考Kubernetes权威指南) 一、Master Kubernetes 里的Master指的是集群的控制节点, 每个Kubernetes 集群里至少需要有一个Master节点负责整个集群的管理和控

    2024年02月11日
    浏览(31)
  • 【云原生 | Kubernetes 系列】— Kubernetes存储方案

    目录 【云原生 | Kubernetes 系列】— Kubernetes存储方案 🍇 一、基本存储 EmptyDir HostPath NFS 搭建nfs服务器 🍋 二、高级存储 PV和PVC pv pvc 演示 -NFS StorageClass(动态存储) StorageClass准备 创建deployment应用StorageClass 创建StatefulSet应用StorageClass 🥭三、配置存储 ConfigMap ConfigMap 的创建

    2024年02月03日
    浏览(48)
  • 【kubernetes系列】kubernetes之计算资源管理

    在 Kubernetes 中,Node 提供资源,而 Pod 使用资源。其中资源分为计算(CPU、Memory、GPU)、存储(Disk、SSD)、网络(Network Bandwidth、IP、Ports)。这些资源提供了应用运行的基础,正确理解这些资源以及集群调度如何使用这些资源,对于大规模的 Kubernetes 集群来说至关重要,不仅

    2024年02月17日
    浏览(44)
  • 【kubernetes系列】Kubernetes之资源限制ResourceQuota

    当多个用户或团队共享具有固定节点数目的集群时,人们会担心有人使用超过其基于公平原则所分配到的资源量。我们可以通过ResourceQuota来解决这个问题,对每个namespace的资源消耗总量提供限制。它可以限制命名空间中某种类型的对象的总数目上限,也可以限制命名空间中的

    2024年02月16日
    浏览(44)
  • 【kubernetes系列】Kubernetes中的重要概念(三)

    在实际的工作中,我们使用Kubernetes 通常不会直接创建 Pod,而是通过 各种 Controller 来管理 Pod 的。Controller 中定义了 Pod 的部署特性,比如有几个副本,在什么样的 Node 上运行等。为了满足不同的业务场景,Kubernetes 提供了多种 Controller,包括 Deployment、Replication Controller、Repl

    2024年02月11日
    浏览(29)
  • 【kubernetes系列】Kubernetes之Taints和tolerations

    节点亲和性是pod的一种属性(优先选择或硬性要求),它使 pod 被优先分配到一类特定的节点上。而Taint则相反,它使节点能够排斥一类特定的 pod。 Taints(污点)与tolerations(容忍度)一起工作确保Pod不会被调度到不合适的节点上。Taints是node的属性,单个节点可以添加多个

    2024年02月12日
    浏览(34)
  • 【kubernetes系列】kubernetes之基础组件高可用方案

    从前面的基础章节了解到,kubernetes的mastere节点基础组件大致包括kube-apiserver、kube-controller-manager、kube-scheduler,还有一个重要的数据存储服务etcd。这些主件作为master节点的服务相当重要,很多时候我们都需要保证其高可用。下面将分享在实际工作中的一些常见做法。 在使用私

    2024年02月16日
    浏览(36)
  • 【kubernetes系列】Kubernetes之配置dashboard安装使用

    Dashboard 是基于网页的 Kubernetes 用户界面。 你可以使用 Dashboard 将容器应用部署到 Kubernetes 集群中,也可以对容器应用排错,还能管理集群资源。 你可以使用 Dashboard 获取运行在集群中的应用的概览信息,也可以创建或者修改 Kubernetes 资源 (如 Deployment,Job,DaemonSet 等等)。

    2024年02月07日
    浏览(43)
  • 云原生Kubernetes系列 | Kubernetes Secret及ConfigMap

       使用某些镜像例如mysql,是需要变量来传递密

    2024年02月04日
    浏览(42)
  • 【kubernetes系列】kubernetes之initcontainer初始化容器

    Init Container就是用来做初始化工作的容器,可以是一个或者多个,如果有多个的话,这些容器会按定义的顺序依次执行,只有所有的Init Container执行完后,主容器才会被启动。我们知道一个Pod里面的所有容器是共享数据卷和网络命名空间的,所以Init Container里面产生的数据可以

    2024年02月12日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包