kubernetes API Server 看这篇试试(1)

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 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 冲突。


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2月前
|
Kubernetes 安全 Cloud Native
云上攻防-云原生篇&K8s安全-Kubelet未授权访问、API Server未授权访问
本文介绍了云原生环境下Kubernetes集群的安全问题及攻击方法。首先概述了云环境下的新型攻击路径,如通过虚拟机攻击云管理平台、容器逃逸控制宿主机等。接着详细解释了Kubernetes集群架构,并列举了常见组件的默认端口及其安全隐患。文章通过具体案例演示了API Server 8080和6443端口未授权访问的攻击过程,以及Kubelet 10250端口未授权访问的利用方法,展示了如何通过这些漏洞实现权限提升和横向渗透。
207 0
云上攻防-云原生篇&K8s安全-Kubelet未授权访问、API Server未授权访问
|
4月前
|
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它自己
|
4月前
|
资源调度 Kubernetes API
在K8S中,能否实现不通过api-Server创建Pod?
在K8S中,能否实现不通过api-Server创建Pod?
|
4月前
|
Kubernetes 负载均衡 API
在K8S中,api-service 和 kube-schedule 高可用原理是什么?
在K8S中,api-service 和 kube-schedule 高可用原理是什么?
|
4月前
|
Kubernetes 监控 API
在k8S中,各模块如何与API Server进行通信的?
在k8S中,各模块如何与API Server进行通信的?
|
1天前
|
存储 Kubernetes 关系型数据库
阿里云ACK备份中心,K8s集群业务应用数据的一站式灾备方案
本文源自2024云栖大会苏雅诗的演讲,探讨了K8s集群业务为何需要灾备及其重要性。文中强调了集群与业务高可用配置对稳定性的重要性,并指出人为误操作等风险,建议实施周期性和特定情况下的灾备措施。针对容器化业务,提出了灾备的新特性与需求,包括工作负载为核心、云资源信息的备份,以及有状态应用的数据保护。介绍了ACK推出的备份中心解决方案,支持命名空间、标签、资源类型等维度的备份,并具备存储卷数据保护功能,能够满足GitOps流程企业的特定需求。此外,还详细描述了备份中心的使用流程、控制台展示、灾备难点及解决方案等内容,展示了备份中心如何有效应对K8s集群资源和存储卷数据的灾备挑战。
|
22天前
|
Kubernetes 监控 Cloud Native
Kubernetes集群的高可用性与伸缩性实践
Kubernetes集群的高可用性与伸缩性实践
56 1
|
2月前
|
JSON Kubernetes 容灾
ACK One应用分发上线:高效管理多集群应用
ACK One应用分发上线,主要介绍了新能力的使用场景
|
2月前
|
Kubernetes 持续交付 开发工具
ACK One GitOps:ApplicationSet UI简化多集群GitOps应用管理
ACK One GitOps新发布了多集群应用控制台,支持管理Argo CD ApplicationSet,提升大规模应用和集群的多集群GitOps应用分发管理体验。
|
2月前
|
Kubernetes Ubuntu Linux
Centos7 搭建 kubernetes集群
本文介绍了如何搭建一个三节点的Kubernetes集群,包括一个主节点和两个工作节点。各节点运行CentOS 7系统,最低配置为2核CPU、2GB内存和15GB硬盘。详细步骤包括环境配置、安装Docker、关闭防火墙和SELinux、禁用交换分区、安装kubeadm、kubelet、kubectl,以及初始化Kubernetes集群和安装网络插件Calico或Flannel。
194 4