ServiceAccount深度解析

news2024/11/24 9:48:04

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 service account

  • Token controller检测service account的创建,并为他们创建secret

  • 开启ServiceAccount Admission Controller后

    • 每个Pod在创建后都会自动设置spec.serviceAccount为default(除非指定了其他ServiceAccount)

    • 验证Pod引用的service account已经存在,否则拒绝创建

    • 如果Pod没有指定ImagePullSecretes,则把service account的ImagePullSecretes加到Pod中

      什么是ImagePullSecretes?

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

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

      以下是一个示例,展示了如何在 Pod 配置中使用 ImagePullSecrets

      yamlCopy codeapiVersion: v1
      kind: Pod
      metadata:
        name: my-app
      spec:
        containers:
          - name: my-container
            image: private-registry.com/my-image:latest
        imagePullSecrets:
          - name: my-secret
      

      在上面的示例中,imagePullSecrets 部分指定了一个名为 my-secretSecret,这个 Secret 包含了访问私有镜像仓库所需的凭据。这样,Pod 就可以使用这个凭据来拉取 private-registry.com/my-image:latest 镜像。

      要使用 ImagePullSecrets,你需要执行以下步骤:

      1. 创建一个 Secret 对象,其中包含访问私有镜像仓库的凭据(如用户名和密码)。
      2. 在 Pod 的配置中的 imagePullSecrets 部分引用这个 Secret
      3. 当 Pod 启动时,Kubernetes 将使用 ImagePullSecrets 中的凭据来拉取所需的私有镜像。

      总之,ImagePullSecrets 是 Kubernetes 中用于访问私有容器镜像的机制,它允许在 Pod 配置中引用存储在 Secret 中的凭据,以确保能够拉取私有镜像。

    • 每个container启动后都会挂载该service account的token和ca.crt到/var/run/secrets/kubernetes.io/serviceaccount/

在 Kubernetes 中,每个 Service Account 都有一个关联的安全令牌(Token),用于对 Kubernetes API 进行身份验证,以及一个与集群通信的根证书(ca.crt)。这些元素有助于确保 Service Account 在与 Kubernetes API 交互时的安全性。

  1. Token(令牌):每个 Service Account 都会被分配一个安全令牌,用于身份验证。这个令牌是一个长字符串,它允许 Service Account 访问 Kubernetes API 中特定于命名空间的资源。当 Service Account 的 Pod 尝试与 API 服务器通信时,它会使用这个令牌进行身份验证,以获取访问权限。令牌会自动挂载到 Pod 中的 /var/run/secrets/kubernetes.io/serviceaccount/token 文件中,供应用程序使用。
  2. ca.crt(根证书):与每个 Service Account 关联的根证书用于验证与 Kubernetes API 服务器之间的通信的安全性。根证书是集群的 CA(Certificate Authority)颁发的,用于加密和验证通信。在与 Kubernetes API 服务器进行通信时,Pod 可以使用这个根证书来验证服务器证书的有效性,确保通信的机密性和完整性。

这两个元素结合在一起,确保了 Service Account 的安全性和通信的安全性。Pod 使用令牌来证明自己的身份,同时使用根证书来验证服务器的身份,以确保与 Kubernetes API 服务器的交互是安全的。

请注意,Service Account 的 Token 和根证书是自动生成的,并在创建 Service Account 时为其分配。这些元素对于运行在 Kubernetes 集群中的应用程序来说是透明的,但它们在底层提供了身份验证和通信安全性的支持。

使用默认的Service Account访问API Server

当创建 pod 的时候,如果没有指定一个 service account,系统会自动得在与该pod 相同的 namespace 下为其指派一个default service account。如果获取刚创建的 pod 的原始 json 或 yaml 信息(例如使用kubectl get pods podename -o yaml命令),将看到spec.serviceAccountName字段已经被设置为 default。

