如何为 Kubernetes 负载均衡器指定静态 IP 地址?

Posted

技术标签:

【中文标题】如何为 Kubernetes 负载均衡器指定静态 IP 地址?【英文标题】:How to specify static IP address for Kubernetes load balancer? 【发布时间】:2015-11-22 19:41:18 【问题描述】:

我有一个在 Google Compute Engine 上运行的 Kubernetes 集群,我想将静态 IP 地址分配给我的外部服务 (type: LoadBalancer)。我不确定目前这是否可行。我找到了关于该主题的以下来源:

Kubernetes Service Documentation 允许您定义一个外部 IP 地址,但它失败了 cannot unmarshal object into Go value of type []v1.LoadBalancerIngress publicIPs field 似乎可以让我指定外部 IP,但它似乎也不起作用 This Github issue 表示我正在尝试做的事情尚不支持,但将在 Kubernetes v1.1 中 clusterIP field 还允许我指定 IP 地址,但失败并显示“提供的 IP 不在有效范围内

我觉得在设置 Web 服务时使用静态 IP 非常重要。我在这里错过了什么吗?如果有人能在这里启发我,我将非常感激!

编辑:澄清一下:我没有使用 Container Engine,我自己使用 Compute Engine 的官方安装说明设置了一个集群。与我的 k8s 服务关联的所有 IP 地址都标记为“临时”,这意味着重新创建 kubernetes 服务可能会导致不同的外部 IP 地址(这就是为什么我需要它们是静态的)。

【问题讨论】:

你到底做了什么来解决这个问题?和你一样,恐怕如果 IP 发生变化,每次重新创建部署时,我都必须更改 godaddy 记录以指向新的 IP 地址。 在您的服务声明中使用loadBalancerIP 字段,如当前文档中所述:kubernetes.io/docs/user-guide/services/#type-loadbalancer 【参考方案1】:

就我而言,我确认loadBalancerIP 字段允许使用 Kubernetes 1.18.2 为 GKE LoadBalancer 指定静态 IP 地址:

apiVersion: v1
kind: Service
spec:
  ...
  type: LoadBalancer
  loadBalancerIP: 10.136.0.49

此外,以下命令会返回给定项目的负载均衡器 IP:

gcloud compute forwarding-rules list --project <PROJECT_IS>
NAME                              REGION       IP_ADDRESS   IP_PROTOCOL  TARGET
aaba14cac607a4413813bebfb7eaaf8a  us-central1  10.136.0.49  TCP          us-central1/backendServices/aaba14cac607a4413813bebfb7eaaf8a

该命令证明它工作正常:

kubectl get service <svc-name> 
NAME          TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
<svc-name>    LoadBalancer   10.136.27.201   10.136.0.49   4040:30754/TCP   57s

【讨论】:

【参考方案2】:

TL;DR 运行 Kubernetes v1.1 的 Google Container Engine 支持 loadBalancerIP 只需先将自动分配的 IP 标记为 static

Kubernetes v1.1 支持externalIPs:

apiVersion: v1
kind: Service
spec:
  type: LoadBalancer
  loadBalancerIP: 10.10.10.10
  ...

到目前为止,还没有关于如何在 GCE 上使用它的非常好的一致文档。可以确定的是,此 IP 首先必须是您预先分配的 静态 IP 之一。

cross-region load balancing 文档主要用于 Compute Engine,而不是 Kubernetes/Container Engine,但它仍然很有用,尤其是“配置负载平衡服务”部分。

如果您只是在 GCE 上创建 Kubernetes LoadBalancer,它将创建一个网络计算引擎 > 网络 > 网络负载平衡 > 转发规则,指向由您集群上的机器组成的目标池(通常只有那些运行 Pod 匹配服务选择器)。看起来删除命名空间并不能很好地清理那些创建的规则。


更新

实际上现在支持它(即使文档不足):

    检查您运行的是 Kubernetes 1.1 或更高版本(在 GKE 下编辑您的集群并检查“节点版本”) 在Networking > External IP addresses 下分配静态IP,或者: 在没有loadBalancerIP 的情况下部署一次,等到您在运行kubectl get svc 时分配了一个外部IP,然后在该页面的列表中查找该IP 并将其从Ephemeral 更改为静态。 单击集群区域中的区域性“保留静态地址”,附加到无。 编辑您的 LoadBalancer 以使 loadBalancerIP=10.10.10.10 如上所述(适应 Google 提供给您的 IP)。

现在,如果您删除 LoadBalancer 甚至命名空间,它会在该集群上重新部署时保留该 IP 地址。


2016 年 11 月 14 日更新

另请参阅 Kubernetes article,描述如何在 Kubernetes 上为单个或多个域设置静态 IP。

【讨论】:

