本文已发表一年以上。较旧的文章可能包含过时内容。请检查页面中的信息自发布以来是否已失效。
将 Kubernetes 端到端测试引入 Azure(第一部分)
在 AppFormix,持续集成测试是我们文化的一部分。我们看到了定期运行端到端测试的诸多好处,包括最大程度地减少回归以及确保我们的软件作为一个整体协同工作。为了确保为客户提供高质量的体验,我们不仅需要为我们的应用程序运行端到端测试,还需要为整个编排堆栈运行测试。我们的客户正在采用 Kubernetes 作为他们首选的容器编排技术,并且他们要求在容器执行位置方面拥有选择权,无论是从私有基础设施到公共云提供商(包括 Azure)。经过数周的工作,我们很高兴地宣布,我们正在贡献一个每晚运行的持续集成任务,该任务在 Azure 平台上执行 e2e 测试。仅运行 e2e 测试几周,我们已经发现并修复了 Kubernetes 中的两个问题。我们希望我们贡献的 e2e 任务将有助于社区随着 Kubernetes 的发展继续支持 Azure 平台。
在本博客文章中,我们将描述我们为实现 Azure 平台部署脚本所走的历程。这些部署脚本是我们正在贡献的 e2e 测试任务的先决条件,因为这些脚本使得我们的 e2e 测试任务能够测试 Kubernetes 主分支的最新提交。在随后的博客文章中,我们将详细描述有助于维护对 Azure 平台支持的 e2e 测试细节,以及如何向 Kubernetes 项目贡献联合 e2e 测试结果。
背景
虽然 Kubernetes 被设计为可在任何 IaaS 上运行,并且许多平台(包括 Google Compute Engine、AWS、Azure 和 Rackspace)都有解决方案指南,但 Kubernetes 项目将这些称为“版本化发行版”,因为它们只针对特定的 Kubernetes 二进制版本进行测试。另一方面,“开发发行版”则每天用于对最新的 Kubernetes 源代码进行自动化 e2e 测试,并作为代码提交的门控检查。
当我们首次调查 Azure 上现有的 Kubernetes 支持时,我们找到了使用 CoreOS 和 Weave 在 Azure 上运行 Kubernetes 的文档。该文档包含了部署脚本,但这些脚本不符合“开发发行版”所需的自动化集群创建的 cluster/kube-up.sh 框架。此外,当时还没有一个持续集成任务利用这些脚本来使用端到端测试场景(在 Kubernetes 仓库的 test/e2e 中找到)验证 Kubernetes。
通过对项目历史进行一些额外的调查(旁注:git log --all --grep='azure' --oneline 非常有用),我们发现之前曾存在一套与 cluster/kube-up.sh 框架集成的脚本。这些脚本于 2015 年 10 月 16 日被废弃(commit 8e8437d),因为它们在 Kubernetes 1.0 版本之前就已经无法工作了。以这些提交作为起点,我们着手更新脚本,并创建一个受支持的持续集成任务,以帮助持续维护。
集群部署脚本
为了在 Azure 上使用 Ubuntu VM 设置 Kubernetes 集群,我们沿用了之前被废弃的提交所奠定的基础,并尝试尽可能地利用现有代码。该解决方案使用 SaltStack 进行部署,并使用 OpenVPN 在主节点和 Minion 节点之间进行网络连接。SaltStack 还被其他几种解决方案用于配置管理,例如 AWS、GCE、Vagrant 和 Vsphere。恢复被废弃的提交只是一个起点,但我们很快意识到有几个关键要素需要关注:
- 使用 SaltStack 在节点上安装 Docker 和 Kubernetes
- 配置服务认证
- 配置网络
集群设置脚本确保 Docker 已安装,将 Kubernetes Docker 镜像复制到主节点和 Minion 节点,并加载镜像。在主节点上,SaltStack 启动 kubelet,然后由 kubelet 启动以下在容器中运行的 Kubernetes 服务:kube-api-server、kube-scheduler 和 kube-controller-manager。在每个 Minion 节点上,SaltStack 启动 kubelet,然后由 kubelet 启动 kube-proxy。
Kubernetes 服务在相互通信时必须进行认证。例如,Minion 会在主节点上向 kube-api 服务注册。在主节点上,脚本生成一个自签名证书和密钥,kube-api 使用它们进行 TLS 连接。Minion 被配置为跳过对 kube-api(自签名)TLS 证书的验证。我们将服务配置为使用用户名和密码凭据。用户名和密码由集群设置脚本生成,并存储在每个节点的 kubeconfig 文件中。
最后,我们实现了网络配置。为了使脚本参数化并最大程度地减少对目标环境的假设,脚本创建一个新的 Linux 网桥设备(cbr0),并确保所有容器都使用该接口访问网络。为了配置网络,我们使用 OpenVPN 在主节点和 Minion 节点之间建立隧道。对于每个 Minion,我们为其 Pod 预留一个 /24 子网。Azure 为每个节点分配了自己的 IP 地址。我们还为此网桥添加了必要的路由表条目,以便使用 OpenVPN 接口。这是确保不同主机中的 Pod 能够相互通信所必需的。主节点和 Minion 上的路由如下:
主节点
Destination Gateway Genmask Flags Metric Ref Use Iface
10.8.0.0 10.8.0.2 255.255.255.0 UG 0 0 0 tun0
10.8.0.2 0.0.0.0 255.255.255.255 UH 0 0 0 tun0
10.244.1.0 10.8.0.2 255.255.255.0 UG 0 0 0 tun0
10.244.2.0 10.8.0.2 255.255.255.0 UG 0 0 0 tun0
172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 cbr0
Minion-1
10.8.0.0 10.8.0.5 255.255.255.0 UG 0 0 0 tun0
10.8.0.5 0.0.0.0 255.255.255.255 UH 0 0 0 tun0
10.244.1.0 0.0.0.0 255.255.255.0 U 0 0 0 cbr0
10.244.2.0 10.8.0.5 255.255.255.0 UG 0 0 0 tun0
Minion-2
10.8.0.0 10.8.0.9 255.255.255.0 UG 0 0 0 tun0
10.8.0.9 0.0.0.0 255.255.255.255 UH 0 0 0 tun0
10.244.1.0 10.8.0.9 255.255.255.0 UG 0 0 0 tun0
10.244.2.0 0.0.0.0 255.255.255.0 U 0 0 0 cbr0
未来工作 部署脚本实现后,Azure 平台上有一部分 e2e 测试用例正在通过。每晚的测试结果发布到 Kubernetes 测试历史仪表盘。庄维序在 Kubernetes GitHub 上提交了一个拉取请求,我们正积极与 Kubernetes 社区合作,合并每晚 e2e 测试任务所需的 Azure 集群部署脚本。这些部署脚本为 Azure 上的 Kubernetes 提供了一个最小工作环境。后续还有几个步骤需要继续推进,我们希望社区能够参与进来共同完成。
- 只有一部分 e2e 场景通过,因为一些云提供商接口尚未在 Azure 上实现,例如负载均衡器和实例信息。为此,我们寻求社区的投入和帮助,以定义 cloudprovider 接口 (pkg/cloudprovider/) 的 Azure 实现。这些接口将启用诸如 Kubernetes Pods 暴露到外部网络和集群 DNS 等功能。
- Azure 有用于与服务交互的新 API。当前提交的脚本使用 Azure Service Management API,这些 API 已被弃用。在部署脚本中应使用 Azure Resource Manager API。AppFormix 团队很高兴能为 Kubernetes 社区贡献对 Azure 的支持。我们期待关于如何合作改进 Azure 上的 Kubernetes 的反馈意见。
编者注:想为 Kubernetes 做出贡献,请在这里参与。如果您有自己的 Kubernetes 故事想要分享,请告诉我们!
第二部分可在此阅读。