【问题标题】:How to specify static IP address for Kubernetes load balancer?如何为 Kubernetes 负载均衡器指定静态 IP 地址?
【发布时间】: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

标签: load-balancing google-compute-engine kubernetes


【解决方案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 匹配服务选择器)。看起来删除命名空间并不能很好地清理那些创建的规则。


    更新

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

    1. 检查您运行的是 Kubernetes 1.1 或更高版本(在 GKE 下编辑您的集群并检查“节点版本”)
    2. Networking > External IP addresses 下分配静态IP,或者:
      • 在没有loadBalancerIP 的情况下部署一次,等到您在运行kubectl get svc 时分配了一个外部IP,然后在该页面的列表中查找该IP 并将其从Ephemeral 更改为静态
      • 单击集群区域中的区域性“保留静态地址”,附加到无。
    3. 编辑您的 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 中解决这个问题。
    猜你喜欢
    • 2018-04-22
    • 2012-11-25
    • 2020-02-20
    • 2018-08-01
    • 2021-01-21
    • 2020-06-02
    • 2020-01-30
    • 2017-03-01
    • 1970-01-01
    相关资源
    最近更新 更多