You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在EKS中通过单个LB暴露多TCP服务与HTTPS(支持IP限制)

Amazon EKS 单NLB多端口暴露方案指南与问题解答

1. 能否在EKS中用单个NLB同时暴露HTTPS与多TCP端口?

可以。AWS NLB原生支持在同一负载均衡器上配置多个监听端口(涵盖TCP、TLS协议),结合AWS Load Balancer Controller或NGINX Ingress的stream模块均可实现。同时可通过注解给NLB绑定弹性IP,获得静态IP地址,满足客户端白名单配置需求。

2. 两种方案哪种更适配此场景?

方案1:单/多LoadBalancer Service + AWS LB控制器

  • 优势:流量从NLB直接转发到后端服务,减少NGINX中转的性能损耗;转发规则由AWS LB控制器管理,架构更轻量化;适合对延迟敏感的TCP服务。
  • 劣势:无法通过域名映射区分TCP服务(TCP基于端口转发,NLB不解析域名);IP白名单配置依赖NLB监听规则或后端Security Group,灵活性有限。

方案2:NGINX Ingress Controller stream模块转发TCP流量

  • 优势:可通过NGINX的stream配置实现TCP流量的域名映射(需结合SNI,建议TCP服务启用TLS);IP白名单可在NGINX层面精细控制;所有流量统一由NGINX管理,配置更集中。
  • 劣势:多了一层NGINX转发,存在轻微性能损耗;需要维护额外的ConfigMap配置,复杂度稍高。

适配建议:如果需要给TCP服务配置域名映射,或者需要灵活的IP白名单规则,选方案2;如果追求极致性能、简化架构,且TCP服务仅通过端口访问,选方案1。

3. 两种方案是否均支持按服务配置IP白名单?

  • 方案1:支持。两种实现方式:
    1. 给对应Service添加service.beta.kubernetes.io/aws-load-balancer-source-ranges注解,配置该端口的源IP白名单;
    2. 在后端服务的Pod Security Group中配置入站规则,限制仅特定IP可访问服务端口。
  • 方案2:支持。在NGINX的stream-snippet中给每个TCP服务添加allow/deny规则,实现精细的IP访问控制。

4. TCP服务能否实现域名映射(如redis.mydomain.com),还是仅HTTPS支持?

  • 纯明文TCP协议不携带域名信息,方案1(直接NLB转发)无法实现域名映射,只能通过端口区分服务。
  • 方案2(NGINX stream模块)可以实现:
    • 如果TCP服务启用了TLS,可利用SNI(Server Name Indication),NGINX通过解析客户端请求中的SNI域名,将流量转发到对应服务;
    • 明文TCP无法直接识别域名,实用性较低,不建议采用。

示例配置

方案1:多Service共享同一NLB示例

1. NGINX Ingress Service(绑定NLB与弹性IP)
apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress-nlb
  annotations:
    # 指定为NLB
    service.beta.kubernetes.io/aws-load-balancer-type: "external"
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
    # 绑定弹性IP,多个EIP用逗号分隔
    service.beta.kubernetes.io/aws-load-balancer-eip-allocations: "eip-xxxxxx,eip-yyyyyy"
    # 允许其他Service共享此NLB
    service.beta.kubernetes.io/aws-load-balancer-shared: "true"
spec:
  type: LoadBalancer
  ports:
    - name: http
      port: 80
      targetPort: 80
      protocol: TCP
    - name: https
      port: 443
      targetPort: 443
      protocol: TCP
  selector:
    app: nginx-ingress-controller
2. Redis Service(共享NLB并配置IP白名单)
apiVersion: v1
kind: Service
metadata:
  name: redis-nlb-service
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "external"
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
    # 指定共享的NLB名称(从NGINX Service的NLB详情中获取)
    service.beta.kubernetes.io/aws-load-balancer-name: "nginx-ingress-nlb-xxxxxx"
    # 配置Redis的IP白名单
    service.beta.kubernetes.io/aws-load-balancer-source-ranges: "192.168.1.0/24"
spec:
  type: LoadBalancer
  ports:
    - name: redis
      port: 6379
      targetPort: 6379
      protocol: TCP
  selector:
    app: redis

方案2:NGINX Ingress Stream模块示例

1. 启用NGINX Stream模块(修改Ingress Controller Deployment)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  namespace: kube-system
spec:
  template:
    spec:
      containers:
        - name: nginx-ingress-controller
          args:
            - /nginx-ingress-controller
            - --enable-stream
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
            - --ingress-class=nginx
            # 其他默认参数...
2. 配置TCP服务映射ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-services
  namespace: kube-system
data:
  # 格式:外部端口: 命名空间/服务名称:服务端口
  6379: "default/redis-service:6379"
  27017: "default/mongo-service:27017"
  3306: "default/mysql-service:3306"
3. 更新NGINX Ingress Service(添加TCP端口)
apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress-nlb
  namespace: kube-system
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "external"
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
    service.beta.kubernetes.io/aws-load-balancer-eip-allocations: "eip-xxxxxx,eip-yyyyyy"
spec:
  type: LoadBalancer
  ports:
    - name: http
      port: 80
      targetPort: 80
      protocol: TCP
    - name: https
      port: 443
      targetPort: 443
      protocol: TCP
    - name: redis
      port: 6379
      targetPort: 6379
      protocol: TCP
    - name: mongo
      port: 27017
      targetPort: 27017
      protocol: TCP
    - name: mysql
      port: 3306
      targetPort: 3306
      protocol: TCP
  selector:
    app: nginx-ingress-controller
4. 配置TCP服务IP白名单
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configuration
  namespace: kube-system
data:
  stream-snippet: |
    # Redis IP白名单配置
    server {
      listen 6379;
      allow 192.168.1.0/24;
      deny all;
      proxy_pass redis-service.default.svc.cluster.local:6379;
    }
    # MongoDB IP白名单配置
    server {
      listen 27017;
      allow 10.0.0.0/8;
      deny all;
      proxy_pass mongo-service.default.svc.cluster.local:27017;
    }
5. TCP服务域名映射(基于SNI,需启用TLS)
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configuration
  namespace: kube-system
data:
  stream-snippet: |
    # 根据SNI域名映射到对应服务
    map $ssl_preread_server_name $target_service {
      redis.mydomain.com redis-service.default.svc.cluster.local:6379;
      mongo.mydomain.com mongo-service.default.svc.cluster.local:27017;
    }

    # TLS监听端口,处理带SNI的TCP请求
    server {
      listen 6443 ssl;
      # 引用你的TLS证书(需提前在K8s中创建Secret)
      ssl_certificate /etc/nginx/secrets/tls-secret/tls.crt;
      ssl_certificate_key /etc/nginx/secrets/tls-secret/tls.key;
      # 启用SNI预读取
      ssl_preread on;
      proxy_pass $target_service;
    }

内容的提问来源于stack exchange,提问作者kingfateh khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 01:35:56