1、kubernetes API概述
Kubernetes API是集群系统中的重要组成部分,Kubernetes中各种资源(对象)的数据通过该API接口被提交到后端的持久化存储(etcd)中,Kubernetes集群中的各部件之间通过该API接口实现解耦合,同时Kubernetes集群中一个重要且便捷的管理工具kubectl也是通过访问该API接口实现其强大的管理功能的。Kubernetes API中的资源对象都拥有通用的元数据,资源对象也可能存在嵌套现象,比如在一个Pod里面嵌套多个Container。创建一个API对象是指通过API调用创建一条有意义的记录,该记录一旦被创建,Kubernetes将确保对应的资源对象会被自动创建并托管 维护。
在Kubernetes系统中,大多数情况下,API定义和实现都符合标准的HTTP REST格式, 比如通过标准的HTTP动词(POST、PUT、GET、DELETE)来完成对相关资源对象的查询、创建、修改、删除等操作。但同时Kubernetes 也为某些非标准的REST行为实现了附加的API接口,例如Watch某个资源的变化、进入容器执行某个操作等。另外,某些API接口可能违背严格的REST模式,因为接口不是返回单一的JSON对象,而是返回其他类型的数据,比如JSON对象流(Stream)或非结构化的文本日志数据等。
Kubernetes开发人员认为,任何成功的系统都会经历一个不断成长和不断适应各种变更的过程。因此,他们期望Kubernetes API是不断变更和增长的。同时,他们在设计和开发时,有意识地兼容了已存在的客户需求。通常,新的API资源(Resource)和新的资源域不希望被频繁地加入系统。资源或域的删除需要一个严格的审核流程。
Kubernetes API文档官网为https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/
运行在Master节点上的API Server进程同时提供了Swagger格式的API网页。Swagger UI是一款REST API文档在线自动生成和功能测试软件,关于Swagger的内容请访问官网http://swagger.io。
假设我们的API Server安装在172.16.10.100服务器上,绑定了6443端口,则可以通过访问https://172.16.10.100:6443/swagger-ui/来查看API信息,如图所示
单击api/v1可以查看所有API的列表。
以create a Pod为例,找到Rest API的访问路径为:/api/v1/namespaces/{namespace}/pods,单击Model链接,则可以查看文本格式显示的API接口描述。
我们看到,在Kubernetes API中,一个API的顶层(Top Level)元素由kind、apiVersion、metadata、spec和status等几个部分组成,接下来,我们分别对这几个部分进行说明。
kind表明对象有以下三大类别。
(1)对象(objects):代表在系统中的一个永久资源(实体),例如Pod、RC、Service、Namespace及Node等。通过操作这些资源的属性,客户端可以对该对象做创建、修改、删除和获取操作。
(2)列表(list):一个或多个资源类别的集合。列表有一个通用元数据的有限集合。所有列表(lists)通过“items”域获得对象数组。例如PodLists、ServiceLists、NodeLists。大部分定义在系统中的对象都有一个返回所有资源(resource)集合的端点,以及零到多个返回所有资源集合的子集的端点。某些对象有可能是单例对象(singletons),例如当前用户、系统默认用户等,这些对象没有列表。
(3)简单类别(simple):该类别包含作用在对象上的特殊行为和非持久实体。该类别限制了使用范围,它有一个通用元数据的有限集合,例如Binding、 Status。
apiVersion表明API的版本号,当前版本默认只支持v1。
Metadata是资源对象的元数据定义,是集合类的元素类型,包含一组由不同名称定义的属性。
在Kubernetes中每个资源对象都必须包含以下3种Metadata。
(1)namespace:对象所属的命名空间,如果不指定,系统则会将对象置于名为“default”的系统命名空间中。
(2)name:对象的名字,在一个命名空间中名字应具备唯一性。
(3)uid:系统为每个对象生成的唯一ID,符合RFC 4122规范的定义。
此外,每种对象还应该包含以下几个重要元数据。
labels:用户可定义的“标签”,键和值都为字符串的map,是对象进行组织和分类的一种手段,通常用于标签选择器(Label Selector),用来匹配目标对象。
annotations:用户可定义的“注解”,键和值都为字符串的map,被Kubernetes内部进程或者某些外部工具使用,用于存储和获取关于该对象的特定元数据。
resourceVersion:用于识别该资源内部版本号的字符串,在用于Watch操作时,可以避免在GET操作和下一次Watch操作之间造成的信息不一致,客户端可以用它来判断资源是否改变。该值应该被客户端看作不透明,且不做任何修改就返回给服务端。客户端不应该假定版本信息具有跨命名空间、跨不同资源类别、跨不同服务器的含义。
creationTimestamp:系统记录创建对象时的时间戳,符合RFC 3339规范。
deletionTimestamp:系统记录删除对象时的时间戳,符合RFC 3339规范。
selfLink:通过API访问资源自身的URL,例如一个Pod的link可能是/api/v1/namespaces/ default/pods/frontend-o8bg4。
spec是集合类的元素类型,用户对需要管理的对象进行详细描述的主体部分都在spec里给出,它会被Kubernetes持久化到etcd中保存,系统通过spec的描述来创建或更新对象,以达到用户期望的对象运行状态。spec的内容既包括用户提供的配置设置、默认值、属性的初始化值,也包括在对象创建过程中由其他相关组件(例如schedulers、auto-scalers)创建或修改的对象属性,比如Pod的Service IP地址。如果spec被删除,那么该对象将会从系统中被删除。
Status用于记录对象在系统中的当前状态信息,它也是集合类元素类型,status在一个自动处理的进程中被持久化,可以在流转的过程中生成。如果观察到一个资源丢失了它的状态(Status),则该丢失的状态可能被重新构造。以Pod为例,Pod的status信息主要包括conditions、containerStatuses、hostIP、phase、podIP、startTime等。其中比较重要的两个状态属性如下。
phase:描述对象所处的生命周期阶段,phase的典型值是“Pending”(创建中)“Running”“Active”(正在运行中)或“Terminated”(已终结),这几种状态对于不同的对象可能有轻微的差别,此外,关于当前phase附加的详细说明可能包含在其他域中。
condition:表示条件,由条件类型和状态值组成,目前仅有一种条件类型Ready,对应的状态值可以为True、False或Unknown。一个对象可以具备多种condition,而condition的状态值也可能不断发生变化,condition可能附带一些信息,例如最后的探测时间或最后的转变时间。
API版本
为了在兼容旧版本的同时不断升级新的API,Kubernetes 提供了多版本API的支持能力,每个版本的API通过一个版本号路径前缀进行区分,例如/api/v1beta3。通常情况下,新旧几个不同的API版本都能涵盖所有的Kubernetes资源对象,在不同的版本之间这些API接口存在一些细微差别。Kubernetes开发团队基于API级别选择版本而不是基于资源和域级别,是为了确保API能够描述一个清晰的连续的系统资源和行为的视图,能够控制访问的整个过程和控制实验性API的访问。
2、Kubernetes API概念
本章介绍了Kubernetes API中的常见概念。
标准API术语
有效检测变化
以块的形式检索大型结果集
以表格形式接收资源
资源的替代表示
Kubernetes API是通过HTTP提供的基于资源(RESTful)的编程接口。 它支持通过标准HTTP谓词(POST,PUT,PATCH,DELETE,GET)检索,创建,更新和删除主要资源,包括允许细粒度授权的许多对象的其他子资源(例如将pod绑定到节点) 为了方便或有效,可以接受和服务于不同表示形式的资源。 它还通过“watches”和一致列表支持对资源的有效更改通知,以允许其他组件有效地缓存和同步资源状态。
2.1 标准API术语
大多数Kubernetes API资源类型都是“objects” - 它们代表集群概念上的具体实例,如pod或命名空间。 较少数量的API资源类型是“virtual” - 它们通常表示操作而不是对象,例如权限检查(SubjectAccessReview使用具有JSON编码的body POST到subjectaccessreviews资源)。 所有对象都具有唯一名称以允许幂等创建和检索,但如果虚拟资源类型不可检索或不依赖于幂等性,则它们可能没有唯一的名称。
Kubernetes通常利用标准RESTful术语来描述API概念:
资源类型是在URL中使用的名称(pods, namespaces, services)
所有资源类型都在JSON(它们的对象模式)中具有具体表示,称为kind
资源类型的实例列表称为collection
资源类型的单个实例称为resource
所有的资源类型都由集群(/apis/GROUP/VERSION/*)或命名空间(/apis/GROUP/VERSION/namespaces/NAMESPACE/*)确定范围。 删除其命名空间时,将删除名称空间作用域资源类型,并通过对名称空间作用域的授权检查来控制对该资源类型的访问。
以下路径用于检索集合和资源
集群范围的资源:
GET /apis/GROUP/VERSION/RESOURCETYPE - 返回资源类型的资源集合
GET /apis/GROUP/VERSION/RESOURCETYPE/NAME - 在资源类型下使用NAME返回指定名称的资源
命名空间范围的资源:
GET /apis/GROUP/VERSION/RESOURCETYPE - 在所有名称空间中返回所有资源类型实例的集合
GET /apis/GROUP/VERSION/namespaces/NAMESPACE/RESOURCETYPE - 返回指定NAMESPACE中资源类型的所有实例的集合
GET /apis/GROUP/VERSION/namespaces/NAMESPACE/RESOURCETYPE/NAME - 在指定NAMESPACE中使用名称NAME返回资源类型的实例
由于命名空间是群集范围的资源类型,因此您可以使用GET /api/v1/namespace检索所有命名空间的列表,并使用GET /api/v1/namespaces/NAME检索有关特定命名空间的详细信息。
几乎所有对象资源类型都支持标准HTTP谓词 - GET,POST,PUT,PATCH和DELETE。 Kubernetes使用术语list来描述返回一组资源,以区别于检索通常称为get的单个资源。
某些资源类型将具有一个或多个子资源,表示为资源下方的子路径:
集群范围的资源:
GET /apis/GROUP/VERSION/RESOURCETYPE/NAME/SUBRESOURCE
命名空间范围的资源:
GET /apis/GROUP/VERSION/namespaces/NAMESPACE/RESOURCETYPE/NAME/SUBRESOURCE
每个子资源支持的谓词将根据对象而有所不同 - 请参阅API文档更多信息。 不可能跨多个资源访问子资源。 通常,如果有必要,将使用新的虚拟资源类型。
2.2 有效检测变化
要使客户端能够构建出群集当前状态的模型,需要所有Kubernetes对象资源类型来支持一致性列表和称为watch的增量更改通知源。 每个Kubernetes对象都有一个resourceVersion字段,表示存储在底层数据库中的该资源的版本。 检索资源集合(命名空间或集群作用域)时,服务器的响应将包含resourceVersion值,该值可用于启动对服务器的监视。 服务器将返回在提供的resourceVersion之后发生的所有更改(创建,删除和更新)。 这允许客户端获取当前状态,然后监视更改而不会丢失任何更新。 如果客户端监视断开连接,则可以从上次返回的resourceVersion重新启动新监视,或执行新的收集请求并重新开始。
例如:
1)列出给定命名空间中的所有pod。
GET /api/v1/namespaces/test/pods
---
200 OK
Content-Type: application/json
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {"resourceVersion":"10245"},
"items": [...]
}
2)从resourceVersion 10245开始,作为单独的JSON对象接收任何创建,删除或更新的通知。
GET /api/v1/namespaces/test/pods?watch=1&resourceVersion=10245
---
200 OK
Transfer-Encoding: chunked
Content-Type: application/json
{
"type": "ADDED",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "10596", ...}, ...}
}
{
"type": "MODIFIED",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "11020", ...}, ...}
}
...
一个给定的Kubernetes服务器仅在有限时间内保留历史变更列表。 使用etcd2的旧集群最多可保留1000个更改。 使用etcd3的较新群集默认情况下会在最近5分钟内保留更改。 当请求的监视操作因该资源的历史版本不可用而失败时,客户端必须通过识别状态代码410 Gone,清除其本地缓存,执行列表操作以及从该返回的resourceVersion启动监视新的清单操作来处理该情况。大多数客户端库为此逻辑提供某种形式的标准工具。 (在Go中,这称为Reflector,位于k8s.io/client-go/cache包中。)
2.3 以块的形式检索大型结果集
在大型群集上,检索某些资源类型的集合可能会导致影响服务器和客户端性能的非常大的响应结果。 例如,一个集群可能有数万个pod,每个pod都是1-2kb的编码JSON。 检索所有命名空间中的所有pod可能会导致响应非常大(10-20MB)并占用大量服务器资源。 从Kubernetes 1.9开始,服务器支持将单个大型结果集分解为许多较小的块,同时保持总请求的一致性。 每个块都可以按顺序返回,这会减少请求的总大小,并允许面向用户的客户端逐步显示结果以提高响应能力与使用体验。
要以块的形式检索单个列表,在集合请求上支持两个新参数limit和continue,并从列表元数据字段中的所有列表操作返回一个新字段continue。客户端应该在每个块中指定希望接收的最大结果,并且服务器将按限制数量返回结果中的资源,如果集合中有更多资源,则会包括一个continue值。然后,客户端可以在下一个请求时将此continue值传递给服务器,以指示服务器返回下一个结果块。直到服务器返回空的continue值时,客户端就可以使用完整的结果集。
与watch操作一样,continue令牌将在很短的时间后(默认为5分钟)到期,如果无法返回更多结果,则返回410 Gone。在这种情况下,客户端需要从头开始或省略limit参数。
例如,如果群集上有1253个pod,并且客户端希望一次接收500个pod的块,则他们将按如下方式请求这些块:
1)列出群集中的所有pod,每次最多检索500个pods。
GET /api/v1/pods?limit=500
---
200 OK
Content-Type: application/json
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"resourceVersion":"10245",
"continue": "ENCODED_CONTINUE_TOKEN",
...
},
"items": [...] // returns pods 1-500
}
2)继续上一个请求,检索下一组的500个pods。
GET /api/v1/pods?limit=500&cOntinue=ENCODED_CONTINUE_TOKEN
---
200 OK
Content-Type: application/json
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"resourceVersion":"10245",
"continue": "ENCODED_CONTINUE_TOKEN_2",
...
},
"items": [...] // returns pods 501-1000
}
3)继续上一个请求,检索最后253个 pods。
GET /api/v1/pods?limit=500&cOntinue=ENCODED_CONTINUE_TOKEN_2
---
200 OK
Content-Type: application/json
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"resourceVersion":"10245",
"continue": "", // continue token is empty because we have reached the end of the list
...
},
"items": [...] // returns pods 1001-1253
}
请注意,列表的resourceVersion在每次请求中保持不变,表示服务器向我们显示了pod的一致快照。
除非用户在没有continue令牌的情况下发出列表请求,否则将不会显示在版本10245之后创建,更新或删除的pods。 这允许客户端将大型请求分解为较小的块,然后对整个集执行监视操作,而不会丢失任何更新。
2.4 以表格形式接收资源
kubectl get是特定资源类型的一个或多个实例的简单表格表示。 过去,客户需要重现表格并描述在kubectl中实现的输出,以执行简单的对象列表。
该方法的一些限制包括在处理某些对象时的非常见的逻辑。 此外,API聚合或第三方资源提供的类型在编译时是未知的。 这意味着必须为客户端无法识别的类型做通用的实现。
为了避免如上所述的潜在限制,客户端可以请求对象的表示,将打印的特定细节委托给服务器。 Kubernetes API实现标准的HTTP内容类型协商:传递一个包含application/json值的Accept头application/json;as=Table;g=meta.k8s.io;v=v1beta1,使用GET调用将请求服务器返回table内容类型。
例如:
1)以表格格式列出群集上的所有pod。
GET /api/v1/pods
Accept: application/json;as=Table;v=meta.k8s.io;g=v1beta1
---
200 OK
Content-Type: application/json
{
"kind": "Table",
"apiVersion": "meta.k8s.io/v1beta1",
...
"columnDefinitions": [
...
]
}
对于服务器上没有自定义表定义的API资源类型,服务器返回默认的表响应,包括资源的name和creationTimestamp字段。
GET /apis/crd.example.com/v1alpha1/namespaces/default/resources
---
200 OK
Content-Type: application/json
...
{
"kind": "Table",
"apiVersion": "meta.k8s.io/v1beta1",
...
"columnDefinitions": [
{
"name": "Name",
"type": "string",
...
},
{
"name": "Created At",
"type": "date",
...
}
]
}
Table格式的响应从kube-apiserver的1.10版本才开始提供。 因此,并非所有API资源类型都支持Table响应,特别是在针对较旧的群集使用客户端时。 必须针对所有资源类型工作或可能处理旧群集的客户端在其Accept header中指定多个内容类型,以支持回退到非表格式的JSON:
Accept: application/json;as=Table;v=meta.k8s.io;g=v1beta1, application/json
2.5 资源的替代表示
默认情况下,Kubernetes将序列化为JSON的对象返回给内容类型为application/json的对象。 这是API的默认序列化格式。 但是,客户可以请求更高效的Protobuf表示这些对象,以获得更好的大规模性能。 Kubernetes API实现了标准HTTP内容类型协商:传递带有Accept头的GET调用将请求服务器返回提供的内容类型中的对象,而进行PUT或POST调用时将Protobuf中的对象发送到服务器将获取Content-Type header。 如果支持所请求的格式,服务器将返回Content-Type header。如果提供了无效的Content Type,则返回406不可接受的错误。
有关每个API支持的内容类型的列表,请参阅API文档。
示例:
1)以Protobuf格式列出群集上的所有pod。
GET /api/v1/pods
Accept: application/vnd.kubernetes.protobuf
---
200 OK
Content-Type: application/vnd.kubernetes.protobuf
... binary encoded PodList object
2)通过将Protobuf编码数据发送到服务器来创建pod,但是请求JSON格式的响应。
POST /api/v1/namespaces/test/pods
Content-Type: application/vnd.kubernetes.protobuf
Accept: application/json
... binary encoded Pod object
---
200 OK
Content-Type: application/json
{
"kind": "Pod",
"apiVersion": "v1",
...
}
并非所有API资源类型都支持Protobuf格式,特别是通过自定义资源定义或API扩展定义的那些。 必须针对所有资源类型工作的客户端应在其Accept header中指定多个内容类型以支持回退到JSON:
Accept: application/vnd.kubernetes.protobuf, application/json
Protobuf 编码
Kubernetes使用封装来编码Protobuf响应。 该包装器以4字节magic number开始,以帮助识别磁盘或etcd中的内容为Protobuf(而不是JSON),然后是Protobuf编码的包装器消息,它描述了底层对象的编码和类型,然后是包含的对象。
封装格式为:
A four byte magic number prefix:
Bytes 0-3: "k8s\x00" [0x6b, 0x38, 0x73, 0x00]
An encoded Protobuf message with the following IDL:
message Unknown {
// typeMeta should have the string values for "kind" and "apiVersion" as set on the JSON object
optional TypeMeta typeMeta = 1;
// raw will hold the complete serialized object in protobuf. See the protobuf definitions in the client libraries for a given kind.
optional bytes raw = 2;
// contentEncoding is encoding used for the raw data. Unspecified means no encoding.
optional string cOntentEncoding= 3;
// contentType is the serialization method used to serialize 'raw'. Unspecified means application/vnd.kubernetes.protobuf and is usually
// omitted.
optional string cOntentType= 4;
}
message TypeMeta {
// apiVersion is the group/version for this type
optional string apiVersion = 1;
// kind is the name of the object schema. A protobuf definition should exist for this object.
optional string kind = 2;
}
在application/vnd.kubernetes.protobuf中收到与预期前缀不匹配的响应的客户端应该拒绝响应,因为将来的版本可能需要以不兼容的方式更改序列化格式,并且将通过更改前缀来实现。
3、API Groups(API组)
为了更容易对API进行扩展,k8s使用API Groups(API组)进行标识。API Groups以REST URL中的路径进行定义。当前支持两类API Groups。
Core Groups(核心组),作为k8s最核心的API。其特点是没有“组”的概念,例如"v1",在资源对象的定义中表示为"apiVersion:v1"。
具有分组信息的API,以/apis/$GROUP_NAME/$VERSION URL路径进行标识,在资源对象的定义中表示为"apiVersion:$GROUP_NAME/$VERSION",例如:"apiVersion:batch/v1", "apiVersion:extensions:v1beta1", "apiVersion:apps/v1beta1"等,详细的API列表参见官网https://kubernetes.io/docs/reference/ 。
例如Pod的API说明如下图所示。由于Pod属于核心资源对象,所以不存在某个扩展API Group,页面显示为"Core",在Pod的定义中为"apiVersion:v1"。
而StatefulSet则属于名为"apps"的API组,版本号为v1beta1,在StatefulSet的定义中为"apiVersion:apps/v1"
如果要启用或禁用特定的API组,则需要在API Server的启动参数中设置--runtime-config进行声明。例如--runtime-cOnfig=batch/v2alpha1表示启用API组"batch/v2alpha1",也可以设置--runtime-cOnfig=batch/v1=false表示禁用API组"batch/v1"。多个API组的设置以逗号分隔。
在API Server服务中,DaemonSets, Deployments, HorizontalPodAutoscalers, Ingress, Jobs, ReplicaSets所属的API组是默认启用的。
在未来的演进中,k8s将支持用户自定义资源对象和对它们的基本CRUD操作。伴随着自定义资源对象,k8s的未来版本还将支持用户自定义API Server,与k8s Master的API Server共同工作,完成更复杂的资源对象管理工作。
4、API方法说明
API 资源使用REST模式,具体说明如下。
GET /<资源名的复数格式>:获得某一类型的资源列表,例如GET /pods 返回一个Pod资源列表。
POST /<资源名的复数格式>:创建一个资源,该资源来自用户提供的JSON对象。
GET /<资源名复数格式>/<名字>:通过给出的名称(Name)获得单个资源,例如GET /pods/first 返回一个名称为“first”的Pod。
DELETE /<资源名复数格式>/<名字>:通过给出的名字删除单个资源,删除选项(DeleteOptions)中可以指定的优雅删除(Grace Deletion)的时间(GracePeriodSeconds),该可选项表明了从服务端接收到删除请求到资源被删除的时间间隔(单位为秒)。不同的类别(Kind)可能为优雅删除时间(Grace Period)申明默认值。用户提交的优雅删除时间将覆盖该默认值,包括值为0的优雅删除时间。
PUT /<资源名复数格式>/<名字>:通过给出的资源名和客户端提供的JSON对象来更新或创建资源。
PATCH /<资源名复数格式>/<名字>:选择修改资源详细指定的域。
对于PATCH操作,目前Kubernetes API通过相应的HTTP首部“Content-Type”对其进行识别。
目前支持以下三种类型的PATCH操作。
JSON Patch, Content-Type: application/json-patch+json。在RFC6902的定义中,JSON Patch是执行在资源对象上的一系列操作,例如 {"op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ]}。详情请查看RFC6902说明,网址为HTTPs://tools.ietf.org/html/rfc6902。
Merge Patch, Content-Type: application/merge-json-patch+json。在RFC7386的定义中,Merge Patch必须包含对一个资源对象的部分描述,这个资源对象的部分描述就是一个JSON对象。该JSON对象被提交到服务端,并和服务端的当前对象合并,从而创建一个新的对象。详情请查看RFC73862说明,网址为HTTPs://tools.ietf.org/html/rfc7386。
Strategic Merge Patch, Content-Type: application/strategic-merge-patch+json,Strategic Merge Patch是一个定制化的Merge Patch实现。
接下来将详细讲解Strategic Merge Patch。
在标准的JSON Merge Patch中,JSON对象总是被合并(merge)的,但是资源对象中的列表域总是被替换的。通常这不是用户所希望的。例如,我们通过下列定义创建一个Pod资源对象:
spec:
containers:
- name: nginx
image: nginx-1.0
接着我们希望添加一个容器到这个Pod中,代码和上传的JSON对象如下所示:
PATCH /api/v1/namespaces/default/pods/pod-name
spec:
containers:
- name: log-tailer
image: log-tailer-1.0
如果我们使用标准的Merge Patch,则其中的整个容器列表将被单个的“log-tailer”容器所替换。然而我们的目的是两个容器列表能够合并。
为了解决这个问题,Strategic Merge Patch通过添加元数据到API对象中,并通过这些新元数据来决定哪个列表被合并,哪个列表不被合并。当前这些元数据作为结构标签,对于API对象自身来说是合法的。对于客户端来说,这些元数据作为Swagger annotations也是合法的。在上述例子中,向“containers”中添加“patchStrategy”域,且它的值为“merge”,通过添加“patchMergeKey”,它的值为“name”。也就是说,“containers”中的列表将会被合并而不是替换,合并的依据为“name”域的值。
此外,Kubernetes API添加了资源变动的“观察者”模式的API接口。
GET /watch/<资源名复数格式>:随时间变化,不断接收一连串的JSON对象,这些JSON对象记录了给定资源类别内所有资源对象的变化情况。
GET /watch/<资源名复数格式>/:随时间变化,不断接收一连串的JSON对象,这些JSON对象记录了某个给定资源对象的变化情况。
上述接口改变了返回数据的基本类别,watch动词返回的是一连串的JSON对象,而不是单个的JSON对象。并不是所有的对象类别都支持“观察者”模式的API接口,在后续的章节中将会说明哪些资源对象支持这种接口。
另外,Kubernetes还增加了HTTP Redirect与HTTP Proxy这两种特殊的API接口,前者实现资源重定向访问,后者则实现HTTP请求的代理。
5、API响应说明
API Server响应用户请求时附带一个状态码,该状态码符合HTTP规范。
下表列出了API Server可能返回的状态码。
在调用API接口发生错误时,Kubernetes 将会返回一个状态类别(Status Kind)。
下面是两种常见的错误场景:
(1)当一个操作不成功时(例如,当服务端返回一个非2xx HTTP 状态码时);
(2)当一个HTTP DELETE方法调用失败时。
状态对象被编码成JSON格式,同时该JSON对象被作为请求的响应体。该状态对象包含人和机器使用的域,这些域中包含来自API的关于失败原因的详细信息。
状态对象中的信息补充了对HTTP状态码的说明。 例如:
$ curl -v -k -H "Authorization: Bearer WhCDvq4VPpYhrcfmF6ei7V9qlbqTubUc" HTTPs://10.240.122.184:443/api/v1/namespaces/default/pods/grafana
> GET /api/v1/namespaces/default/pods/grafana HTTP/1.1> User-Agent: curl/7.26.0> Host: 10.240.122.184> Accept: */*> Authorization: Bearer WhCDvq4VPpYhrcfmF6ei7V9qlbqTubUc>
< { "kind": "Status", "apiVersion": "v1", "metadata": {}, "status": "Failure", "message": "pods \"grafana\" not found", "reason": "NotFound", "details": { "name": "grafana", "kind": "pods" }, "code": 404 } “status”域包含两个可能的值:Success和Failure。 “message”域包含对错误的可读描述。 “reason”域包含说明该操作失败原因的可读描述。如果该域的值为空,则表示该域内没有任何说明信息。“reason”域澄清HTTP状态码,但没有覆盖该状态码。 “details”可能包含和“reason”域相关的扩展数据。每个“reason”域可以定义它的扩展的“details”域。该域是可选的,返回数据的格式是不确定的,不同的reason类型返回的“details”域的内容不一样。 6、Kubernetes API的客户端库 使用各种编程语言的Kubernetes API的客户端库,主要包括两类: 官方支持的Kubernetes客户端库 社区维护的客户端库 要使用Kubernetes REST API编写应用程序,无需自己实现API调用和请求/响应类型。 可以将客户端库用于你所使用的编程语言。 客户端库通常会为您执行常见任务,例如身份验证。 大多数客户端库可以发现并使用Kubernetes服务帐户来验证API客户端是否在Kubernetes集群内运行,或者可以了解kubeconfig文件格式以读取凭据和API服务器地址。 下表中是官方支持的Kubernetes客户端库: Language Client Library Sample Programs Go github.com/kubernetes/client-go/ browse Python github.com/kubernetes-client/python/ browse Java github.com/kubernetes-client/java browse dotnet github.com/kubernetes-client/csharp browse Javascript github.com/kubernetes-client/Javascript browse 下表中是社区维护的客户端库: Language Client Library Clojure github.com/yanatan16/clj-kubernetes-api Go github.com/ericchiang/k8s Java (OSGi) bitbucket.org/amdatulabs/amdatu-kubernetes Java (Fabric8, OSGi) github.com/fabric8io/kubernetes-client Lisp github.com/brendandburns/cl-k8s Node.js (TypeScript) github.com/Goyoo/node-k8s-client Node.js github.com/tenxcloud/node-kubernetes-client Node.js github.com/godaddy/kubernetes-client Perl metacpan.org/pod/Net::Kubernetes PHP github.com/devstub/kubernetes-api-php-client PHP github.com/maclof/kubernetes-client Python github.com/eldarion-gondor/pykube Python github.com/mnubo/kubernetes-py Ruby github.com/Ch00k/kuber Ruby github.com/abonas/kubeclient Scala github.com/doriordan/skuber dotNet github.com/tonnyeremin/kubernetes_gen DotNet (RestSharp) github.com/masroorhasan/Kubernetes.DotNet Elixir github.com/obmarg/kazan Haskell github.com/soundcloud/haskell-kubernetes