[root@k8s-master ~]# kubectl get pods
NAME                     READY     STATUS    RESTARTS   AGE
filebeat-ds-hxgdx        1/1       Running   1          34d
filebeat-ds-s466l        1/1       Running   2          34d
myapp-0                  1/1       Running   0          3h
myapp-1                  1/1       Running   0          3h
myapp-2                  1/1       Running   0          4h
myapp-3                  1/1       Running   0          4h
pod-vol-demo             2/2       Running   0          2d
redis-5b5d6fbbbd-q8ppz   1/1       Running   1          2d
[root@k8s-master ~]# kubectl get pods/myapp-0 -o yaml |grep "serviceAccountName"
  serviceAccountName: default

[root@k8s-master ~]# kubectl describe pods myapp-0
Name:               myapp-0
Namespace:          default
......
Volumes:
  ......
  default-token-j5pf5:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-j5pf5
    Optional:    false

从上面可以看到每个Pod无论定义与否都会有一个存储卷,这个存储卷为default-token-*** token令牌,这就是service account是为Pod中的进程与apiserver联系提供身份认证信息。通过secret进行定义,由于认证信息属于敏感信息,所以需要保存在secret资源当中,并以存储卷的方式挂载到Pod当中。从而让Pod内运行的应用通过对应的secret中的service account来连接apiserver,并完成认证。每个 namespace 中都有一个默认的叫做 default 的 service account资源。可以使用kubectl get secret命令当前名称空间内的secret,也可以看到对应的default-token。可以使用的预制认证信息让当前名称空间中所有的pod连接至apiserver,从而保证pod与apiserver之间的通信。

[root@k8s-master ~]# kubectl get sa
NAME      SECRETS   AGE
default    1         50d
[root@k8s-master ~]# kubectl get sa -n ingress-nginx  #前期创建的ingress-nginx名称空间也存在这样的serviceaccount
NAME                           SECRETS   AGE
default                        1         11d
nginx-ingress-serviceaccount   1         11d
[root@k8s-master ~]# kubectl get secret
NAME                    TYPE                                  DATA      AGE
default-token-j5pf5     kubernetes.io/service-account-token   3         50d
mysecret                Opaque                                2         1d
tomcat-ingress-secret   kubernetes.io/tls                     2         10d
[root@k8s-master ~]# kubectl get secret -n ingress-nginx
NAME                                       TYPE                                  DATA      AGE
default-token-zl49j                        kubernetes.io/service-account-token   3         11d
nginx-ingress-serviceaccount-token-mcsf4   kubernetes.io/service-account-token   3         11d

默认的service account仅仅只能获取当前Pod自身的相关属性,无法观察到其他名称空间Pod的相关属性信息。如果想要拓展Pod,假设有一个Pod需要用于管理其他Pod或者是其他资源对象(例如dashboard),是无法通过自身的名称空间的default service account进行获取其他Pod的相关属性信息的,此时就需要进行手动创建一个serviceaccount,并在创建Pod时进行定义。

创建一个ServiceAccount

[root@master-1 app]# vim serviceaccount.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin
  namespace: default

[root@master-1 app]# kubectl apply -f serviceaccount.yaml 
serviceaccount/admin created

[root@master-1 app]# kubectl get sa
NAME              SECRETS   AGE
admin             1         31s
default           1         20d
nfs-provisioner   1         18d

[root@master-1 app]# kubectl get secret
NAME                          TYPE                                  DATA   AGE
admin-token-j7n8j             kubernetes.io/service-account-token   3      27m
default-token-zmv4x           kubernetes.io/service-account-token   3      20d
mysecret                      Opaque                                2      19d
nfs-provisioner-token-xjn7p   kubernetes.io/service-account-token   3      18d

[root@master-1 app]# 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: "2019-02-12T03:07:07Z"
  name: admin
  namespace: default
  resourceVersion: "2606053"
  selfLink: /api/v1/namespaces/default/serviceaccounts/admin
  uid: 48250903-2e73-11e9-a8c7-d8490b8af3ae
secrets:
- name: admin-token-j7n8j

看到有一个 token 已经被自动创建,只需要在 pod 的spec.serviceAccountName 字段中将name设置为您想要用的 service account 名字即可。在 pod 创建之初 service account 就必须已经存在,否则创建将被拒绝。需要注意的是不能更新已创建的 pod 的 service account

