首页 > 解决方案 > 在 Type=LoadBalancer 的服务上指定 nodePort

问题描述

我们公司有一个外部服务需要连接到在我们的一个 Kubernetes 集群中运行的应用程序。外部服务必须通过 IP 地址(不能使用主机名)与静态端口(端口 80)连接。这并不理想,但我们无法控制外部服务。

我们集群中唯一对外暴露的服务运行 HAProxy,它将流量路由到集群中的所有内部(未公开暴露)的 Pod/服务。HAProxy 的服务部署为 LoadBalancer 类型,它位于 AWS ELB 后面,用于 SSL 终止。

当我尝试使用静态端口部署 HAProxy 时,问题就来了。根据文档,我应该能够在服务类型 = NodePort 或 LoadBalancer 的端口部分中指定“nodePort”:

nodePort:
The port on each node on which this service is exposed when type=NodePort or 
LoadBalancer. Usually assigned by the system. If specified, it will be 
allocated to the service if unused or else creation of the service will fail. 
Default is to auto-allocate a port if the ServiceType of this Service 
requires one.

Note that this Service will be visible as both <NodeIP>:spec.ports[*].nodePort and .spec.clusterIP:spec.ports[*].port. (If the --nodeport-addresses flag in kube-proxy is set, would be filtered NodeIP(s).)

所以当然,我尝试使用以下 k8s 配置文件:

apiVersion: v1
kind      : Service
metadata:
    name: haproxy
    labels:
        app : haproxy
        env : {{ .Values.env | lower }}
    annotations:
        dns.alpha.kubernetes.io/external: "{{ .Values.externalUrl | lower }}"
        service.beta.kubernetes.io/aws-load-balancer-ssl-cert                : {{ .Values.sslcert | lower }}
        service.beta.kubernetes.io/aws-load-balancer-ssl-ports               : "443"
        service.beta.kubernetes.io/aws-load-balancer-backend-protocol        : http
        service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout : "500"
        service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: "Environment={{ .Values.env | lower }},Type=k8s"
spec:
    type : LoadBalancer
    ports:
        - name      : https
          port      : 443
          targetPort: 80
          nodePort  : 80
    selector:
        app : haproxy
        env : {{ .Values.env | lower }}

使用 Helm 部署时会产生以下错误:

Error: UPGRADE FAILED: Service "haproxy" is invalid: spec.ports[0].nodePort: Invalid value: 80:

我只需要能够通过在浏览器中输入节点的 ip 来访问 haproxy 服务,但也许我放错了 nodePort 配置密钥。它应该放在配置文件的其他地方吗?我尝试将它移动到“端口”部分下的各个位置,但这只会引发解析错误。

提前致谢!我完全不知所措。

标签: kuberneteskubernetes-helm

解决方案


我相信如果你只是不尝试配置nodePort它会做你想做的事。

和很重要:在您的情况下porttargetPort它们指定端口 443(在 ELB 或 Kubernetes 服务端点上haproxy.default.svc.cluster.local)将被转发到 pod 中的端口 80。在您描述的 AWS 环境中,这nodePort主要是一个副作用:您将使用ClusterIP服务在 Pod 之间进行通信,并使用服务来LoadBalancer处理您想要在直接集群之外公开的内容,并且通常不会直接连接到节点本身。

一个更具体的限制nodePort必须在 30000 和 32767 之间;您不能使用它从节点发布任意端口,这就是您收到错误消息的原因。


推荐阅读