HAProxy 入口控制器服务更改了 GCP 上的 IP

HAProxy Ingress Controller Service Changed IP on GCP

我在我的 GKE 集群中使用 HAProxy 作为入口控制器。并将 HAProxy 服务公开为 LoadBalancer 服务(内部)。

最近,我遇到了一个问题,HA-Proxy 服务更改了其外部 IP,流量停止路由到 HAProxy。这个问题在不同的日子里发生了多次(现在已经停止了)。我必须手动将那个新的外部 IP 添加到那个 Loadbalancer 的前端以允许流量到 HAProxy。
HAProxy 有两个 pods 运行,并且都 运行 好几天了,日志中什么也没有。我认为它与服务或 GCP LB 有关,而不是 HAProxy 本身。
恐怕我没有任何与此相关的日志。

还是不知道,是什么导致服务IP变了。由于最近没有变化,集群和所有服务 运行 好几天正常,突然出现这种情况。

有没有人之前遇到过类似的问题?或者我该怎么做才能避免将来出现此类问题?
什么可能导致 IP 发生变化?

我的服务是这样配置的:

---
apiVersion: v1
kind: Service
metadata:
  labels:
    run: haproxy-ingress
  name: haproxy-ingress
  namespace: haproxy-controller
  annotations:
    cloud.google.com/load-balancer-type: "Internal"
    networking.gke.io/internal-load-balancer-allow-global-access: "true"
    cloud.google.com/network-tier: "Premium"
spec:
  selector:
    run: haproxy-ingress
  type: LoadBalancer
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  - name: https
    port: 443
    protocol: TCP
    targetPort: 443
  - name: stat
    port: 1024
    protocol: TCP
    targetPort: 1024

找到一些日志:

Warning SyncLoadBalancerFailed 30m (x3570 over 13d) service-controller Error syncing load balancer: failed to ensure load balancer: googleapi: Error 409: IP_IN_USE_BY_ANOTHER_RESOURCE - IP '10.17.129.17' is already being used by another resource.
Normal EnsuringLoadBalancer 3m33s (x3576 over 13d) service-controller Ensuring load balancer

不幸的是,没有日志,很难确定。您应该检查 GKE 发送到 Cloud Logging 的审计日志,因为这可能会让您了解发生了什么。一种选择是 GCP“哎呀”了 GLB 和 GKE 重新创建它,从而给它一个新的 IP。不过,我从来没有听说过 LB 会发生这种情况(它经常发生在节点上,但 LB 不会)。一个更常见的情况是你 运行 一些 kubectl 命令无意中删除了服务对象,然后它被你设置的一些管理层重新创建(Argo,Flux,Helm Operator,等等)但是再次删除+重新创建意味着它是具有新 IP 的新 LB。后一种情况应该在审核日志中可见,因此请务必检查一下。

简短的回答是:External IP 因为服务是短暂的。
因为 HA-Proxy 控制器 pods 已重新创建,所以 HA-Proxy 服务是使用临时 IP 创建的。

为避免此问题,我建议您使用可在 loadBalancerIP 字段中引用的静态 IP。

这可以通过以下步骤完成:

  • 保留静态IP。 (link)
  • 使用此IP,创建服务(link)

示例 YAML:

apiVersion: v1
kind: Service
metadata:
  name: helloweb
  labels:
    app: hello
spec:
  selector:
    app: hello
    tier: web
  ports:
  - port: 80
    targetPort: 8080
  type: LoadBalancer
  loadBalancerIP: "YOUR.IP.ADDRESS.HERE"