如何连接不同数据中心的 Kubernetes 集群

如何连接不同数据中心的 Kubernetes 集群
欢迎来到我们的 Kubernetes 快速入门系列。 这是一个定期专栏,其中包含我们在网上和培训中收到的最有趣的问题。 Kubernetes 专家解答。

今天的专家是 Daniel Polenchik(丹尼尔·波伦西奇)。 丹尼尔在以下公司担任讲师和软件开发人员 学习8s.

如果您希望在下一篇文章中回答您的问题, 通过电子邮件联系我们推特:@learnk8s.

错过了以前的帖子吗? 在这里找到他们.

如何连接不同数据中心的Kubernetes集群?

简要地: Kubefed v2 即将推出,我还建议阅读有关 发货人 и 多集群调度程序项目.

通常,基础设施会在不同区域进行复制和分布,尤其是在受控环境中。

如果一个区域不可用,流量将被重定向到另一区域以避免中断。

借助 Kubernetes,您可以使用类似的策略并将工作负载分配到不同的区域。

您可以为每个团队、区域、环境或这些元素的组合拥有一个或多个集群。

您的集群可以托管在不同的云和本地中。

但如何针对如此地理分布规划基础设施呢?
您是否需要通过单个网络为多个云环境创建一个大型集群?
或者有很多小集群并找到一种方法来控制和同步它们?

一个领导集群

通过单个网络创建一个集群并不是那么容易。

想象一下,您发生了事故,集群段之间的连接丢失了。

如果您有一台主服务器,一半的资源将无法接收新命令,因为它们将无法联系主服务器。

同时你还有旧的路由表(kube-proxy 无法下载新的)并且没有额外的 pod(kubelet 无法请求更新)。

更糟糕的是,如果 Kubernetes 没有看到某个节点,它会将其标记为孤立节点,并将丢失的 pod 分发到现有节点。

因此,您的 Pod 数量是原来的两倍。

如果为每个区域制作一台主服务器,etcd 数据库中的共识算法就会出现问题。 (约。 编辑。 — 事实上,etcd 数据库不一定必须位于主服务器上。 它可以在同一区域的一组单独的服务器上运行。 确实,同时获得了集群的故障点。 但要快。)

etcd 用途 筏算法在将值写入磁盘之前协商该值。
也就是说,在将状态写入 etcd 之前,大多数实例必须达成共识。

如果etcd实例之间的延迟急剧增加,例如不同区域的三个etcd实例,则协商一个值并将其写入磁盘需要很长时间。
这反映在 Kubernetes 控制器中。

控制器管理器需要更多时间来了解更改并将响应写入数据库。

由于控制器不是一个,而是多个, 连锁反应的结果,整个集群开始工作非常缓慢.

etcd 对延迟非常敏感 官方文档建议使用SSD代替普通硬盘.

目前还没有针对单个集群的大型网络的良好示例。

基本上,开发者社区和 SIG 集群小组正在尝试找出如何像 Kubernetes 编排容器一样编排集群。

选项 1:使用 kubefed 进行集群联合

SIG-cluster 的官方回应 - kubefed2,原始 kube federation 客户端和运营商的新版本.

我们第一次尝试使用 kube federation 工具将集群集合作为单个对象进行管理。

开始是好的,但最终 kube federation 从未流行起来,因为它不支持所有资源。

例如,它支持联合交付和服务,但不支持 StatefulSet。
而且联邦配置都是以注解的形式传递的,不够灵活。

想象一下如何仅使用注释来描述联合中每个集群的副本分区。

真是一团糟。

SIG-cluster 在 kubefed v1 之后做了很多工作,并决定从不同的角度来处理这个问题。

他们决定发布安装在集群上的控制器,而不是注释。 可以使用自定义资源定义 (CRD) 对其进行自定义。

对于将成为联合一部分的每个资源,您都有一个包含三个部分的自定义 CRD 定义:

  • 资源的标准定义,例如部署;
  • 部分 placement,您可以在其中定义资源在联合中的分配方式;
  • 部分 override,对于特定资源,您可以覆盖放置中的权重和参数。

以下是包含放置部分和覆盖部分的组合交付的示例。

apiVersion: types.federation.k8s.io/v1alpha1
kind: FederatedDeployment
metadata:
  name: test-deployment
  namespace: test-namespace
spec:
  template:
    metadata:
      labels:
        app: nginx
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
            - image: nginx
              name: nginx
  placement:
    clusterNames:
      - cluster2
      - cluster1
  overrides:
    - clusterName: cluster2
      clusterOverrides:
        - path: spec.replicas
          value: 5

如您所见,供应分布在两个集群中: cluster1 и cluster2.

第一个集群提供 5 个副本,第二个集群设置为 XNUMX 个。

如果您需要对副本数量进行更多控制,kubefed2 提供了一个新的 ReplicaSchedulingPreference 对象,可以在其中对副本进行加权:

