# Kubernetes 支持 OpenAPI

原文：[Kubernetes supports OpenAPI](https://kubernetes.io/blog/2016/12/kubernetes-supports-openapi)

[Open API](https://www.openapis.org/) 让 API 提供者可以定义自己的操作和模型，并让开发者可以自动化的生成喜欢语言的客户端，用以和 API 服务器通信。Kubernetes 已经支持 Swagger 1.2（OpenAPI 规范的前身）有一段时间了，但是这一标准不够完整和有效，凭借这一支持，非常难生成工具或客户端。

在 Kubernetes 1.4，我们对目前的模型和操作进行了升级，引入了 Open API 规范（在没被捐献给 [Open API](https://www.openapis.org/about) 之前被称作 Swagger 2.0）支持的 Alpha 版本。从 [Kubernetes 1.5](http://blog.kubernetes.io/2016/12/kubernetes-1.5-supporting-production-workloads.html) 开始，OpenAPI 规范的支持已经完备，能够直接从 Kubernetes 源码生成规范，对于模型和方法的任何变更，都会保障文档和规范的完全同步。

新规范让我们有了更好的 API 文档，甚至还有了一个 [Python 客户端](https://github.com/kubernetes-incubator/client-python)。

这一模块化的规范用 GroupVersion 进行分隔，这一做法属于未雨绸缪，我们想要让不同的 API Server 使用不同的 GroupVersion。

规范的结构在 [Open API spec definition](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md) 中有解释。我们用 [operation 标记](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#tag-object) 来拆分每个 GroupVersion 并尽可能的丰富其中的模型、路径、操作等信息。操作的参数、调用方法以及响应都有文档描述。

例如，获取 Pod 信息的 OpenAPI 规范

~~~json
{
...
  "paths": {
"/api/v1/namespaces/{namespace}/pods/{name}": {
    "get": {
     "description": "read the specified Pod",
     "consumes": [
      "*/*"
     ],
     "produces": [
      "application/json",
      "application/yaml",
      "application/vnd.kubernetes.protobuf"
     ],
     "schemes": [
      "https"
     ],
     "tags": [
      "core_v1"
     ],
     "operationId": "readCoreV1NamespacedPod",
     "parameters": [
      {
       "uniqueItems": true,
       "type": "boolean",
       "description": "Should the export be exact.  Exact export maintains cluster-specific fields like 'Namespace'.",
       "name": "exact",
       "in": "query"
      },
      {
       "uniqueItems": true,
       "type": "boolean",
       "description": "Should this value be exported.  Export strips fields that a user can not specify.",
       "name": "export",
       "in": "query"
      }
     ],
     "responses": {
      "200": {
       "description": "OK",
       "schema": {
        "$ref": "#/definitions/v1.Pod"
       }
      },
      "401": {
       "description": "Unauthorized"
      }
     }
    },
…
}
…
~~~

有了这些信息，以及 `kube-apiserver` 的 URL，就可以据此来调用接口了（`/api/v1/namespaces/{namespace}/pods/{name}`），参数包括 `name`、`exact` 以及 `export` 等，调用结果会返回 Pod 信息。客户库生成器也会使用这些信息来创建一个 API 函数调用来读取 Pod 信息。例如 [Python 客户端](https://github.com/kubernetes-incubator/client-python) 能够很简单的进行如下调用：

~~~python
from kubernetes import client
ret = client.CoreV1Api().read_namespaced_pod(name="pods_name", namespace="default")
~~~

> https://gist.github.com/mbohlool/d5ec1dace27ef90cf742555c05480146
> 
> 一个简化版的 [`read_namespaced_pod`](https://gist.github.com/mbohlool/d5ec1dace27ef90cf742555c05480146)。
> 
> Python Client：https://github.com/kubernetes-incubator/client-python
> 

还可以使用 Swagger-codegen 文档生成器来根据这些信息生成文档：

    GET /api/v1/namespaces/{namespace}/pods/{name}
    (readCoreV1NamespacedPod)
    read the specified Pod
    Path parameters
    name (required)
    Path Parameter — name of the Pod
    namespace (required)
    Path Parameter — object name and auth scope, such as for teams and projects
    Consumes
    This API call consumes the following media types via the Content-Type request header:
    */*

    Query parameters
    pretty (optional)
    Query Parameter — If 'true', then the output is pretty printed.
    exact (optional)
    Query Parameter — Should the export be exact. Exact export maintains cluster-specific fields like 'Namespace'.
    export (optional)
    Query Parameter — Should this value be exported. Export strips fields that a user can not specify.
    Return type
    v1.Pod

    Produces
    This API call produces the following media types according to the Accept request header; the media type will be conveyed by the Content-Type response header.
    application/json
    application/yaml
    application/vnd.kubernetes.protobuf
    Responses
    200
    OK v1.Pod
    401
    Unauthorized

有两种方式访问 OpenAPI ：

- 从 `kube-apiserver`/swagger.json。这个文件会包含所有启用的 GroupVersion 方法和模型，其中的内容会是该 API Server 所对应的最新版本。
- Kubernetes 的 Github 仓库，可以访问 master 或者其他指定的 Release。

有很多[工具](http://swagger.io/tools/) 能和这些 API 协同工作，例如可以用 [swagger editor](http://swagger.io/swagger-editor/) 来打开规范文件并渲染文档，或者生成客户端；还可以直接利用 [swagger codegen](http://swagger.io/swagger-codegen/) 来生成文档和客户端。自动生成的客户端多数时候是开箱即用的。不过可能需要做一些登录和 Kubernetes 相关的设置。可以使用 [Python 客户端](https://github.com/kubernetes-incubator/client-python) 作为模板来开发自己的客户端。
