在 GKE 中动态部署有状态应用

时间:2021-07-02 17:00:13

标签: kubernetes devops google-kubernetes-engine kubernetes-ingress

我正在尝试找出我应该将 GKE 堆栈中的哪些工具应用于我的用例,即具有动态 HTTP 端点的有状态应用程序的动态部署。

在我的情况下有状态意味着我不想要任何副本和负载平衡(因为应用程序根本不能水平扩展)。我明白虽然在 k8s/gke 命名法中我仍然会使用“负载平衡器”,即使它会充当反向代理并且实际上不会平衡任何负载。

用例如下。我有一些网络应用程序,我可以在其中请求一个“新实例”,作为回报,我得到一个动态生成的 url(例如 http://random-uuid-1.acme.io)。此域应指向托管某些 Web 应用程序的容器 (Pod) 的新生成的单个实例。同样,如果我请求另一个“新实例”,我将得到一个 http://random-uuid-2.acme.io,它将指向同一应用程序的另一个(单独的)新生成的实例。

到目前为止,我想出了以下设置。每次我请求“新实例”时,我都会执行以下操作:

  • 创建一个动态名称为 app-${uuid} 的新 Pod,用于公开 HTTP 端口
  • 使用 NodePort 创建一个新服务,将 Pod 的 HTTP 端口“暴露”给集群
  • 通过添加新的 http 规则来创建或更新(如果存在)Ingress,其中我指定域 X 应指向 NodePort X

上面提到的 Ingress 使用 LoadBalancer 作为其控制器,这是 GKE 中的自动化过程。

我已经遇到的一些问题,您可以帮我解决:

  1. 虽然 Pod 和 NodePort 是每个应用程序的独立资源,但 Ingress 是共享的。因此,我无法仅创建/删除资源,但我还被迫跟踪已添加到 Ingress 的内容,以便能够从 yaml 中追加/删除,这绝对不是这样做的方法(即编辑yamls)。相反,我可能想要像 Ingress 这样的东西来监控特定的命名空间并根据 Pod 标签自动创建规则。假设我有 3 个带有标签的 Pod,app-1app-2app-3,我希望 Ingress 自动监控我的命名空间中的所有 Pod 并根据这些 Pod 的标签创建规则(即应用程序-1.acme.io -> Pod app-1 的反向代理)。
  2. 使用新的 HTTP 规则更新 Ingress 需要大约一分钟的时间才能允许流量进入 Pod,在此之前,即使 Ingress 和 LoadBalancer 看起来都“就绪”,我仍然收到 404。我不知道应该注意/等待什么才能获得明确的消息,表明入口控制器已准备好接受新生成的应用的流量。
  3. 在您无法严格定义 Pod/服务清单的情况下,管理此类集群的最佳做法是什么,因为您正在动态创建它们(使用不同的名称、端点或规则)。您肯定不想为每个要维护的应用程序创建一堆 yaml-s。我会想象在 Consul 的情况下类似于 consul templates 的东西,但对于 k8s?

1 个答案:

答案 0 :(得分:2)

我参与了一个类似的项目,我们决定使用 Kubernetes Client Library 来生成实例。这些实例由一个简单的 Web 应用程序管理,该应用程序采用一些自定义参数,将它们保存到其数据库中,然后创建一个实例。由于数据库的存在,跟踪到目前为止已创建的内容没有问题。通过查询数据库,我们能够判断此类部署是否已创建或更新/删除任何相关资源。

每个实例包括:

  • 部署(单副本或多副本,取决于实例);
  • ClusterIp 服务(没有理由使用 NodePort 保留机器端口);
  • 共享入口控制器的入口对象;
  • 和一些共享的 configMap。

我们还使用了 external DNScert manager,一个用于管理 DNS 记录,另一个用于为入口颁发 SSL 证书。通过此设置,部署新实例大约需要 10 分钟。 pod 和入口控制器在几秒钟内就准备好了,但我们不得不等待证书,它的准备情况取决于发行者的 DNS 是否获得了我们的新记录。这个问题可以通过使用通配符域来避免,但我们不得不使用许多不同的域,所以在我们的例子中它不是一个选项。

除此之外,您可以考虑编写 Helm chart 并利用 helm list command 查找现有实例并对其进行管理。虽然,这是一个相当“手动”的解决方案。如果您希望此功能成为您应用程序的一部分 - 最好使用 Kubernetes 客户端库。