ServiceAccount的自定义使用

这里在default名称空间创建了一个serviceaccount为admin,可以看到已经自动生成了一个Tokens:admin-token-j7n8j,下面展示如何使用自定义的serviceaccount

[root@master-1 app]# vim pod-sa-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-sa-demo
  namespace: default
  labels:
    app: myapp
    tier: frontend
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    ports:
    - name: http
      containerPort: 80
  serviceAccountName: admin
[root@master-1 app]# kubectl apply -f pod-sa-demo.yaml 
pod/pod-sa-demo created
[root@master-1 app]# kubectl describe pods pod-sa-demo
......
Volumes:
  admin-token-j7n8j:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  admin-token-j7n8j
    Optional:    false
......

User Account的定义以及使用

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

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

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

在这里插入图片描述

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

注意:此步骤在/etc/kubernetes/pki路径下执行,因为需要用到Kubernetes CA证书。

  1. 生成证书

    [root@k8s-master pki]# (umask 077;openssl genrsa -out magedu.key 2048)
    Generating RSA private key, 2048 bit long modulus
    ............................................................................................+++
    ...................................................................................+++
    e is 65537 (0x10001)
    
    [root@k8s-master pki]# ll magedu.key 
    -rw------- 1 root root 1675 Oct 12 23:52 magedu.key
    
    
  2. 使用ca.crt进行签署

    [root@k8s-master pki]# openssl req -new -key magedu.key -out magedu.csr -subj "/CN=magedu"  证书签署请求(CN表示用户名,O表示组)
    
    [root@k8s-master pki]# openssl x509 -req -in magedu.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out magedu.crt -days 365  #证书签署
    Signature ok
    subject=/CN=magedu
    Getting CA Private Key
    
    [root@k8s-master pki]# openssl x509 -in magedu.crt -text -noout
    

    生成证书和签署证书是证书颁发的两个不同步骤,这两个步骤涉及到不同的操作和角色,用于创建和验证数字证书的完整新和合法性。

    • 生成证书:在这个步骤中,证书的申请者(通常是实体,服务器胡总和客户端)生成一个密钥对,包括一个私钥和一个公钥。 私钥用于加密和解密数据,而公钥用于加密和验证签名。然后证书申请者会将公约和一些标识信息(如域名,组织名称等)提供给证书颁发机构(CA)
    • 签署证书:在这个步骤中,证书颁发机构(CA)使用其自己的私钥来对证书申请者提供的公钥和标识信息进行签名。这个签名包括一些元数据,比如颁发者,有效期,颁发日期等。
  3. 添加到用户认证

    [root@k8s-master pki]# kubectl config set-credentials magedu --client-certificate=./magedu.crt --client-key=./magedu.key --embed-certs=true
    User "magedu" set.
    
    [root@k8s-master pki]# kubectl config set-context magedu@kubernetes --cluster=kubernetes --user=magedu
    Context "magedu@kubernetes" created.
    
    [root@k8s-master pki]# kubectl config view
    apiVersion: v1
    clusters:
    - cluster:
        certificate-authority-data: REDACTED
        server: https://192.168.56.11:6443
      name: kubernetes
    contexts:
    - context:
        cluster: kubernetes
        user: kubernetes-admin
      name: kubernetes-admin@kubernetes
    - context:
        cluster: kubernetes
        user: magedu
      name: magedu@kubernetes
    current-context: kubernetes-admin@kubernetes
    kind: Config
    preferences: {}
    users:
    - name: kubernetes-admin
      user:
        client-certificate-data: REDACTED
        client-key-data: REDACTED
    - name: magedu
      user:
        client-certificate-data: REDACTED
        client-key-data: REDACTED
    
    [root@k8s-master pki]# kubectl config use-context magedu@kubernetes
    Switched to context "magedu@kubernetes".
    
    [root@k8s-master pki]# kubectl get pods
    No resources found.
    Error from server (Forbidden): pods is forbidden: User "magedu" cannot list pods in the namespace "default"
    

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Pytest测试框架2