谢谢——loadBalancerIP 效果很好。也许他们自此发布以来纠正了一个错误。 在 1.1 中遵循新程序,loadBalancerIP 工作得很好。是否有类似的技术来添加 HTTP/HTTPS 负载平衡器? @GNN HTTP/HTTPS 与 IP 无关。更准确地说,你只有一个带有静态 IP 的 LB 服务,而该服务只有 80 和 443 端口(可能重定向到 pod 的 80 和 443 端口)。 在花费数小时阅读谷歌文档试图弄清楚这一点之后 - 我很高兴我找到了这篇文章。干得好。 这很有帮助。 k8s 文档令人困惑,因为它暗示 loadBalancerIP 不是负载均衡器的 ingress 地址,但看起来确实如此。【参考方案3】:

Kubernetes v1.1 将进行一些更改。

首先,GCE 中的所有负载均衡器都将获得静态 IP。这允许我们模拟 GCE 不支持的“更新”操作。

其次,https://github.com/kubernetes/kubernetes/pull/13005 提出了一个新字段来显式设置负载均衡器的 IP。

请注意,只要您的服务存在,您的“临时”IP 就是您的。这大致类似于 AWS 对 ELB 名称所做的操作(随机分配,在您发布之前是您的)。

publicIPs(或 v1 中已弃用的PublicIPs)将被替换为具有非常相似语义的外部IPs。这些是“非托管”IP——kubernetes 不会使用它们建立负载均衡器,但会接受它们的流量。

clusterIP 是一个集群内地址,通常在集群或“项目”或 VPC 之外不可用(在 GCE 或 AWS 术语中)

【讨论】:

感谢您的详尽解释 :) 如果我想删除 + 重新创建服务并确保它保留其外部 IP 地址,您有什么建议? v1.0.x 中的临时 IP 可以做到这一点吗?我也对 v1.1 感到非常兴奋,是否有发布日期(或粗略估计)? 为什么需要删除服务并使用相同的负载均衡器 IP 重新创建它?简短的回答是目前还不支持。它有望在 v1.1(10 月中下旬)中得到支持。如果它对你来说真的很重要,你可以做一些黑客攻击,但所有黑客攻击都是有代价的:) 好吧,我的公共端点的 DNS 条目指向该 IP 地址,所以我想确保它不会改变,以防我必须更改 k8s 服务对象!我真的认为这将是一个常见的用例? :) 如前所述,对服务对象的更改导致 IP 更改的事实是一个错误,已在 v1.1 中得到纠正。这是一个常见的情况 - 错误很糟糕:) @TimHockin 如果我错了,请纠正我。当我在 Google Container Engine 中创建服务并将其标记为非临时服务时,该 ip 将在重新启动和删除后持续存在。因此,我可以为我的每个客户端(子域)创建这样的服务,这样每个 godaddy 子域都指向该特定服务的外部 IP。这是完成的标准方式还是我很荒谬?此外,将 ip 标记为非临时会导致 GCE 向我收取静态 IP 地址的费用吗?而且,将 LoadBalancer 用于该服务会导致 Google 向我收取额外费用,对吗?【参考方案4】:

如果您在 Google Container Engine 上运行,并且正在使用 type: LoadBalancer,那么 Google Cloud Platform 应该已经为您创建了一个网络负载均衡器,其静态 IP 地址将路由到该服务。您无需指定任何 IP 地址。

要查找网络负载均衡器的 IP,请运行:

gcloud compute forwarding-rules list --project "YOUR-PROJECT-ID"

你应该也能跑:

kubectl get services

这将为您的服务返回集群和外部 IP 和端口。

【讨论】:

我没有使用 Container Engine,我使用 Compute Engine 的官方安装说明自己设置了一个集群。转发规则已创建,但与它们关联的 IP 地址都标记为“临时”,这意味着重新创建 Kubernetes 服务可能会导致不同的外部 IP 地址。 一般来说,您永远不需要“重新创建服务”。 v1.0 中有一个错误导致某些类型的更新释放 IP 地址。这已在 v1.1 中修复。 @TimHockin 在某些情况下,永远不要重新创建服务可能会很好,但在有一个允许仅应用更改的部署解决方案之前,这是一个大问题。如果您认为每次必须重新创建 LoadBalancer 服务时,您就必须更新您的 DNS 并等待它传播。 我不确定“仅应用更改”是什么意思,但请查看 v1.1 版本中的 kubectl apply @TimHockin 例如,如果您 LoadBalancer 应该指向一组不同的标签,或者如果您想使用重新创建所有服务/pod 的新部署方法,或类似情况。在所有这些情况下,您最终都会重新创建LoadBalancer 服务并最终拥有一个新的“静态”IP。 loadBalancerIP 应该在 v1.1 中解决这个问题。

以上是关于如何为 Kubernetes 负载均衡器指定静态 IP 地址?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 NGINX 负载均衡器设置例外

如何为 AutoScale 实例使用 AWS 负载均衡器代理协议?

如何为 ECS 添加带有应用程序负载均衡器的 AWS API 网关?

如何为 Elastic Load Balancer 配置自动超时?

实用干货:Kubernetes中的负载均衡全解

DNS解析常见问题:如何为网站配置负载均衡?