简单说,kubeamark是k8官方推出的专门模拟性能测试的软件,透明公开一般被广泛认可,今天来简单上手接触一下。 参考官方文档
0x00.简介
what is kubeamark?
因为海量测试环境现实难以存在,而在集群上的测试又需要保证足够的机器和访问量,所以K8社区提供了kubemark这样一个模拟集群测试的工具,目的是暴露一些可能只会出现在大规模调度使用时出现的bug(当然,我们主要是用来模拟一下小规模的)
结构
从大体结构上看,kubeamark测试集群由两个部分组成:一个真实的master节点和一组Hollow(空心) 节点 。任何带有”Hollow”前缀的组件意味着实际组件的实例化并不真实存在(又或是自动删除/移动了组件?)。最好的例子就是HollowKubelet,它看起来像是一个普通的Kubelet,但是并没有启动任何的东西,也没有做任何磁盘映射-这只是一个虚假的Kubelet。本文末尾有更详细的设计和实施细节。
目前,主组件作为由kubelet创建/管理的pod运行在专用机器上,根据VM发行版,它自身作为主VM上的systemd或supervisord服务运行(我们使用了GCI镜像标准,尽管当下systemd还是主流)。拥有专用主机的master与在外部集群上运行master组件相比略有优势,因为master组件可以完全隔离主机资源。另一方面,HollowNodes在一个“外部”K8集群上以一个pod的方式运行,这个pod使用单独的命名空间(名为kubemark)。通过在真实环境的K8集群中构建多个pod,以模拟出kubemark测试集群的方案是这个测试架构设计的核心。
要求
要运行Kubemark,您需要一个K8集群(称为external cluster)来运行所有的HollowNodes和一个专用的master。master必须直接从HollowNodes进行路由。您还需要访问Docker镜像仓库(在GCE云主机的情况下为gcr.io),该仓库具有etcd,hollow-node和node-problem-detector的容器镜像。 (可以把镜像仓库本地化)
目前,自动构建脚本在GCE上是简单易用的,但是其他平台包括本地环境没有很好的支持,(我们)正努力将kubemark代码重构,使得它在其他云提供者上运行kubemark集群也变得相对简单。
常见用例和帮助程序脚本
Kubemark的常见工作流程是:
- 开启一个测试集群(在GCE上)
- 在测试集群上运行e2e测试 (what is e2e 测试)
- 监视测试过程并对错误进行调试
- 退出测试集群
对于那些想要将Kubemark移植到不同提供商的人来说,描述中的注释(在哪?目前未知)会比较有用。当上面提到的重构完成时,我们会用一个干净的API替换这些注释,这样可以让kubemark在任何提供者之上运行。
开始一个Kubemark集群
要在GCE上启动Kubemark测试集群,您需要自行创建一个外部的K8集群(可以是GCE或其他主机),确保kubeconfig默认指向它,构建一个kubernetes系统(例如通过运行 make quick-release)并运行test/kubemark/start-kubemark.sh脚本。该脚本将为主服务器创建一个虚拟机(安装好了PD并且设置了防火墙规则),然后启动kubelet并运行主组件的pods。接下来,它会在外部集群上将Hollow Node设置为Pods,并配置好所有必要的设置,让他们与kubemark apiserver通信。它将使用存储 cluster/kubemark/config-default.sh 的配置- 你可以根据需要调整它,但是注意到一些特性可能还没有实现,因为实现Hollow组件/ mock可能会落后于“真实”的。对于性能测试,重要?(interesting)的变量是NUM_NODES和KUBEMARK_MASTER_SIZE。启动kubemark脚本后,您将拥有一个测试集群和一个用于与测试集群通信的kubeconfig文件,这个文件存储在test/kubemark/resources/kubeconfig.kubemark目录下。
目前我们正在运行的Hollow Node,一般限制为0.09个CPU核心/ pod和220MB的内存。但是,如果我们还考虑在“外部”集群上运行的默认集群插件和fluentd所收集的资源,则此限制将变为0.1 CPU核心/ pod,从而在每个核心上允许运行10个Hollow Node节点(在“n1-standard-8“VM节点)。
背后细节:
start-kubemark.sh脚本做了很多事情:
准备一个名为MASTER_NAME的master(这个变量的值应该由此设置):(
以下步骤使用gcloud,在GCE之外应该很容易)
- 创建一个网络存储磁盘以供主服务器使用(如果标记,给etcd-events多一个)
- 为集群中的主节点创建静态IP地址,并将其分配给变量MASTER_IP
- 为主服务器创建一个VM实例,使用上面创建的PD和IP进行配置。
- 在主服务器中设置防火墙规则,默认情况下为所有TCP通信打开端口443 。
*端口443是master上的一个安全端口,用于与API服务器的所有外部通信。在最后一句话中,*外部 不仅仅意味着来自集群外部,还有来自其他机器(包括所有节点)的所有流量。目前本地组件,即ControllerManager和调度程序使用不安全的端口8080与API服务器通信。
[可选项]建立为kubemark集群设置PKI所需的必要证书/密钥(以下步骤独立于GCE,适用于所有提供商)
- 生成一个随机命名的临时目录,用于存储在EXIT上删除陷阱的PKI证书/密钥。
- 在master中为“admin”创建一个不记名token令牌。
- 为master,kubelet和kubecfg中的每一个生成CA和(证书+私钥)对的证书。
- 为master创建kubelet和kubeproxy令牌。
- 在本地写一个kubeconfig以
test/kubemark/resources/kubeconfig.kubemark启用本地kubectl的使用。
设置环境并启动主组件(通过
start-kubemark-master.sh脚本):(以下步骤使用gcloud进行SSH和SCP的掌握,不用GCE应该很容易做到)- SSH到master,并创建一个新的目录(
/etc/srv/kubernetes),并写入所有的证书/密钥/令牌/密码。 - 将所有的
master pod的资源配置文件、shell脚本(start-kubemark-master.sh,configure-kubectl.sh等)、 配置环境文件(kubemark-master-env.sh)从本机SCP到master。 - SSH到master并运行启动脚本
start-kubemark-master.sh(可能还有其他)。
注意:目录结构和由启动脚本执行的功能可能因主发行版而异。我们目前支持
gci-dev-56-8977-0-0GCE 的GCI镜像。- SSH到master,并创建一个新的目录(
在外部集群上设置并启动
Hollow Node(作为Pod):(以下步骤(第二和第三除外)独立于GCE,适用于所有提供商)- 从linux / amd64平台中下载适应当前kubernetes版本的的kubemark二进制文件。
- 使用这个二进制文件为
Hollow Node创建一个Docker镜像,并将其上传到一个远程的Docker仓库。(我们在GCE中使用gcr.io/作为我们的远程库,对于其他提供上应该是其他的) - [一次性]除了HollowKubelet和HollowProxy之外,为NodeProblemDetector创建并上传一个Docker镜像(参见kubernetes / node-problem-detector repo),这是
Hollow Nodepod中的一个容器。然而我们用的是一个会被检测到空的规则和条件的空配置,此步骤仅适用于其他云提供商,因为GCE的docker镜像已存在于GCR上。 - 创建并存储一个用于HollowKubelet / HollowProxy,addons,kubeconfig,和用于
HollowNode与HollowNodeProblemDetector的configMaps的kubeconfig加密文件。 - 在替换hollow-node_template.json资源中的所有变量之后,为启动它们的
HollowNodes创建一个ReplicationController。 - 等到所有的
HollowNodes都处于运行阶段。
在Kubemark集群上运行e2e测试
要在上一步创建的Kubemark集群上运行标准的e2e测试,请执行test/kubemark/run-e2e-tests.sh脚本。它会配置ginko使用Kubemark集群而不是其他的东西并启动一个e2e测试。此脚本不需要任何更改就可以在其他云提供商上工作。
默认情况下(如果没有东西会被传递给它),脚本将运行Density ‘30测试。如果你想运行一个不同的e2e测试,你只需要提供你想传递给hack/ginkgo-e2e.sh脚本的标志,例如--ginkgo.focus="Load"运行负载测试。
默认情况下,在每次测试结束时,它将删除Kubemark Master上的命名空间及其下的所有内容(例如事件,复制控制器),这需要花费很多时间。大多数情况下不需要这样的工作:如果您在运行后删除了Kubemark集群run-e2e-tests.sh,你不关心命名空间的删除性能,具体涉及到etcd; 有一个标志,使您可以避免名称空间删除:--delete-namespace=false。添加标志应该让你看到日志:Found DeleteNamespace=false, skipping namespace deletion!
监视测试执行和调试问题
Run-e2e-tests会在Kubemark上打印与普通e2e集群相同的输出,但是如果您需要深入挖掘,您需要了解如何调试HollowNodes以及当前master与普通机器的区别。
如果你需要调试master,你可以像在普通master上做类似的事情。Kubemark设置和普通设置的区别在于Kubemark的etcd是作为一个简单的docker容器运行的,所有的主组件都像普通进程一样运行。没有Kubelet监督他们。日志存储在完全相同的地方,即/var/logs/目录。因为二进制文件不受任何监督,所以在崩溃的情况下不会重新启动。
为了帮助你在集群启动脚本中进行调试,在~/configure-kubectl.sh主服务器上放置了一个 脚本。它负责下载gcloud和kubectl工具和配置kubectl工作在不安全的master端口(如果有安全问题就会派上用场)。脚本运行后,你可以使用master机器上的kubectl命令来控制整个集群。
调试HollowNodes更麻烦一点,就好像你遇到了一个问题,你需要知道哪个Hollow Node对应着Master所知道的HollowNode。在自注册过程中,HollowNodes提供其集群IP作为名称,这意味着如果您需要查找名为HollowNode的用户10.2.4.5,只需使用此集群IP在外部集群中查找Pod。在 test/kubemark/get-real-pod-for-hollow-node.sh下有一个帮助脚本来为你做这个。
当你有一个Pod名称,你可以kubectl logs在外部集群上使用获取日志,或者使用一个kubectl describe pod调用来找到一个外部节点,在这个外部节点上运行这个特定的HollowNode,这样你就可以SSH了。
例如,您想要查看my-pod运行Pod的HollowKubelet的日志。要做到这一点,你可以执行:
1 | kubectl kubernetes/test/kubemark/resources/kubeconfig.kubemark describe pod my-pod |
然后会输出pod的描述:
1 | Node: 1.2.3.4/1.2.3.4 |
要学习使用上述脚本的hollow-node对应于节点的pod1.2.3.4:
1 | kubernetes/test/kubemark/get-real-pod-for-hollow-node.sh 1.2.3.4 |
然后就会输出:
1 | hollow-node-1234 |
现在您只需使用普通的kubectl命令来获取日志:
1 | kubectl --namespace=kubemark logs hollow-node-1234 |
所有这些东西都应该在所有云提供商上完全一样。
退出Kubemark集群
在GCE上,您只需要执行test/kubemark/stop-kubemark.sh脚本,它将删除HollowNode ReplicationController和所有资源。在其他提供商,你需要自己删除所有这些东西。作为上述工作的一部分,还需要将kubemark重构为独立于提供者和特定于提供者的部分,再将删除了特定于提供者部分的资源转移到纯净的API中。
一些当前的实施细节和未来路线图
Kubemark master使用与普通Kubernetes完全相同的二进制文件。这意味着它永远不会过时。另一方面,HollowNodes使用现有的Kubelet的简化版(称为SimpleKubelet),它删除了其runtime管理器pkg/kubelet/dockertools/fake_manager.go,也是大部分的逻辑所在之处。因为没有简单的方法来模拟其他管理器(例如VolumeManager),所以它们在Kubemark中不被支持(例如,我们不能在其中调度具有和本地磁盘有映射关系的Pod)。
我们目前计划沿着以下方向扩展kubemark:
- 正如您在上述位置注意到的那样,我们的目标是使kubemark更加结构化,并且易于跨多个云提供商运行,而无需使用定义良好的kubemark提供程序API调整设置脚本。
- 允许kubemark运行在各种发行版(GCI,debian,redhat等)上。
- 使cube-test上的Kubemark性能模拟真正的集群ci-tests,如CPU,内存和网络带宽使用等指标,并通过可衡量的目标(如kubemark度量与真实群集度量的变化不超过X%)实现此目标。我们也可以使用Prometheus报告的指标。
- 通过将CI测试度量(例如聚合的API调用延迟,调度调用等待时间,密度/负载测试中不同master组件的CPU /内存使用率百分比)记录到结构良好的存储中,而不是(当前)dump到日志。
- 给kubemark一个前端界面,以便轻松查看和比较测试的指标。
分割线,下面是英文原文对照改进
Architecture
On a very high level, Kubemark cluster consists of two parts: a real master and a set of “Hollow” Nodes. The prefix “Hollow” to any component means an implementation/instantiation of the actual component with all “moving” parts mocked out. The best example is HollowKubelet, which pretends to be an ordinary Kubelet, but does not start anything, nor mount any volumes - it just lies it does. More detailed design and implementation details are at the end of this document.
Currently, master components run on a dedicated machine as pods that are created/managed by kubelet, which itself runs as either a systemd or a supervisord service on the master VM depending on the VM distro (though currently it is only systemd as we use a GCI image). Having a dedicated machine for the master has a slight advantage over running the master components on an external cluster, which is being able to completely isolate master resources from everything else. The HollowNodes on the other hand are run on an ‘external’ Kubernetes cluster as pods in an isolated namespace (named kubemark). This idea of using pods on a real cluster behave (or act) as nodes on the kubemark cluster lies at the heart of kubemark’s design.
Requirements
To run Kubemark you need a Kubernetes cluster (called external cluster) for running all your HollowNodes and a dedicated machine for a master. Master machine has to be directly routable from HollowNodes. You also need access to a Docker repository (which is gcr.io in the case of GCE) that has the container images for etcd, hollow-node and node-problem-detector.
Currently, scripts are written to be easily usable by GCE, but it should be relatively straightforward to port them to different providers or bare metal. There is an ongoing effort to refactor kubemark code into provider-specific (gce) and provider-independent code, which should make it relatively simple to run kubemark clusters on other cloud providers as well.