目录: pytest参数化用例pytest标记测试用例pytest设置跳过、预期失败用例pytest运行用例pytest测试用例调度与运行pytest命令行常用参数python执行pytestpytest异常处理 1.pytest参数化用例 参数化 通过参数的方式传递数据,从而实现数据和脚本分离。…

C++三个线程依次打印abc

代码 #include<iostream> #include<thread> #include<mutex> #include<condition_variable> using namespace std; mutex mtx; condition_variable cv; int flag0; void A(){unique_lock<mutex>lk(mtx);int count0;while(count<10){while(fl…

【工程实践】使用EDA(Easy Data Augmentation)做数据增强

工程项目中&#xff0c;由于数据量不够&#xff0c;经常需要用到数据增强技术&#xff0c;尝试使用EDA进行数据增强。 1.EDA简介 EDA是一种简单但是非常有效的文本数据增强方法&#xff0c;是由美国Protago实验室发表于 EMNLP-IJCNLP 2019 会议。EDA来自论文《EDA: Easy Data…

AI Chat 设计模式:12. 享元模式

本文是该系列的第十二篇&#xff0c;采用问答式的方式展开&#xff0c;问题由我提出&#xff0c;答案由 Chat AI 作出&#xff0c;灰色背景的文字则主要是我的一些思考和补充。 问题列表 Q.1 给我介绍一下享元模式A.1Q.2 也就是说&#xff0c;其实共享的是对象的内部状态&…

【Pytorch】P0 Windows 安装 Pytorch

Windows安装Pytorch 前言PyTorch&#xff0c;CUDA与GPUCUDA ToolkitSo...总而言之 整体流程一&#xff1a;安装 CUDA Toolkit步骤一&#xff1a;获取CUDA版本信息步骤二&#xff1a;下载安装 CUDA Toolkit步骤三&#xff1a;按照默认步骤安装步骤四&#xff1a;检查CUDA安装成功…

Android应用开发(6)TextView进阶用法

Android应用开发学习笔记——目录索引 上一章Android应用开发&#xff08;5&#xff09;文本视图&#xff08;TextView&#xff09;介绍了文本视图&#xff08;TextView&#xff09;设置文本内容、设置文本大小、设置文本显示颜色。 TextView是最基础的文本显示控件&#xff…

cpu的几核和几线程是什么意思

先说一下i7-12800H 14核 20线程是什么意思 答: 超线程功能先简单的解释下就是:能使一个大核拥有同时处理两个线程的能力. 14核是大小核技术,6个大核,8个小核,小核没有超线程功能 ,比大核的性能要弱些 也就是说6个大核,每个大核都同时处理2个线程, 每个小核只能同时处理…

Vue缓存字典值减少网络请求次数,解决同样参数并发请求多次

前言 在一些项目里&#xff0c;我们可能有着大量的下拉框&#xff0c;而这些下拉框的数据就来源于我们后端接口返回的字典信息。于是&#xff0c;画风可能是这样的&#xff0c;每次下拉&#xff0c;你都需要请求一次字典接口拿到这些数据&#xff0c;于是每次组件刷新都会重复…

UNIX基础知识:UNIX体系结构、登录、文件和目录、输入和输出、程序和进程、出错处理、用户标识、信号、时间值、系统调用和库函数

引言&#xff1a; 所有的操作系统都为运行在其上的程序提供服务&#xff0c;比如&#xff1a;执行新程序、打开文件、读写文件、分配存储区、获得系统当前时间等等 1. UNIX体系结构 从严格意义上来说&#xff0c;操作系统可被定义为一种软件&#xff0c;它控制计算机硬件资源&…

ClickHouse(十三):Clickhouse MergeTree系列表引擎 - ReplicingMergeTree

进入正文前&#xff0c;感谢宝子们订阅专题、点赞、评论、收藏&#xff01;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; &#x1f3e1;个人主页&#xff1a;含各种IT体系技术&#xff0c;IT贫道_Apache Doris,大数据OLAP体系技术栈,Kerberos安全认证-CSDN博客 &…