apiVersion: scheduling.federation.k8s.io/v1alpha1
kind: ReplicaSchedulingPreference
metadata:
  name: test-deployment
  namespace: test-ns
spec:
  targetKind: FederatedDeployment
  totalReplicas: 9
  clusters:
    A:
      weight: 1
    B:
      weight: 2

CRD 结构和 API 尚未完全准备好,官方项目存储库正在进行积极的工作。

密切关注 kubefed2,但请记住它尚不适合生产。

了解有关 kubefed2 的更多信息 关于 kubefed2 的官方文章 在有关 Kubernetes 的博客中以及 kubefed 项目的官方存储库.

选项 2:以 Booking.com 风格组合集群

Booking.com 的开发人员并未开发 kubefed v2,但他们提出了 Shipper - 一个在多个集群、多个区域和多个云中进行交付的操作员。

发货人 有点类似于 kubefed2。

这两个工具都允许您自定义多集群部署策略(使用哪些集群以及它们拥有多少个副本)。

托运人的目标是降低交付过程中出现错误的风险。

在 Shipper 中,您可以定义一系列步骤来描述先前和当前部署之间的副本划分以及传入流量。

当您将资源推送到集群时,Shipper 控制器会在所有已加入的集群中逐步推出该更改。

此外,托运人非常有限。

Например, 它接受舵图作为输入 并且不支持普通资源。
一般来说,Shipper 的工作方式是这样的。

您需要创建一个包含 Helm 图表的应用程序资源,而不是标准交付:

apiVersion: shipper.booking.com/v1alpha1
kind: Application
metadata:
  name: super-server
spec:
  revisionHistoryLimit: 3
  template:
    chart:
      name: nginx
      repoUrl: https://storage.googleapis.com/shipper-demo
      version: 0.0.1
    clusterRequirements:
      regions:
        - name: local
    strategy:
      steps:
        - capacity:
            contender: 1
            incumbent: 100
          name: staging
          traffic:
            contender: 0
            incumbent: 100
        - capacity:
            contender: 100
            incumbent: 0
          name: full on
          traffic:
            contender: 100
            incumbent: 0
    values:
      replicaCount: 3

Shipper 是管理多个集群的不错选择,但它与 Helm 的密切关系只会造成阻碍。

如果我们都从 Helm 切换到 自定义 или 甲必丹?

了解有关 Shipper 及其理念的更多信息,请访问 本官方新闻稿.

如果你想深入研究代码, 前往官方项目存储库.

选项 3:“神奇”集群合并

Kubefed v2 和 Shipper 与集群联合配合使用,通过自定义资源定义为集群提供新资源。

但是如果您不想重写所有交付、StatefulSet、DaemonSet 等来合并怎么办?

如何在不更改 YAML 的情况下将现有集群纳入联邦?

多集群调度器是一个 Admirality 项目,它处理集群上的工作负载调度。

但多集群调度程序并没有提出一种与集群交互并将资源包装在自定义定义中的新方法,而是嵌入到标准 Kubernetes 生命周期中并拦截创建 pod 的所有调用。

每个创建的 Pod 都会立即替换为虚拟 Pod。

多集群调度器的用途 用于访问修改的 webhook拦截调用并创建一个空闲的虚拟 Pod。

原始 Pod 经历另一个规划周期,在轮询整个联邦后,做出放置决定。

最后将Pod投递到目标集群。

结果,你有一个额外的 Pod,它什么也不做,只是占用空间。

优点是您不必编写新资源来组合供应。

创建 Pod 的每个资源都会自动准备好合并。

这很有趣,因为突然间你的物资分布在多个地区,而你甚至没有注意到。 然而,这是相当冒险的,因为这里的一切都依赖于魔法。

但是,虽然 Shipper 试图在很大程度上减轻交付的影响,但多集群调度程序可以处理更一般的任务,并且可能更适合批处理作业。

它没有先进的渐进交付机制。

有关多集群调度程序的更多信息,请访问 官方存储库页面.

如果您想了解实际的多集群调度程序,Admiralty 有 Argo 的有趣用例 — 工作流程、事件、CI 和 CD Kubernetes。

其他工具和解决方案

连接和管理多个集群是一项复杂的任务,并且没有通用的解决方案。

如果您想进一步探讨这个主题,这里有一些资源:

这就是今天的全部内容

感谢您阅读到最后!

如果您知道如何更有效地连接多个集群, 告诉我们.

我们会将您的方法添加到链接中。

特别感谢克里斯·内斯比特·史密斯(Chris Nesbitt-Smith)(克里斯·内斯比特-史密斯)和文森特·德·斯梅(文森特·德·斯梅特)(可靠性工程师 swatmobile.io)阅读文章并分享有关联盟如何运作的有用信息。

来源: habr.com

添加评论