kubernetes API Server 看这篇试试(1)

简介: kubernetes API Server 看这篇试试(1)

kubernetes api-server Overview

tags: api-server

文章目录

kubernetes api-server Overview

1. 简介

2. 特征

3. 组成

4. 原理

5. 命令参数

6. API 路径

7. 管理 Request

7.1 Requests 类型

7.2 Request 生命周期

7.2.1 Authentication(认证)

7.2.2 RBAC/授权

7.2.3 Admission control(准入控制)

7.2.4 Validation(验证)

7.3 特殊 requests

7.4 Watch operations

7.5 乐观并发更新

8. 访问 API Server

8.1 kubectl

8.2 kubectl proxy

8.3 curl

9. 调试 API Server

9.1 Basic Logs

9.2 Audit Logs

9.3 激活附加日志

9.4 调试 kubectl 请求

10. API 版本

11. 替代编码

12. 常见响应代码

13. API Server Internals

14. CRD Control Loop

15. OpenAPI 规范服务

{% youtube %}

https://www.youtube.com/watch?v=_65Md2qar14

{% endyoutube %}

1. 简介

api server 是 Kubernetes 集群的网关。它是 Kubernetes 集群中的所有用户、自动化和组件都可以访问的中心接触点。API Server通过 HTTP 实现 RESTful API,执行所有 API 操作,并负责将 API 对象存储到持久存储后端。

2. 特征

尽管 Kubernetes API Server很复杂,但从管理的角度来看,实际上管理起来相对简单。因为 API Server的所有持久状态都存储在 API Server外部的数据库中,所以服务器本身是无状态的,可以复制以处理请求负载和容错。通常,在高可用集群中,API Server会被复制 3 次。


API Server输出的日志可能非常健谈。它为接收到的每个请求至少输出一行。因此,将某种形式的日志滚动添加到 API Server非常重要,这样它就不会消耗所有可用的磁盘空间。但是,由于 API Server日志对于理解 API Server的操作至关重要,我们强烈建议将日志从 API Server传送到日志聚合服务,以便后续自省和查询以调试用户或组件对 API 的请求。

3. 组成

操作 Kubernetes API Server涉及三个核心功能:


API management

服务器公开和管理 API 的过程


Request processing

处理来自客户端的单个 API 请求的最大功能集


Internal control loops

负责 API Server成功运行所需的后台操作的内部人员。

4. 原理

kube-apiserver 提供了 Kubernetes 的 REST API,实现了认证、授权、准入控制等安全校验功能,同时也负责集群状态的存储操作(通过 etcd)。

1035234-20181020215539574-213176954.png

/apis/batch/v2alpha1/jobs 为例,GET 请求的处理过程如下图所示:

1035234-20181020215539574-213176954.png

POST 请求的处理过程为:

1035234-20181020215539574-213176954.png

