Kubernetes客户端认证—— 基于ServiceAccount的JWTToken认证
1、概述
在 Kubernetes 官方手册中给出了 “用户” 的概念,Kubernetes 集群中存在的用户包括 “普通用户” 与 “ServiceAccount”, 但是 Kubernetes 没有普通用户的管理方式,通常只是将使用集群根证书签署的有效证书的用户都被视为合法用户。
那么对于使得 Kubernetes 集群有一个真正的用户系统,就可以根据上面给出的概念将 Kubernetes 用户分为“内部用户”与“外部用户”。如何理解内部与外部用户呢?实际上就是由 Kubernetes 管理的用户,即在 kubernetes 定义用户的数据模型这种为 “内部用户” ,正如 ServiceAccount;反之,非 Kubernetes 托管的用户则为 “外部用户”, 这种概念也更好的对 kubernetes 用户的阐述。
对于外部用户来说,实际上 Kubernetes 给出了多种用户概念,例如:
- 拥有 kubernetes 集群证书的用户
- 拥有 Kubernetes 集群 token 的用户(--token-auth-file指定的静态 token)
- 用户来自外部用户系统,例如 OpenID,LDAP,QQ connect, google identity platform 等
本文不过多介绍Kubernetes外部用户认证,主要讲解Kubernetes内部用户ServiceAccount的认证方式,即大部分Pod默认的认证方式(Pod和APIServer之间如果没有配置基于CA根证书签名的双向数字证书方式进行认证的话,则默认通过Token方式进行认证)。
注意:在之前博文中讲解过拥有kubernetes集群证书的用户的认证方式,详情见《Kubernetes客户端认证——基于CA证书的双向认证方式》。
2、基于ServiceAccount的JWTToken认证
2.1 ServiceAccount定义
ServiceAccount(服务帐户)与Namespace绑定,关联一套凭证,Pod创建时挂载Token,从而允许与API Server之间调用。ServiceAccount同样是Kubernetes中的资源,与Pod、ConfigMap类似,且作用于独立的命名空间,也就是ServiceAccount是属于命名空间级别的,创建命名空间时会自动创建一个名为default的ServiceAccount。
使用下面命令可以查看ServiceAccount。
1 2 3 |
|
同时Kubernetes还会为ServiceAccount自动创建一个Token,使用下面命令可以查看到。
1 2 3 4 5 6 7 8 9 |
|
在Pod的定义文件中,可以用指定帐户名称的方式将一个ServiceAccount赋值给一个Pod,如果不指定就会使用默认的ServiceAccount。当API Server接收到一个带有认证Token的请求时,API Server会用这个Token来验证发送请求的客户端所关联的ServiceAccount是否允许执行请求的操作。
注意:
- 1.21以前版本的集群中,Pod中获取Token的形式是通过挂载ServiceAccount的Secret来获取Token,这种方式获得的Token是永久的。该方式在1.21及以上的版本中不再推荐使用,并且根据社区版本迭代策略,在1.25及以上版本的集群中,ServiceAccount将不会自动创建对应的Secret。
1.21及以上版本的集群中,直接使用TokenRequest API获得Token,并使用投射卷(Projected Volume)挂载到Pod中。使用这种方法获得的Token具有固定的生命周期,并且当挂载的Pod被删除时这些Token将自动失效。详情请参见Token安全性提升说明。
- 如果您在业务中需要一个永不过期的Token,您也可以选择手动管理ServiceAccount的Secret。尽管存在手动创建永久ServiceAccount Token的机制,但还是推荐使用TokenRequest的方式使用短期的Token,以提高安全性。
2.2 创建ServiceAccount
使用如下命令就可以创建ServiceAccount:
1 2 3 4 5 6 |
|
可以看到已经创建了与ServiceAccount相关联的Token。
1 2 3 4 5 6 7 8 9 |
|
查看Secret的内容,可以发现ca.crt、namespace和token三个数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
注意:只有在1.23及之前版本的集群中,ServiceAccount才会自动创建Secret。
2.3 在Pod中使用ServiceAccount
Pod中使用ServiceAccount非常方便,只需要指定ServiceAccount的名称即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
创建并查看这个Pod,可以看到Pod挂载了sa-example-token-c7bqx,即Pod使用这个Token来做认证。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
注意: 通过这个方式,您可以了解Pod的认证机制,但在实际使用中,出于安全性考虑,1.21及以上版本的集群中Pod中默认挂载的Token是临时的。
进入Pod内部,还可以看到对应的文件,如下所示:
1 2 3 4 5 |
|
如上,在容器应用中,就可以使用ca.crt和Token来访问APIServer。
2.4 基于token访问APIServer
下面来验证一下认证是否能生效。在Kubernetes集群中,默认为API Server创建了一个名为kubernetes的Service,通过这个Service可以访问API Server。
1 2 3 |
|
进入Pod,使用curl命令直接访问会报以下错误:
1 2 3 4 5 6 7 8 9 10 |
|
注意:报错原因是因为curl客户端和Kube-Apiserver服务端建立的是SSL/TLS单向连接,curl和Kube-Apiserver建立连接过程中,Kube-Apiserver会将服务端证书返回给curl客户端,而curl客户端没有指定ca.crt,因此无法验证服务器的合法性,因此无法建立与它的安全连接。
使用ca.crt和Token做认证,先将ca.crt放到CURL_CA_BUNDLE这个环境变量中,curl命令使用CURL_CA_BUNDLE指定证书;再将Token的内容放到TOKEN中,然后带上TOKEN访问API Server。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
可以看到,已经能够通过认证了,但是API Server返回的是cannot get path \"/\"",表示没有权限访问,这说明还需要得到授权后才能访问,接下来为default命名空间下的ServiceAccount sa-example关联Role使其能够获取Pod资源。
首先创建Role,Role的定义非常简单,指定namespace,然后就是rules规则。如下面示例中的规则就是允许对default命名空间下的Pod进行GET、LIST操作。
1 2 3 4 5 6 7 8 9 |
|
有了Role之后,就可以将Role与具体的用户绑定起来,实现这个的就是RoleBinding了。如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
在Kubernetes集群apply Role和Rolebind文件,现在再进入到sa-example这个Pod,使用curl命令通过API Server访问资源来验证权限是否生效。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
返回结果正常,说明sa-example现在有LIST Pod的权限了。
注意 1:本示例中,sa-example Pod通过HTTPS单向认证方式与Kube-Apiserver服务端建立连接后,进入Kube-Apiserver认证过滤器链(默认支持CA认证和Token认证两种身份验证方式,因为客户端证书为空,所以不会执行CA认证过滤器逻辑),如果请求中包含Authorization头部,并且其值是以Bearer开头的Token,则进入Token认证过滤器逻辑,对JWT Token进行验证,如果Token未过期且签名有效,则认证成功,并从中获取Pod所使用的ServiceAccount的用户信息。认证成功后,进入Kube-Apiserver授权阶段,如果请求被授权,则继续处理;否则,Kube-Apiserver会返回HTTP 403未授权错误。
注意 2:本示例中,sa-example Pod和 API Server 之间建立了一个加密的 SSL/TLS 连接(HTTPS单向认证方式),所有的通信都会经过加密传输,包括客户端请求中的 token 信息和 Kube-Apiserver 的响应。这样可以确保通信过程中的安全性,同时防止任何未经授权的访问和攻击。HTTPS单向认证步骤如下:
- 客户端发起建立HTTPS连接请求,将SSL协议版本的信息发送给服务端。
- 服务端将自己的公钥证书(server.crt)发送给客户端。
- 客户端通过自己的根证书(ca.crt)验证服务端的公钥证书(server.crt)的合法性,取出服务端公钥。(如果验证公钥证书失败,则中断HTTPS连接)
- 客户端生成密钥R,用服务端公钥去加密它形成密文,发送给服务端。
- 服务端用自己的私钥(server.key)去解密这个密文,得到客户端的密钥R。
- 服务端和客户端使用密钥R进行通信。
注意 3: Kube-Apiserver tls客户端认证配置为RequestClientCert(客户端请求可以不发送客户端证书),即可以不使用SSL/TLS加密方式或仅使用SSL/TLS单向认证方式或使SSL/TLS双向认证方式与Kube-Apiserver服务端建立连接,所以不使用SSL/TLS加密方式方式认证与Kube-Apiserver服务端建立连接也是可以的。
注意 4:Kube-Apiserver服务端监听的是tls端口,如果使用http方式访问是不行的(对HTTPS服务发起HTTP请求会报请求方式错误,Client sent an HTTP request to an HTTPS server.)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/ # curl -k https://kubernetes/api/v1/namespaces/default/pods
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "pods is forbidden: User \"system:anonymous\" cannot list resource \"pods\" in API group \"\" in the namespace \"default\"",
"reason": "Forbidden",
"details": {
"kind": "pods"
},
"code": 403
/ # TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
/ # curl -k -H "Authorization: Bearer $TOKEN" https://kubernetes/api/v1/namespaces/default/pods
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/namespaces/default/pods",
"resourceVersion": "10377013"
},
"items": [
{
"metadata": {
"name": "sa-example",
......
1
2
3
/ # TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
/ # curl -k -H "Authorization: Bearer $TOKEN" http://kubernetes/api/v1/namespaces/default/pods
curl: (52) Empty reply from server
3、总结
在 Kubernetes 中,Pod客户端和Kube-Apiserver服务端进行交互时,使用 token 进行身份验证的请求会使用 SSL/TLS 加密进行保护。具体来说,使用 token 进行身份验证的请求流程如下:
-
客户端使用提前生成好的 token 发起请求,将 token 附加在请求的 Authorization 头部。
-
客户端会首先与 API Server 建立一个加密的 SSL/TLS 连接,以保护通信的安全性。
-
Kube-Apiserver 收到请求后,会对 token 进行验证,如果验证通过,进入Kube-Apiserver授权阶段,如果请求被授权,则继续处理;否则,Kube-Apiserver会返回HTTP 403未授权错误。
在这个过程中,客户端和 API Server 之间建立了一个加密的 SSL/TLS 连接,所有的通信都会经过加密传输,包括客户端请求中的 token 信息和 API Server 的响应。这样可以确保通信过程中的安全性,同时防止任何未经授权的访问和攻击。
需要注意的是,虽然使用 token 进行身份验证的请求会经过 SSL/TLS 加密进行保护,但是 SSL/TLS 加密并不能完全防止所有的安全威胁,因此在实际使用中,仍然需要采取其他安全措施来保障 Kubernetes 环境的安全性。
相关文章:

Kubernetes客户端认证—— 基于ServiceAccount的JWTToken认证
1、概述 在 Kubernetes 官方手册中给出了 “用户” 的概念,Kubernetes 集群中存在的用户包括 “普通用户” 与 “ServiceAccount”, 但是 Kubernetes 没有普通用户的管理方式,通常只是将使用集群根证书签署的有效证书的用户都被视为合法用户。…...

45.ubuntu Linux系统安装教程
目录 一、安装Vmware 二、Linux系统的安装 今天开始了新的学习,Linux,下面是今天学习的内容。 一、安装Vmware 这里是在 Vmware 虚拟机中安装 linux 系统,所以需要先安装 vmware 软件,然 后再安装 Linux 系统。 所需安装文件:…...

Jmeter函数助手(一)随机字符串(RandomString)
一、目标 实现一个请求单次调用,请求体里多个集合中的相同参数(zxqs)值随机从序列{01、02、03、03、04、05、06、07、08}中取 若使用CSV数据文件、用户参数等参数化手段,单次执行请求,请求体里多个集合中的相同参数&a…...

SpringCloud之微服务API网关Gateway介绍
文章目录 1 微服务API网关Gateway1.1 网关简介1.2 Spring Cloud Gateway介绍1.3 Gateway特性1.4 Gateway核心概念1.4.1 路由1.4.1.1 定义1.4.1.2 动态路由 1.4.2 断言1.4.2.1 默认断言1.4.2.2 自定义Predicate 1.4.3 过滤器1.4.3.1 默认过滤器1.4.3.2 自定义Filter(…...

机器学习入门之 pandas
pandas 有三种数据结构 一种是 Series 一种是 Dataframe import pandas as pd import numpy as np score np.random.randint(0,100,[10,5])score[0,0] 100Datascore pd.DataFrame(score)subject ["语文","数学","英语","物理&quo…...

Django之JWT库与SimpleJWT库的使用
Django之JWT库与SimpleJWT库的使用 JWTJWT概述头部(header)载荷(payload)签名(signature) Django使用JWT说明jwt库的使用安装依赖库配置settings.py文件配置urls.py文件创建视图配置权限 SimpleJWT库的使用安装SimpleJWT库配置Django项目配置路由创建用户接口测试身份认证自定义…...

Jmeter远程服务模式运行时引用csv文件的路径配置
问题 在使用jmeter过程中,本机的内存等配置不足,启动较多的线程时,可以采用分布式运行。 在分布式运行的时候,jmeter会自动将脚本从master主机发送到remote主机上,所以不需要考虑将脚本拷贝到remote主机。但是jmeter…...
《OWASP代码审计》学习——注入漏洞审计
一、注入的概念 注入攻击允许恶意用户向应用程序添加或注入内容和命令,以修改其行为。这些类型的攻击是常见且广泛的,黑客很容易测试网站是否易受攻击,攻击者也很容易利用这些攻击。如今,它们在尚未更新的遗留应用程序中非常常见…...

Linux虚拟机中安装MySQL5.6.34
目录 第一章、xshell工具和xftp的使用1.1)xshell下载与安装1.2)xshell连接1.3)xftp下载安装和连接 第二章、安装MySQL5.6.34(不同版本安装方式不同)2.1)关闭防火墙,传输MySQL压缩包到Linux虚拟机2.2&#x…...

Django的FBV和CBV
Django的FBV和CBV 基于django开发项目时,对于视图可以使用 FBV 和 CBV 两种模式编写。 FBV,function base views,其实就是编写函数来处理业务请求。 from django.contrib import admin from django.urls import path from app01 import view…...

[每周一更]-(第57期):用Docker、Docker-compose部署一个完整的前后端go+vue分离项目
文章目录 1.参考项目2.技能点3.GO的Dockerfile配置后端的结构如图Dockerfile先手动docker调试服务是否可以启动报错 4.Vue的Dockerfile配置前端的结构如图nginx_docker.confDockerfile构建 5.docker-compose 整合前后端docker-compose.yml错误记录(1)ip端…...

springboot-mybatis的增删改查
目录 一、准备工作 二、常用配置 三、尝试 四、增删改查 1、增加 2、删除 3、修改 4、查询 五、XML的映射方法 一、准备工作 实施前的准备工作: 准备数据库表 创建一个新的springboot工程,选择引入对应的起步依赖(mybatis、mysql驱动…...

HTML5(H5)的前生今世
目录 概述HTML5与其他HTML的区别CSS3与其他CSS版本的区别总结 概述 HTML5是一种用于构建和呈现网页的最新标准。它是HTML(超文本标记语言)的第五个版本,于2014年由万维网联盟(W3C)正式推出。HTML5的前身可以追溯到互联…...

抽象工厂模式(Abstract Factory)
抽象工厂模式提供一个创建一组相关或相互依赖的对象的接口,而无须指定它们具体的类,每个子类可以生产一系列相关的产品。 The Abstract Factory Pattern is to provide an interface for creating families of related or dependent objects without s…...
Java 实现下载文件工具类
package com.liunian.utils;import lombok.SneakyThrows;import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream;/*** ClassName DownloadFileUtils* Author liuyan 下载文件工具类…...
C# 12 预览版的新功能
作者:Kathleen Dollard 排版:Alan Wang Visual Studio 17.7 Preview 3 和 .NET 8 Preview 6 的发布推进了 C# 12的发展。此预览版包含的功能为将来的性能增强奠定了基础。现在,您能够在库中更方便的使用内联函数。此预览版首次推出了一项实验…...

34.利用matlab解 多变量多目标规划问题(matlab程序)
1.简述 学习目标:适合解 多变量多目标规划问题,例如 收益最大,风险最小 主要目标法,线性加权法,权值我们可以自己设定。 收益函数是 70*x(1)66*x(2) ; 风险函数是 0.02*x(1)^20.01*x(2)^20.04*(x…...
暑假刷题第18天--7/30
165. 小猫爬山 - AcWing题库(dfs) #include<iostream> #include<string> #include<bitset> #include<cstring> #include<algorithm> using namespace std; const int N18; bool vis[N]; int a[N],n,ans,sum[N],k; bool cmp(int x,int y){retur…...

通向架构师的道路之Apache整合Tomcat
一、先从J2EE工程的通用架构说起 这是一个通用的Web即B/S工程的架构,它由: Web Server App Server DB Server 三大部分组成,其中: Web Server 置于企业防火墙外,这个防火墙,大家可以认为是…...

如何消除“信息孤岛”对业务增长的威胁?
根据CMSWire的数据,员工平均每天要花36%的时间来查找和整合信息。但44%的情况下,他们找不到信息。这种时间和精力的浪费就是信息孤岛造成的。 什么是信息孤岛? 当部门存储数据并限制其他人访问数据时,就会出现信息孤岛ÿ…...

利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...

Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...