调用k8s API

调用k8s API,第1张

如上图所示,用户(User和Service Account)在调用API时会经过三个步骤:认证、鉴权和准入控制。

如上图步骤 1 所示,建立 TLS 后, HTTP 请求将进入认证(Authentication)步骤。 集群创建脚本或者集群管理员配置 API 服务器,使之运行一个或多个身份认证组件。

认证步骤输入的是整个 HTTP 请求,但是组件通常只检查头部和客户端证书。

认证模块包含客户端证书、密码、普通令牌、引导令牌和 JSON Web 令牌(JWT,用于服务账户)。

可以指定多个认证模块,在这种情况下,服务器依次尝试每个验证模块,直到其中一个成功。

如果请求认证不通过,服务器将以 HTTP 状态码 401 拒绝该请求。 反之,该用户被认证为特定的 username ,并且该用户名可用于后续步骤以在其决策中使用。 部分验证器还提供用户的组成员身份,其他则不提供。

如上图的步骤 2 所示,将请求验证为来自特定的用户后,请求必须被鉴权。

请求必须包含请求者的用户名、请求的行为以及受该操作影响的对象。 如果现有策略声明用户有权完成请求的操作,那么该请求被鉴权通过。

Kubernetes 支持多种鉴权模块,例如 ABAC 模式、RBAC 模式和 Webhook 模式等。 管理员创建集群时,他们配置应在 API 服务器中使用的鉴权模块。 如果配置了多个鉴权模块,则 Kubernetes 会检查每个模块,任意一个模块鉴权该请求,请求即可继续; 如果所有模块拒绝了该请求,请求将会被拒绝(HTTP 状态码 403)。

准入控制模块是可以修改或拒绝请求的软件模块。 除鉴权模块可用的属性外,准入控制模块还可以访问正在创建或修改的对象的内容。

准入控制器对创建、修改、删除或(通过代理)连接对象的请求进行操作。 准入控制器不会对仅读取对象的请求起作用 。 有多个准入控制器被配置时,服务器将依次调用它们。

这一操作如上图的步骤 3 所示。

与身份认证和鉴权模块不同,如果任何准入控制器模块拒绝某请求,则该请求将立即被拒绝。

除了拒绝对象之外,准入控制器还可以为字段设置复杂的默认值。

请求通过所有准入控制器后,将使用检验例程检查对应的 API 对象,然后将其写入对象存储(如步骤 4 所示)。

所有 Kubernetes 集群都有两类用户:普通用户和由 Kubernetes 管理的服务账号。

Kubernetes 并不包含用来代表普通用户账号的对象 。 普通用户的信息无法通过 API 调用添加到集群中。

但是Kubernetes 仍然认为能够提供由集群的证书机构签名的合法证书的用户是通过身份认证的用户。基于这样的配置,Kubernetes 使用证书中的 'subject' 的通用名称(Common Name)字段(例如,"/CN=bob")来确定用户名。然后,基于角色访问控制(RBAC)子系统会确定用户是否有权针对 某资源执行特定的操作。

与普通用户不同,服务账号是 Kubernetes API 所管理的用户。它们被绑定到特定的名字空间, 或者由 API 服务器自动创建,或者通过 API 调用创建。服务账号与一组以 Secret 保存的凭据相关,这些凭据会被挂载到 Pod 中,从而允许集群内的进程访问 Kubernetes API。

Kubernetes 使用身份认证插件利用客户端证书、持有者令牌(Bearer Token)、身份认证代理(Proxy) 或者 HTTP 基本认证机制来认证 API 请求的身份。HTTP 请求发给 API 服务器时, 插件会将以下属性关联到请求本身:

你可以同时启用多种身份认证方法,并且你通常会至少使用两种方法:

当集群中启用了多个身份认证模块时,第一个成功地对请求完成身份认证的模块会 直接做出评估决定。API 服务器并不保证身份认证模块的运行顺序。

要启动客户端证书身份认证,需要配置apiserver, 传入参数 --client-ca-file=SOMEFILE ,其中ca要与集群的ca一致。集群使用的ca可以通过以下命令查看

如果客户端的证书认证通过,则 subject 中的公共名称(Common Name)就被 作为请求的用户名。 自 Kubernetes 1.4 开始,客户端证书还可以通过证书的 organization 字段标明用户的组成员信息。 要包含用户的多个组成员信息,可以在证书种包含多个 organization 字段。

当 API server的命令行设置了 --token-auth-file=SOMEFILE 选项时,会从文件中读取持有者令牌。目前,令牌会长期有效,并且在 不重启 API server的情况下 无法更改令牌列表。

令牌文件是一个 CSV 文件,包含至少 3 个列:令牌、用户名和用户的 UID。 其余列被视为可选的组名。

服务账号(Service Account)是一种自动被启用的用户认证机制,使用经过签名的 持有者令牌来验证请求。

当服务账号创建后,k8s会自动生成对应的secret,存有可以用来认证的token。

上面的token就可以用来认证。

所有使用token进行认证的请求 ,都要加上 Authorization 的 HTTP请求头,其值格式为 Bearer TOKEN 。

例如:如果持有者令牌为 31ada4fd-adec-460c-809a-9e56ceb75269 ,则其 出现在 HTTP 头部时如下所示:

使用这种认证方式,apiserver将从请求头中获取用户信息,认证过程如图所示。

使用这种认证方式需要对apiserver进行如下配置:

例子:

假设apiserver配置如下

收到的请求头如下

会生成如下的用户信息用于鉴权

Role 总是用来在某个namespace内设置访问权限;在你创建 Role 时,你必须指定该 Role 所属的namespace。

与之相对,ClusterRole 则是一个集群作用域的资源。这两种资源的名字不同(Role 和 ClusterRole)是因为 Kubernetes 对象要么是namespace作用域的,要么是集群作用域的, 不可两者兼具。

