使用Kubernetes容器本机负载平衡和GCP Standalone NEG的网络负载平衡

使用Kubernetes容器本机负载平衡和GCP Standalone NEG的网络负载平衡,kubernetes,google-cloud-platform,google-kubernetes-engine,Kubernetes,Google Cloud Platform,Google Kubernetes Engine,场景 使用kubernetes managed NEG()作为TCP/SSL全局代理的后端。我的后端服务不是基于HTTP的服务。今天,我已经使用针对GCE端点的网络端点组设置了此功能。所以我想要的是切换出我的GCE端点,并用GKE工作负载替换它们 问题 我的终结点的运行状况检查不起作用。因为我的目标不是基于http的,所以我需要使用单独的服务来满足GCP负载平衡器使用的基于http的健康检查 为了演示这一点,我使用了iperf作为服务,并使用了运行http health checker应用程序的

场景

使用kubernetes managed NEG()作为TCP/SSL全局代理的后端。我的后端服务不是基于HTTP的服务。今天,我已经使用针对GCE端点的网络端点组设置了此功能。所以我想要的是切换出我的GCE端点,并用GKE工作负载替换它们

问题

我的终结点的运行状况检查不起作用。因为我的目标不是基于http的,所以我需要使用单独的服务来满足GCP负载平衡器使用的基于http的健康检查

为了演示这一点,我使用了iperf作为服务,并使用了运行http health checker应用程序的辅助工具

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: iperf
  labels:
    app: iperf
spec:
  replicas: 1
  selector:
    matchLabels:
      app: iperf
  serviceName: iperf
  template:
    metadata:
      labels:
        app: iperf
    spec:
      containers:
      - name: iperf
        image: networkstatic/iperf3
        imagePullPolicy: Always
        args:
          - "-s"
        ports:
          - name: iperf
            containerPort: 5201
            protocol: TCP
        readinessProbe:
          tcpSocket:
            port: iperf
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:
          tcpSocket:
            port: iperf
          initialDelaySeconds: 15
          periodSeconds: 20

      # Health checker side car
      - name: checker
        # This is the image built from the Dockerfile
        image: health-checker
        imagePullPolicy: Always
        command: ["/home/checker/health-checker/health-checker"]
        args: ["--listener=0.0.0.0:8081", "--port=5201", "--log-level=warning"]
        ports:
          - name: checker
            containerPort: 8081
            protocol: TCP

# Service with standalone neg
---
apiVersion: v1
kind: Service
metadata:
  name: iperf-s-iperf
  annotations:
    cloud.google.com/neg: '{"exposed_ports": {"5201":{}}}'
spec:
  selector:
    app: iperf
  ports:
  - name: iperf
    protocol: TCP
    port: 5201
    targetPort: 5201
  - name: checker
    protocol: TCP
    port: 8081
    targetPort: 8081
侧车集装箱使用的是从以下Dockerfile生成的图像:

FROM ubuntu:latest

# Create home directory for the user
RUN mkdir -p /home/checker/health-checker/ && \
    useradd -m -u 1001 -U -s /bin/sh -d /home/checker checker && \
    chown -R checker:checker /home/checker/health-checker

WORKDIR /home/checker/health-checker

# Copy health-checker from Github
ADD https://github.com/gruntwork-io/health-checker/releases/download/v0.0.5/health-checker_linux_386 /home/checker/health-checker/health-checker
RUN chmod +x /home/checker/health-checker/health-checker

# Change user to checker
USER checker

CMD ["/home/checker/health-checker/health-checker"]
构建映像,设置状态集和服务

GCP代理

接下来,我们必须设置TCP代理,im使用标准的外部TCP负载平衡器,跨越多个区域。
iperf
端口是命名端口,协议是TCP。对于HTTP健康检查,我做了一个标准检查,目标是端口8081,检查路径
/

我添加了将iperf端口作为后端暴露给负载平衡器的NEG。目标从未被发现为健康

预期行为

我希望我的吊舱被发现是健康的,iperf端口是可访问的

奇怪的行为/解决方法

我可以通过使用http入口安装一个附加服务来“欺骗”健康检查,目标是相同的端口和pod

---
apiVersion: v1
kind: Service
metadata:
  name: iperf-s-checker
  annotations:
    cloud.google.com/neg: '{"ingress": true}'
spec:
  type: ClusterIP
  selector:
    app: iperf
  ports:
  - name: checker
    protocol: TCP
    port: 8081
    targetPort: 8081

---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: iperf-i-checker
spec:
  backend:
    serviceName: iperf-s-checker
    servicePort: 8081
上面的配置将创建一个外部的基于HTTP的负载平衡器,带有支持网络端点。基于http的健康检查现在使用服务端口作为健康检查目标。 正如预期的那样,这将很好地发挥作用,我们可以从外部达成健康响应。令人兴奋的 现在来看看奇怪的部分。现在,当我们的支持pod被标记为这个基于http的服务的健康状态时,我们还将在上面的iperf服务中发现它的健康状态,现在非http流量的负载平衡工作正常

这种工作方式显然不是正确的

有什么办法解决这个问题吗?我是否遗漏了一些东西,可能是在NEG创建期间可以传递的注释,用于将健康检查端口与服务端口分离


谢谢

请提供您的环境详细信息、配置和所有步骤。还有,您希望看到最终结果是什么。我添加了更好的解释和示例代码来重现这个问题@PjoterS让我知道,如果您需要任何其他信息,正如我所看到的,您正在使用“TCP/SSL全局代理”,您应该期望在使用它时实现负载平衡。请看一下文档。请描述您的用例。@SerhiiRohoza您是正确的,我想使用网络端点组和容器本机负载平衡设置TCP/SSL全局代理,并通过后端向其发送负载平衡请求。如果我的端点组以GCE资源为目标,那么这个设置工作得很好,但是当我的目标是GKE工作负载时,它就不工作了。问题一定是在GKE的健康检查实现中,因为如果我实现了上面描述的非常奇怪的解决方法,我就可以完成这项工作。谢谢。所以它实际上和你的解决方法是一致的,对吗?您是将
iperf
用作测试应用程序还是将其作为设置的一部分?