【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/serviceaccountserviceAccount: defaultserviceAccountName: default[root@k8s-m1 pki]# kubectl  get pod  my-nginx-7ff446c4f4-2d9gz  -o yaml|grep -i tokenname: default-token-glxls- name: default-token-glxlssecretName: default-token-glxls[root@k8s-m1 dashboard]# kubectl exec -it my-nginx-7ff446c4f4-2d9gz -- /bin/bashroot@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-scraperimage: kubernetesui/metrics-scraper:v1.0.4ports:- containerPort: 8000protocol: TCPlivenessProbe:httpGet:scheme: HTTPpath: /port: 8000initialDelaySeconds: 30timeoutSeconds: 30volumeMounts:- mountPath: /tmpname: tmp-volumesecurityContext:allowPrivilegeEscalation: falsereadOnlyRootFilesystem: truerunAsUser: 1001runAsGroup: 2001serviceAccountName: kubernetes-dashboard
.....

service account的创建

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

#yaml文件
[root@k8s-m1 k8s-serviceaccount]# cat serviceaccount.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:name: adminnamespace: 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: v1fieldsType: FieldsV1fieldsV1:f:secrets:.: {}k:{"name":"admin-token-r7w27"}:.: {}f:name: {}manager: kube-controller-manageroperation: Updatetime: "2023-07-12T03:22:21Z"- apiVersion: v1fieldsType: FieldsV1fieldsV1:f:metadata:f:annotations:.: {}f:kubectl.kubernetes.io/last-applied-configuration: {}manager: kubectl-client-side-applyoperation: Updatetime: "2023-07-12T03:22:21Z"name: adminnamespace: defaultresourceVersion: "86037692"selfLink: /api/v1/namespaces/default/serviceaccounts/adminuid: 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-podnamespace: defaultlabels:app: nginx
spec:containers:- name: nginximage: nginxports:- name: httpcontainerPort: 80serviceAccountName: 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-r7w27Optional:    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+OMITTEDserver: https://192.168.2.250:8443name: kubernetes
contexts: #上下文列表
- context: #定义哪个集群被哪个用户访问cluster: kubernetesuser: kubernetes-adminname: kubernetes-admin@kubernetes
- context:cluster: kubernetesuser: marguname: margu@kubernetes
current-context: kubernetes-admin@kubernetes #当前上下文
kind: Config
preferences: {}
users:   #用户列表
- name: kubernetes-adminuser:client-certificate-data: REDACTEDclient-key-data: REDACTED
- name: marguuser:client-certificate-data: REDACTED

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

自建证书和账号进行访问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的知识分享,请前往博客主页。编写过程中,难免出现差错,敬请指出

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/21102.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

flink启动报错Failed to construct kafka producer

flink local模式下启动 sink2kafka报错&#xff0c;具体报错如下 apache.kafka.common.KafkaException: Failed to construct kafka producerat org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:432)at org.apache.kafka.clients.producer.…

wps如何加载mathtype和Endnote

为了支持国产化软件&#xff0c;弃用office套装&#xff0c;现在改用wps办公软件&#xff0c;但是写作科技论文的时候还是会出现很多的不方便&#xff0c;比如文献引用、公式排版编号等等。尽管wps自带了公式编辑器&#xff0c;然鹅这可太不方便了&#xff0c;因此把几个技巧总…

谈谈你对 binder 的理解?

面试官提了一个问题&#xff0c;我们来看看 &#x1f60e;、&#x1f628; 和 &#x1f914;️ 三位同学的表现如何吧 &#x1f60e; 自认为无所不知&#xff0c;水平已达应用开发天花板&#xff0c;目前月薪 10k 面试官️&#xff1a;谈谈你对 binder 的理解 &#x1f60e;&a…

驱动开发-day10

驱动代码&#xff1a; #include <linux/cdev.h> #include <linux/device.h> #include <linux/fs.h> #include <linux/gpio.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/mod_devicetable.h> #include …

本地服务器localhost:3000一直连接不上

1.检查使用端口3000的进程: 在Windows上,运行 netstat -ano | findstr :3000在Mac/Linux上,运行lsof -i :3000 这将列出当前使用端口3000的任何进程。您要终止这些进程以释放该端口。 2.检查防火墙规则: 确保您的防火墙允许连接到localhost:3000。在MacOS和Windows上,通常不…

【分布式能源的选址与定容】基于多目标粒子群算法分布式电源选址定容规划研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

防范 XSS 攻击的措施

防范 XSS 攻击的措施 XSS&#xff08;Cross-site scripting&#xff09;攻击是一种常见的网络安全漏洞&#xff0c;它可以通过注入恶意代码来攻击用户的计算机和浏览器&#xff0c;从而窃取用户的敏感信息或执行恶意操作。本篇文章将介绍防范 XSS 攻击的措施&#xff0c;并提供…

JConsole或者JvisualVM远程连接jetty进行jvm监控

最近项目发现了服务有内存泄漏的问题&#xff0c;但是在jvm上并没有配置即jvm没有配置 -XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/tmp/heapdump.hprof 这两个参数&#xff0c;导致在发生了oom后只能看到日志中有OOM异常&#xff0c;其他的并不能分析出来&#xff0c;等…

CSS3 动画 animation 入门学习笔记 之 属性详解

文章目录 简单介绍 CSS 动画CSS 动画的作用CSS 动画语法介绍CSS 动画属性animation-nameanimation-durationanimation-delayanimation-directionanimation-iteration-countanimation-play-stateanimation-timing-functionanimation-fill-modeanimation 简单介绍 CSS 动画 引用…

css3提供的网页布局

css3提供的网页布局 弹性盒子模型&#xff08;flex box&#xff09;&#xff1a; 设置成弹性盒子 默认横着排放&#xff08;div也是&#xff09; 当子盒子给的宽度过大&#xff0c;总的子盒子宽度超过父级盒子&#xff0c;会自动适配&#xff0c;计算整个盒子父级的大小&#…

【计算机视觉 | 图像分割】arxiv 计算机视觉关于图像分割的学术速递(7 月 13 日论文合集)

文章目录 一、分割|语义相关(7篇)1.1 Correlation-Aware Mutual Learning for Semi-supervised Medical Image Segmentation1.2 RFENet: Towards Reciprocal Feature Evolution for Glass Segmentation1.3 Sem-CS: Semantic CLIPStyler for Text-Based Image Style Transfer1.4…

Django_静态资源配置和ajax(九)

目录 一、静态资源配置 二、AJAX ajax作用 使用ajax 1、环境配置 2、创建html模板文件 3、编写视图函数并添加路由 4、运行django开发服务器进行验证 源码等资料获取方法 一、静态资源配置 静态资源的相关配置都在项目目录下的 settings.py 文件中进行配置。配置参数如…