「13.Developing Kubernetes」

  CREATED BY JENKINSBOT

到本章为止,我们学习了如何安装 Kubernetes Kubernetes交互,以及使用Kubernetes部署和管理应用程序。

本章中我们将介绍如何根据需求改进 Kubernetes Kubernetes的bug。

为此,我们需要安装Go,并需要从 GitHub Kubernetes的源代码。

我们将介绍如何编译整个 Kubernetes kubectl等具体的组件。

我们还将演示如何使用 Python Kubernetes的API服务,以及如何使用自定义的资源扩展 Kubernetes.

13.1. Compiling from Source

如何从源代码制作自己的Kubernetes可执行文件,而不是下载官方发行的可执行文件(请参阅2.4节),或第三方的产品?

克隆 Kubernetes Git代码仓库,并编译源代码。

如果在Docker的主机上,可以使用顶层 Makefile 的 quick-release 目标,如下所示:

# git clone
https://github.com/kubernetes/kubernetes

# cd kubernetes

# make quick-release

!!!基于 Docker Docker服务可以使用的内存足够。对于 MacOS,通过 Docker for Mac选项增加分配给 Docker的内存。

编译好的可执行文件保存在_output/release-stages目录中,完整的包再_output/release-tars中。

如果有设置好的 Golang ,则可以使用 Makefile 的 release 目标:

# git clone https: //github. com/kubernetes/kubernetes

# cd kubernetes

# make

编译好的可执行文件保存在_output/bin目录中。

具体的开发者指南
https://gtubcom/kubernetes/community/tree//contributors/devel

13.2. Compiling a Specific Component

如何从源代码编译特定 Kubernetes组件而不是所有的组件,例如,编译客户端 kubectl1?

使用 make kubectl

顶层 Makefile 中包含了用于编译各个组件的的目标。例如,编译kubectl kubeadm hyperkube的命令如下所示:

make kubectl

make kubeadm

make hypercube

编译好的可执行文件保存在_output/bin目录中。

13.3. Using a Python Client to Interact with the Kubernetes API

如何在 Python Kubernetes API编写脚本?

首先需要安装 Python kubernetes模块。这个模块是在 Kubernetes incubator Python软件包管理工具(Python Package Index,pyPi)网站安装此模块:

# pip install kubernetes

通过默认的 kubectl 环境可以访问 Kubernetes 的集群,然后就可以使用该 Python Kubernetes API对话了。

from kubernetes import client, config

config.load_kube_config()
v1= client. CoreV1Api()
res= v1.list_pod_for_all_namespaces(watch=False)

for pod in res.items:
	print(pod.metadata.name)

脚本中 config.load_kube_config()的调用,可以从 kubectl1的配置文件中加载 Kubernetes的认证信息和访问点。默认情况下,它将加载当前环境中的集群访问点和认证信息。

Python Kubernetes API的 OpenAPI 规格创建的。它会自动生成并一直保持最新。该客户端可以访问所有的API。

每个API组对应一个具体的类,所以如果需要调用属于/api/v1 API组的API对象的方法,那么需要实例化 CoreV1Api类。在使用Deploymnet时,需要实例化 extensionsV11beta1Api类。你可以在自动生成的帮助文档中找到所有的方法与对应的API组的实例(https://github. com/kubernetes-clientlpython/treel masterkubernetes)。

项目代码仓库中的实例
https: /github. com/kubernetes/python/tree//kuberetes-clietpyhntree masterexamples

13.4. Extending the API Using Custom Resource Definitions (CRDs)

假设你有一个自定义的工作负荷,但没有任何已有的资源(比如,部署、job或Statefulset)适合描述这个工作负荷。如何利用代表该工作负荷的新资源扩展 Kubernetes API,且可以像往常一样使用 kubectl?

可以使用自定义资源定义(Custom Resource Definition,CRD)

假设需要定义一个 Function类型的自定义资源。它代表了短期运行的、像Job一样的资源,类似于 AWS Lambda提供的功能,也就是所谓的“功能即服务”(Function–Service,as,它还有个极具误导性的名字“无服务器体系”)
关于在 Kubernetes上运行适合生产环境的FaaS解决方案,请参阅14.7节。

首先,在一个名为 functions–crd.yaml的清单文件中定义该CRD:

然后,通知API服务器这个新的CRD(注册需要几分钟的时间):

现在自定义的资源 Function已经定义好了并且服务器也知道了它的存在,接下来可以使用一个名为 myfaas.yaml的清单文件实例化这个资源,如下所示:

照例还需创建 Function myfaas的资源:

现在只需通过访问API服务器就可以找到CRD。例如,使用 kubectl1 proxy可以从本地访问API服务器,还可以查询键空间(比如下例中查询了 example.com/v1):

这里可以看到资源列表以及允许的操作。

如果想要删除自定义的资源实例 myfaas,那么只需运行删除命令:

正如你所见,创建一个CRD很直观。从终端用户的角度看来,CRD代表一个稳定的API,几乎与pod或job等内置的资源没有什么区别。所有常见的命令,比如 kubectl get和kubectl delete,也可以照常工作。

然而,创建一个CRD其实只是完全扩展该 Kubernetes API所必需的工作的一小半。CRD仅仅实现了通过API服务在etcd中存储数据或获取数据。还需要编写自定义的控制器,用于解释自定义数据表达用户的意图和建立控制循环对比当前的状态和声明的状态,以及调和二者。

在v1.7之前,CRD被称作第三方资源(third-party resources,tprs)如果你手头有一个TPR,强烈建议现在就移植它。

CRD主要的局限性在于(因此在某些场合,你可能希望使用用户的API服务器):

每个CRD仅支持一个版本,尽管每个API可以有多个版本(这意味着不可以在不同的CRD代表之间互相转换)。

在v1.7或更早的版本中,CRD不支持给字段赋默认值。

从v1.8开始,支持在CRD规格中使用字段验证规则。

不可以定义子资源,比如 status资源。

# 相关文章

使用CRD扩展 crd  kubernetes api
https: kubernetesi. iol docs/tasks/access-(htts:kubernetesioldocs/tasks/access-kubernetes-apilextend-api-custom-resource-definitionsh)

Stefan Schimanski F Michael Hausenblas的博文“深入 Kubernetes:API服务器之三 HR&&2=
(https: /blog.openshift. com/kubernetes- part-3a/)

Aaron Levy KubeCon2017大会上的演讲“编写自定的控制器:扩展集群的功能 HIhRE(
https: //www.youtube.com/watch?v=_BugPMIXfpE).

tu  nguyen 的文章“深入Kubernetes控制器”
(htpsengineerng bitnami. com/articlesla-deep-dive-into-kubernetes-controllers. html

Yaron Haviv的文章“使用自定义资源扩展Kubernetes1.7”
https: //(https: thenewstack.iolextend-kubernetes-1-7-custom-resources/