分布式应用有很多定义,但通常它们被定义为在由多台计算机组成的网络上运行的应用。如今,这很可能意味着一个在多个Kubernetes集群上运行的应用程序,这些集群分布在一个大的地理区域。由于这样的集群是分布式的,它们有很多好处--如高可用性、速度、弹性--但它会使开发、操作和测试这样的应用变得繁琐。Bank-Vaults的Multi-DC功能就是这样一个分布式应用;它的测试没有自动化,需要我们在每次重要的PR进入主程序时手动测试。这篇博文展示了如何在本地建立一个多集群测试基础设施,并在集群之间进行适当的负载平衡。另外,我们将向你展示我们如何在该基础设施上测试Bank-Vaults。
本地多集群 🔗︎
对于在本地测试Kubernetes应用程序,首先,你需要在你的笔记本电脑上有一个集群。许多项目提供了在本地运行Kubernetes集群,比如minikube、kind、Docker for Mac、k3s等等。我们最喜欢kind ,因为它是高度可定制的,是轻量级的,并且自己在Docker中运行,这带来了很多机会--正如你将看到的。在本教程中,我们将用kind创建三个Kubernetes集群,然后将它们加入Vault。
计划是将Vault与Bank-Vaults部署到这些集群中,并将它们与Raft存储后端连接。这个过程是完全自动化的,从Kubernetes集群的创建直到多DC Vault Raft集群读取为健康。这些基于Raft的Vault节点之间的通信是通过LoadBalancer类型的Kubernetes服务完成的。拥有一个有效的LoadBalancer服务是绝对必要的,为此,我们将在每个集群上配置一个MetalLB实例。我们已经在上一篇关于MetalLB的文章中详细介绍了如何在内部集群中工作。
在多集群上运行Bank-Vaults 🔗︎
我们将使用Bank-Vaults仓库中的multi-dc-raft.sh脚本来设置3个基于kind 的Kubernetes集群,在其上安装MetalLB,并在整个平台上安装Bank-Vaults。我们也用这个脚本对整个项目进行持续集成。如果脚本以0退出,说明多集群Raft设置是健康的。
对于自动解封的Vault集群,我们有必要将解封密钥存储在集群外的某个地方(加密)。在这个例子中,一个 "外部 "Vault实例被用作KMS服务(在Kubernetes集群之外)。kind ,创建自己的Docker网络,称为kind (这可以用KIND_EXPERIMENTAL_DOCKER_NETWORK 环境变量覆盖),并在此基础上提供集群。设置脚本在Kubernetes节点运行的同一个kind Docker网络上部署了一个Vault Docker容器,因此它们可以在网络层面上看到对方。集群内的三个Vault实例与这个 "外部 "实例解封。
在本地运行这个测试的要求(如果你已经在使用Kubernetes,你可能已经有了大部分的要求)如下。
- docker
- jq
- 种类
- kubectl
- 舵手
- github.com/subfuzion/e…
- github.com/hankjacobs/…
在检查完资源库后,在本地运行安装程序。
$ ./operator/deploy/multi-dc/test/multi-dc-raft.sh install
Creating cluster "primary" ...
✓ Ensuring node image (kindest/node:v1.19.1) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
Set kubectl context to "kind-primary"
You can now use your cluster with:
# ...
# A few minutes later
# ...
Waiting for for tertiary vault instance...
pod/vault-tertiary-0 condition met
Multi-DC Vault cluster setup completed.
现在设置完成了,你可以分析集群和运行在上面的Vaults,包括它们如何成功地相互连接。这些是我们在该顶层的Docker容器。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4ce56b6efe33 vault "docker-entrypoint.s…" 19 minutes ago Up 19 minutes 8200/tcp central-vault
af4c70d249bd kindest/node:v1.19.1 "/usr/local/bin/entr…" 20 minutes ago Up 20 minutes 127.0.0.1:59885->6443/tcp tertiary-control-plane
852771794e95 kindest/node:v1.19.1 "/usr/local/bin/entr…" 21 minutes ago Up 21 minutes 127.0.0.1:59542->6443/tcp secondary-control-plane
f017a2d80e89 kindest/node:v1.19.1 "/usr/local/bin/entr…" 22 minutes ago Up 22 minutes 127.0.0.1:59202->6443/tcp primary-control-plane
所有种类的Kubernetes节点都是Docker容器,kind ,在同一个Docker网络上启动它们,这被称为kind 。让我们看一下这个网络的子网。
$ docker network inspect kind
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
},
$ docker inspect primary-control-plane --format '{{.NetworkSettings.Networks.kind.IPAddress}}'
172.18.0.2
172.18.0.0/16,这是一个很多的地址。这三个节点从这个CIDR中得到一个地址。测试脚本从这个Docker子网为三个MetalLB控制器分配了三个范围,他们在相应的集群中管理地址。
- 172.18.1.128/25(主)。
- 172.18.2.128/25 (二级)
- 172.18.3.128/25 (三级)
现在,我们要在MetalLB中使用第二层的配置。这不需要任何特殊的重新配置(kind 中默认的kube-proxy 模式是 "iptables",这也减少了步骤),只需要为3个MetalLB实例管理以下配置的地址范围(用于主集群)。
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 172.18.1.128/25
第二层的配置在整个kind Docker网络上工作。MetalLBspeakers 组件在整个172.18.0.0/16网络中向地址解析协议(ARP)传达IP地址。
让我们确定,由于MetalLB的存在,现在一级实例在172.18.1.128到172.18.1.255范围内的一个地址(172.18.1.128)上可用。
$ kubectl config use-context kind-primary
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 9m48s
vault-operator ClusterIP 10.109.203.236 80/TCP,8383/TCP 6m50s
vault-primary LoadBalancer 10.103.77.250 172.18.1.128 8200:31187/TCP,8201:32413/TCP,9091:32638/TCP,9102:30358/TCP 5m44s
vault-primary-0 ClusterIP 10.109.38.127 8200/TCP,8201/TCP,9091/TCP 5m43s
vault-primary-configurer ClusterIP 10.111.165.239 9091/TCP 5m26s
现在三级实例(172.18.3.128:8201)可以加入一级和二级节点的集群,我们将在日志中看到。
$ kubectl config use-context kind-tertiary
$ kubectl logs -f vault-tertiary-0 -c vault
...
2020-09-17T07:10:45.223Z [INFO] storage.raft: initial configuration: index=1 servers="[
{Suffrage:Voter ID:6caa8795-74f1-d97b-5652-e592f2694a13 Address:172.18.1.128:8201}
{Suffrage:Voter ID:44ede1d6-c12a-86d5-a34b-7521ce0096b9 Address:172.18.2.128:8201}
{Suffrage:Voter ID:db17edbd-f423-ab47-3e5d-17624add5abf Address:172.18.3.128:8201}
]"
...
要完全删除测试设置,请运行以下内容。
$ ./operator/deploy/multi-dc/test/multi-dc-raft.sh uninstall
Deleting cluster "primary" ...
Deleting cluster "secondary" ...
Deleting cluster "tertiary" ...
central-vault
有了这个小脚本以及kind和MetalLB的帮助,我们可以很容易地测试这个复杂的多集群Vault设置,甚至在一台商品笔记本电脑上,或者--完全自动化--在一个托管的CI解决方案上,以防止错误潜入代码库。当你需要进行实验并希望在多集群应用程序中添加新功能时,这种设置也很方便。请随意抓取该脚本并使用它来安装你的应用程序。