ClusterRole 有若干用法。你可以用它来:

如果你希望在namespace内定义角色,应该使用 Role; 如果你希望定义集群范围的角色,应该使用 ClusterRole。

Role例子

ClusterRole例子

角色绑定(Role Binding)是将角色中定义的权限赋予一个或者一组用户。 它包含若干 主体 (用户、组或服务账户)的列表和对这些主体所获得的角色的引用。 RoleBinding 在指定的名字空间中执行授权,而 ClusterRoleBinding 在集群范围执行授权。

一个 RoleBinding 可以引用同一的名字空间中的任何 Role。 或者,一个 RoleBinding 可以引用某 ClusterRole 并将该 ClusterRole 绑定到 RoleBinding 所在的名字空间。 如果你希望将某 ClusterRole 绑定到集群中所有名字空间,你要使用 ClusterRoleBinding。

RoleBinding例子

ClusterRoleBinding例子

以上就是RBAC鉴权的一个概述,总结下就是Role定义了角色有哪些权限,RoleBinding则将角色和用户关联起来。这里的权限指的是对哪些资源有哪些操作的权限,用户则包括了普通用户和服务账号。

更多的关于RBAC的描述可以看下 官网 ,包括了k8s内置的一些默认角色。

这里测试使用的k8s集群是通过kubeadm安装的,这种安装方式会将k8s中的组件如kube-apiserver、kube-scheduler等作为static pod的形式运行。因此可以通过 kubectl get pod 命令来查看对应组件的配置。

从上面的结果可以看到使用的ca是 /etc/kubernetes/pki/ca.crt ,接下来开始生成客户端的证书。

这样就生成了一个用户名为test的客户端证书,接下来用这个证书去调k8s的api。

这代表我们认证通过了,但是鉴权没有通过。接下来给test授权。

先创建一个角色(role.yaml),拥有kube-system namespace下读取pod的权限,使用命令 kubectl apply -f role.yaml 来让他生效。

接下来创建一个RoleBinding,将刚刚创建的角色绑定到test上,并使用命令 kubectl apply -f bind.yaml 来让他生效

生效后再次使用curl调用api,一切正常。

先创建一个kube-system下的服务账号,命令如下

查看有没有生效

可以看到名称为test的sa(service account)已经创建了。接下来查看他对应的secret来获得token。

使用token调用k8s的api

从结果可以确认认证通过了,现在给sa授权,修改bind.yaml,修改后内容如下

使用命令 kubectl apply -f bind.yaml 生效后,再次调用api,这时就不会返回403了。

之前查看apiserver的配置时,看到以下配置,说明apiserver是开启了代理认证的,并且指明了使用的ca。

接下来根据ca生成代理所使用的证书,注意这个ca一般与X509所使用的ca不一致。

并且使用这种方法调用api时,不同的用户只需更改对应的请求头即可,证书不用变更,而如果使用X509的方法,则不同的用户需要使用不同的证书。

调用api

这里由于使用的请求头表明了当前的用户是test,并且之前已经给test授权过了,所以没有返回403。

接下来更改用户名为jojo,再次调用api

返回结果如下

这里 是官方的API参考文档,说明了有哪些api以及对应的使用方式。

API 接口代理

我们一般做vue的项目都会配置接口代理,比如以 /API 径开头的请求都代理到本机的3000端口

那么问题来了这里的配置只有在本机没打包的时候才有效的,打包之后/API 径开头的请求就不会代理了,上传到服务器后

如何解决呢?

办法来了!!!

我的后台服务是node的,也部署在同一个服务器,开启的是3000端口

看如下nginx配置

好了看上面配置后面的注释吧,就这样配置绝逼没问题

apipost的一些基本设置介绍:

一.默认请求超时时间

apipost默认设置的是25000毫秒,就是在25秒钟之内响应没有成功的话就默认失败,我们也可以自定义设置8秒或者10秒.

二.默认请求Method(方法)

请求方法主要有八大方法:get、post、put、head、delete、options、trace、connect。

一般使用最多的是get和post两种方法:

get:方法用来请求访问已被URI识别的资源。指定的资源经过服务器解析后返回响应内容。也就是说,如果请求的资源是文本,那就保持原样返回。

post: 方法用来传输实体的主体。虽然用GET方法也可以传输实体的主体,但一般不用GET方法进行传输,而是用POST方法。虽说POST的功能与GET很相似,但是POST的主要目的并不是获取响应的主题内容。

这里默认的是post方法,也可以改为get、put、connect等方法

三.默认请求方式

1.multipart/form-data:一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 表单的 enctype 等于 multipart/form-data。

2…application/x-www-form-urlencoded:最常见的 POST 提交数据的方式了。浏览器的原生 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。

3.application/json:作为请求头告诉服务端消息主体是序列化的JSON字符串。除低版本的IE,基本都支持。

4.text/xml:它是一种使用 HTTP 作为传输协议,XML 作为编码方式的远程调用规范。

四.自动识别请求参数的Mock变量

一般保持开启状态就可以了。

五.获取接口锁定状态

这里自动获取接口状态,就是是否获取接口的状态,接口状态一般三种:开发中、已完成和需修改。

六.发送后切换至“响应”标签

发送后切换至“响应”标签是:在请求头、成功响应示例及文档页面,发送请求之后,直接返回响应页面。

七.关闭标签时,删除本地缓存

因为接口数据缓存在本地,接口数据量比较大的时候使用apipost的时候就会变得卡顿,然后可以清理缓存就可以清楚使用apipost卡顿感。


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/398838.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-19
下一篇2023-05-19

发表评论

登录后才能评论

评论列表(0条)

    保存