Session与Cookie的区别(五)

储存状态的方式 小明的故事说完了&#xff0c;该来把上面这一段变成网络的实际案例了。其实在网络世界中问题也是一样的。 前面已经提到过我们会把状态存在 Cookie 里面&#xff0c;让 Request 之间能够变得有关联。 假设我们今天要来做一个会员系统&#xff0c;那我要怎么知道…

24届近5年南京航空航天大学自动化考研院校分析

今天给大家带来的是南京航空航天大学控制考研分析 满满干货&#xff5e;还不快快点赞收藏 一、南京航空航天大学 学校简介 南京航空航天大学创建于1952年10月&#xff0c;是新中国自己创办的第一批航空高等院校之一。1978年被国务院确定为全国重点大学&#xff1b;1981年经…

Llama 2 云端部署与API调用【AWS SageMaker】

Meta 刚刚发布了 Llama 2 大模型。如果你和我们一样&#xff0c;你一定会迫不及待地想要亲自动手并用它来构建。 推荐&#xff1a;用 NSDT设计器 快速搭建可编程3D场景。 使用任何类型的 LLM 进行构建的第一步是将其托管在某处并通过 API 使用它。 然后你的开发人员可以轻松地将…

Java技术整理(4)—— 多线程并发篇

1、Java 线程实现/创建方式 &#xff08;1&#xff09;继承Thread类 Thread类本质上是实现了Runnable接口的实例&#xff0c;代表一个线程的实例&#xff0c;通过start()启动&#xff0c;自动执行run()方法。 &#xff08;2&#xff09;实现Runnable接口 Runnable是一个没有…

2023 java web面试秘籍

目录 第一章&#xff1a;Java Web基础知识1.介绍3.Java Web基本概念 4.常见面试问题第二章&#xff1a;Java Web核心概念和技术1.介绍3.Servlet和JSP4.Web安全5.常见面试问题 第三章&#xff1a;Java Web高级概念和技术1.介绍3.Spring框架4.安全性5.常见面试问题 第四章&#x…

Clickhouse 数据存储

一、数据分区 数据是以分区目录的形式组织的&#xff0c;每个分区独立分开存储.这种形式&#xff0c;查询数据时&#xff0c;可以有效的跳过无用的数据文件。 1.1 数据分区的规则 分区键的取值&#xff0c;生成分区ID&#xff0c;分区根据ID决定。根据分区键的数据类型不同&am…

springboot房地产管理java购房租房二手房j客户sp源代码mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 springboot房地产管理 系统1权限&#xff1a;管理员 …

Spring Boot多级缓存实现方案

1.背景 缓存&#xff0c;就是让数据更接近使用者&#xff0c;让访问速度加快&#xff0c;从而提升系统性能。工作机制大概是先从缓存中加载数据&#xff0c;如果没有&#xff0c;再从慢速设备(eg:数据库)中加载数据并同步到缓存中。 所谓多级缓存&#xff0c;是指在整个系统架…

2、简单上手+el挂载点+v-xx(v-text、v-html、v-on、v-show、v-if、v-bind、v-for)

官网&#xff1a; vue3&#xff1a;https://cn.vuejs.org/ vue2&#xff1a;https://v2.cn.vuejs.org/v2/guide/ 简单上手&#xff1a; 流程&#xff1a; 导入开发版本的Vue.js <!--开发环境版本&#xff0c;包含了有帮助的命令行警告--> <script src"https…

【IDEA+Spark Streaming 3.4.1+Dstream监控套接字流统计WordCount保存至MySQL8】

【IDEASpark Streaming 3.4.1Dstream监控套接字流统计WordCount保存至MySQL8】 把DStream写入到MySQL数据库中 Spark 3.4.1MySQL 8.0.30sbt 1.9.2 文章目录 【IDEASpark Streaming 3.4.1Dstream监控套接字流统计WordCount保存至MySQL8】前言一、背景说明二、使用步骤1.引入库2…