(图片来自 OpenShift Blog

5. 命令参数

查看资源与版本

$ kubectl api-versions
admissionregistration.k8s.io/v1beta1
apiextensions.k8s.io/v1beta1
apiregistration.k8s.io/v1
apiregistration.k8s.io/v1beta1
apps/v1
apps/v1beta1
apps/v1beta2
authentication.k8s.io/v1
authentication.k8s.io/v1beta1
authorization.k8s.io/v1
authorization.k8s.io/v1beta1
autoscaling/v1
autoscaling/v2beta1
batch/v1
batch/v1beta1
certificates.k8s.io/v1beta1
events.k8s.io/v1beta1
extensions/v1beta1
metrics.k8s.io/v1beta1
networking.k8s.io/v1
policy/v1beta1
rbac.authorization.k8s.io/v1
rbac.authorization.k8s.io/v1beta1
scheduling.k8s.io/v1beta1
storage.k8s.io/v1
storage.k8s.io/v1beta1
v1
$ kubectl api-resources --api-group=storage.k8s.io
NAME                SHORTNAMES   APIGROUP         NAMESPACED   KIND
storageclasses      sc           storage.k8s.io   false        StorageClass
volumeattachments                storage.k8s.io   false        VolumeAttachment

尽管 API 的主要用途是为单个客户端请求提供服务,但在处理 API 请求之前,客户端必须知道如何发出 API 请求。最终,API Server是一个 HTTP 服务器——因此,每个 API 请求都是一个 HTTP 请求。但是必须描述这些 HTTP 请求的特征,以便客户端和服务器知道如何通信。出于探索的目的,让 API Server实际启动并运行非常好,这样您就可以对它进行探索。您可以使用您有权访问的现有 Kubernetes 集群,也可以将minikube 工具用于本地 Kubernetes 集群。为了便于使用该curl工具来探索 API Server,请kubectl在proxy使用以下命令在 localhost:8001 上公开未经身份验证的 API Server的模式:

kubectl proxy

6. API 路径

对 API Server的每个请求都遵循 RESTful API 模式,其中请求由请求的 HTTP 路径定义。所有 Kubernetes 请求都以前缀/api/(核心 API)或/apis/(按 API 组分组的 API)开头。这两组不同的路径主要是历史性的。API 组最初不存在于 Kubernetes API 中,因此原始或“核心”对象,如 Pod 和Services,在没有 API 组的情况下维护在'/api/'前缀下。后续 API 一般都添加在 API 组下,因此它们遵循’/apis/<api-group>/'路径。例如,该Job对象是batch API 组的一部分,因此可以在/apis/batch/v1/...下找到。


资源路径的另一个问题是资源是否已命名空间。Namespaces在 Kubernetes 中为对象添加了一层分组,命名空间资源只能在命名空间内创建,并且该命名空间的名称包含在命名空间资源的 HTTP 路径中。当然,有些资源并不存在于命名空间中(最明显的例子是NamespaceAPI 对象本身),在这种情况下,它们的 HTTP 路径中没有命名空间组件。

以下是命名空间资源类型的两种不同路径的组成部分:


/api/v1/namespaces/<namespace-name>/<resource-type-name>/<resource-name>


/apis/<api-group>/<api-version>/namespaces/<namespace-name>/<resource-type-name>/<resource-name>


以下是非命名空间资源类型的两种不同路径的组成部分:


/api/v1/<resource-type-name>/<resource-name>


/apis/<api-group>/<api-version>/<resource-type-name>/<resource-name>

7. 管理 Request

Kubernetes 中 API Server的主要用途是接收和处理 HTTP 请求形式的 API 调用。这些请求要么来自 Kubernetes 系统中的其他组件,要么是最终用户请求。无论哪种情况,它们都由 Kubernetes API Server以相同的方式处理。

7.1 Requests 类型

GET

最简单的请求是GET对特定资源的请求。这些请求检索与特定资源关联的数据。例如,对路径/api/v1/namespaces/default/pods/foo 的 HTTP请求检索名为foo的 Pod 的数据。


LIST

一个稍微复杂但仍然相当简单的请求是 acollection GET或LIST。这些是列出许多不同请求的请求。例如,对路径/api/v1/namespaces/default/podsGET的 HTTP请求检索命名空间中所有 Pod 的集合。requests 还可以选择指定标签查询,在这种情况下,仅返回与该标签查询匹配的资源。


POST

要创建资源,需要使用POST请求。请求的主体是应该创建的新资源。在POST请求的情况下,路径是资源类型(例如,/api/v1/namespaces/default/pods)。要更新现有资源,需要PUT向特定资源路径(例如/api/v1/namespaces/default/pods/foo)发出请求。


DELETE

当需要删除请求时,将使用DELETE对资源路径(例如/api/v1/namespaces/default/pods/foo)的 HTTP 请求。请务必注意,此更改是永久性的——在发出 HTTP 请求后,资源将被删除。


所有这些请求的内容类型通常是基于文本的 JSON ( application/json),但最近发布的 Kubernetes 也支持 Protocol Buffers 二进制编码。一般来说,JSON 更适合客户端和服务器之间网络上的人类可读和可调试流量,但解析起来更加冗长和昂贵。常用工具 curl,可以提高 API 请求的性能和吞吐量。


除了这些标准请求之外,许多请求还使用 WebSocket 协议来启用客户端和服务器之间的流式会话。此类协议的示例类似attach命令。

7.2 Request 生命周期

为了更好地理解 API Server对每个不同的请求做了什么,我们将拆开并描述对 API Server的单个请求的处理。

1035234-20181020215539574-213176954.png

7.2.1 Authentication(认证)

请求处理的第一阶段是身份验证,它建立与请求关联的身份。API Server支持多种不同的身份建立模式,包括客户端证书、承载令牌和 HTTP 基本身份验证。一般来说,应该使用客户端证书或不记名令牌进行身份验证;不鼓励使用 HTTP 基本身份验证。


除了这些建立身份的本地方法之外,身份验证是可插入的,并且有几个使用远程身份提供者的插件实现。其中包括对 OpenID Connect (OIDC) 协议以及 Azure Active Directory 的支持。这些身份验证插件被编译到 API Server和客户端库中。这意味着您可能需要确保命令行工具和 API Server的版本大致相同或支持相同的身份验证方法。


API Server还支持基于远程 webhook 的身份验证配置,其中身份验证决策通过不记名令牌转发委托给外部服务器。外部服务器验证来自最终用户的不记名令牌,并将身份验证信息返回给 API Server

7.2.2 RBAC/授权

在 API Server确定请求的身份后,它会继续对其进行授权。对 Kubernetes 的每个请求都遵循传统的 RBAC 模型。要访问请求,身份必须具有与请求关联的适当角色。Kubernetes RBAC 是一个丰富而复杂的话题,因此,我们用一整章的时间来详细介绍RBAC它的运作方式。就本 API Server摘要而言,在处理请求时,API Server会确定与请求关联的身份是否可以访问请求中的动词和 HTTP 路径的组合。如果请求的身份具有适当的角色,则允许继续。否则,返回 HTTP 403 响应。

7.2.3 Admission control(准入控制)

在请求经过身份验证和授权后,它会进入准入控制。身份验证和 RBAC 确定是否允许发生请求,这基于请求的 HTTP 属性(标头、方法和路径)。准入控制确定请求是否格式正确,并可能在处理请求之前对其进行修改。准入控制定义了一个可插拔的接口:


apply(request): (transformedRequest, error)

如果任何准入控制器发现错误,则拒绝该请求。如果请求被接受,则使用转换后的请求而不是初始请求。准入控制器被串行调用,每个接收前一个的输出。


因为准入控制是一种通用的、可插入的机制,所以它被用于 API Server中的各种不同功能。例如,它用于向对象添加默认值。它还可以用于强制执行策略(例如,要求所有对象都具有特定标签)。此外,它还可以用来做一些事情,比如向每个 Pod 注入一个额外的容器。服务网格 Istio 使用这种方法透明地注入其 sidecar 容器。


准入控制器非常通用,可以通过基于 webhook 的准入控制动态添加到 API Server。

7.2.4 Validation(验证)

请求验证发生在准入控制之后,尽管它也可以作为准入控制的一部分来实现,尤其是对于基于 Webhook 的外部验证。此外,仅对单个对象执行验证。如果它需要更广泛的集群状态知识,则必须将其实现为准入控制器。


请求验证确保请求中包含的特定资源有效。例如,它确保Service对象的名称符合 DNS 名称的规则,因为最终 a 的名称Service将被编程到 KubernetesService发现 DNS 服务器中。通常,验证是作为按资源类型定义的自定义代码来实现的。

7.3 特殊 requests

除了标准的 RESTful 请求之外,API Server还有许多专门的请求模式,为客户端提供扩展功能:

/proxy, /exec, /attach, /logs

第一类重要的操作是与 API Server的开放的、长时间运行的连接。这些请求提供流数据而不是立即响应。


该logs操作是我们描述的第一个流式请求,因为它最容易理解。事实上,默认情况下,logs根本不是流式传输请求。/logs客户端通过附加到特定 Pod 的路径末尾(例如 /api/v1/namespaces/default/pods/some-pod/logs)然后指定容器名称来请求获取 Pod 的日志作为 HTTP 查询参数和 HTTP GET请求。给定一个默认请求,API Server会以纯文本形式返回截至当前时间的所有日志,然后关闭 HTTP 请求。但是,如果客户端请求跟踪日志(通过指定follow查询参数),HTTP 响应由 API Server保持打开状态,并且在通过 API Server从 kubelet 接收新日志时将新日志写入 HTTP 响应。这种连接如图 4-1所示。。

1035234-20181020215539574-213176954.png

logs是最容易理解的流式传输请求,因为它只是让请求保持打开状态并流入更多数据。其余操作利用 WebSocket 协议进行双向流数据。它们实际上还对这些流中的数据进行了多路复用,以通过 HTTP 启用任意数量的双向流。如果这一切听起来有点复杂,它确实是,但它也是 API Server表面区域的一个有价值的部分。


API Server实际上支持两种不同的流协议。它支持 SPDY 协议,以及 HTTP2/WebSocket。SPDY 正在被 HTTP2/WebSocket 取代,因此我们将注意力集中在 WebSocket 协议上。


完整的 WebSocket 协议超出了本书的范围,但它在许多其他地方都有记录。为了理解 API Server,您可以简单地将 WebSocket 视为一种将 HTTP 转换为双向字节流协议的协议。


然而,在这些流之上,Kubernetes API Server实际上引入了一个额外的多路复用流协议。这样做的原因是,对于许多用例,API Server能够为多个独立的字节流提供服务是非常有用的。例如,考虑在容器中执行命令。在这种情况下,实际上需要维护三个流(stdin、stderr和stdout)。


此流的基本协议如下:为每个流分配一个从 0 到 255 的数字。该流编号用于输入和输出,它在概念上模拟单个双向字节流。


对于通过 WebSocket 协议发送的每一帧,第一个字节是流号(例如,0),帧的其余部分是在该流上传输的数据(图 4-2)。

1035234-20181020215539574-213176954.png

图 4-2。Kubernetes WebSocket 多通道框架的示例


使用此协议和 WebSockets,API Server可以在单个 WebSocket 会话中同时多路复用 256 字节流。


此基本协议用于会话exec,attach具有以下通道:


0

stdin用于写入进程的流。不会从此流中读取数据。


1

用于从进程stdout读取的输出流。stdout不应将数据写入此流。


2

用于从进程stderr读取的输出流。stderr不应将数据写入此流。


endpoint用于在/proxy客户端与集群内运行的容器和服务之间转发网络流量,而这些endpoint不会暴露在外部。为了流式传输这些 TCP 会话,协议稍微复杂一些。除了多路复用各种流之外,流的前两个字节(在流号之后,所以实际上是 WebSockets 帧中的第二和第三个字节)是正在转发的端口号,因此单个 WebSockets 帧用于/proxy查找如图4-3 所示。

1035234-20181020215539574-213176954.png

7.4 Watch operations

除了流式数据,API Server还支持 watch API。watch监视更改的路径。因此,不是在某个时间间隔轮询可能的更新,这会引入额外的负载(由于快速轮询)或额外的延迟(由于慢速轮询),使用watch使用户能够通过单个连接获得低延迟更新。当用户通过向?watch=true某个 API Server请求添加查询参数来建立到 API Server的监视连接时,API Server切换到监视模式,并保持客户端和服务器之间的连接打开。同样,API Server返回的数据不再只是 API 对象——它是一个Watch包含更改类型(创建、更新、删除)和 API 对象本身的对象。通过这种方式,客户端可以观察和观察对该对象或对象集的所有更改。

7.5 乐观并发更新

API Server支持的另一个高级操作是能够乐观地执行 Kubernetes API 的并发更新。乐观并发背后的想法是能够在不使用锁的情况下执行大多数操作(悲观并发),并检测何时发生并发写入,拒绝两个并发写入中的后者。被拒绝的写入不会重试(由客户端检测冲突并自己重试写入)。


要理解为什么需要这种乐观并发和冲突检测,了解读/更新/写竞争条件的结构很重要。许多 API Server客户端的操作涉及三个操作:


从 API Server读取一些数据。

更新内存中的数据。

将其写回 API Server。

现在想象一下当这两种读/更新/写模式同时发生时会发生什么。


服务器 A 读取对象 O。

服务器 B 读取对象 O。

服务器 A 更新客户端内存中的对象 O。

服务器 B 更新客户端内存中的对象 O。

服务器 A 写入对象 O。

服务器 B 写入对象 O。

最后,服务器 A 所做的更改将丢失,因为它们被服务器 B 的更新覆盖。


解决这场比赛有两种选择。第一个是悲观锁(pessimistic lock),它可以防止在服务器 A 对对象进行操作时发生其他读取。这样做的问题是它会序列化所有操作,这会导致性能和吞吐量问题。


Kubernetes API Server实现的另一个选项是乐观并发(optimistic concurrency),它假设一切都会顺利进行,并且仅在尝试写入冲突时才检测到问题。为此,对象的每个实例都返回其数据和资源版本。此资源版本指示对象的当前迭代。发生写入时,如果设置了对象的资源版本,则只有当前版本与对象的版本匹配,才能写入成功。如果没有,则返回 HTTP 错误 409(冲突)并且客户端发霉重试。要了解这如何解决刚刚描述的读/更新/写竞争,让我们再次看一下操作:


服务器 A 读取版本为 v1 的对象 O。

服务器 B 读取版本为 v1 的对象 O。

服务器 A 在客户端的内存中更新版本为 v1 的对象 O。

服务器 B 更新客户端内存中版本 v1 的对象 O。

服务器 A 以版本 v1 写入对象 O;这是成功的。

服务器B在v1版本写入对象O,但对象在v2;返回 409 冲突。


相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
9月前
|
人工智能 API 开发工具
GitHub官方开源MCP服务!GitHub MCP Server:无缝集成GitHub API,实现Git流程完全自动化
GitHub MCP Server是基于Model Context Protocol的服务器工具,提供与GitHub API的无缝集成,支持自动化处理问题、Pull Request和仓库管理等功能。
1959 2
GitHub官方开源MCP服务!GitHub MCP Server:无缝集成GitHub API,实现Git流程完全自动化
|
10月前
|
Kubernetes API 网络安全
当node节点kubectl 命令无法连接到 Kubernetes API 服务器
当Node节点上的 `kubectl`无法连接到Kubernetes API服务器时,可以通过以上步骤逐步排查和解决问题。首先确保网络连接正常,验证 `kubeconfig`文件配置正确,检查API服务器和Node节点的状态,最后排除防火墙或网络策略的干扰,并通过重启服务恢复正常连接。通过这些措施,可以有效解决与Kubernetes API服务器通信的常见问题,从而保障集群的正常运行。
854 17
|
10月前
|
人工智能 JavaScript 测试技术
构建智能 API 开发环境:在 Cursor 中连接 Apifox MCP Server
本文介绍了如何将Apifox MCP Server与Cursor结合,通过AI直接获取和理解API文档,大幅提升开发效率。首先需配置Apifox的Access Token和项目ID,并在Cursor中设置MCP连接。实际应用场景包括快速生成模型代码、同步更新接口文档与代码、生成CRUD操作、搜索API文档及自动生成测试用例。此外,还提供了管理多项目、安全性实践和优化AI响应质量的技巧。这种组合可显著减少从API规范到代码实现的时间,降低错误率并加速迭代过程,为开发者带来更高效的体验。
|
Kubernetes 安全 Cloud Native
云上攻防-云原生篇&K8s安全-Kubelet未授权访问、API Server未授权访问
本文介绍了云原生环境下Kubernetes集群的安全问题及攻击方法。首先概述了云环境下的新型攻击路径,如通过虚拟机攻击云管理平台、容器逃逸控制宿主机等。接着详细解释了Kubernetes集群架构,并列举了常见组件的默认端口及其安全隐患。文章通过具体案例演示了API Server 8080和6443端口未授权访问的攻击过程,以及Kubelet 10250端口未授权访问的利用方法,展示了如何通过这些漏洞实现权限提升和横向渗透。
1532 0
云上攻防-云原生篇&K8s安全-Kubelet未授权访问、API Server未授权访问
|
API 开发者
【API管理 APIM】APIM集成内部VNet后,自我访问出现(Unable to connect to the remote server)问题,而Remote Server正是APIM它自己
【API管理 APIM】APIM集成内部VNet后,自我访问出现(Unable to connect to the remote server)问题,而Remote Server正是APIM它自己
601 5
|
Kubernetes 负载均衡 API
在K8S中,api-service 和 kube-schedule 高可用原理是什么?
在K8S中,api-service 和 kube-schedule 高可用原理是什么?
|
存储 Kubernetes API
深度剖析Kubernetes API Server三部曲 - part 1
欢迎来到深入学习Kubernetes API Server的系列文章,在本系列文章中我们将深入的探究Kubernetes API Server的相关实现。如果你对Kubernetes 的内部实现机制比较感兴趣或者正在进行Kubernetes 项目的相关开发工作,那么本系列文章能够为你提供一些帮助。
1593 0
|
存储 Kubernetes API
深度剖析Kubernetes API Server三部曲 - part 2
欢迎来到深入学习Kubernetes API Server的系列文章的第二部分。在上一部分中我们对APIserver总体,相关术语及request请求流进行探讨说明。在本部分文章中,我们主要聚焦于探究如何对Kubernetes 对象的状态以一种可靠,持久的方式进行管理。
1538 0