无法访问AWS EKS中Nginx-Ingress与NLB后的gRPC应用求排查
我在AWS EKS中部署了一个gRPC应用,通过端口转发可正常访问:
grpcurl -plaintext -protoset-out=reflection.protoset localhost:8080 list grpc.health.v1.Health grpc.reflection.v1alpha.ServerReflection
通过Helm Chart安装Nginx-Ingress,配置如下:
USER-SUPPLIED VALUES: controller: service: annotations: service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp service.beta.kubernetes.io/aws-load-balancer-ssl-cert: <cert-arn> service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443" service.beta.kubernetes.io/aws-load-balancer-type: nlb targetPorts: https: 443
已成功创建带HTTP和TLS监听器的NLB。随后创建Ingress资源:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: cert-manager.io/cluster-issuer: letsencrypt-prod nginx.ingress.kubernetes.io/backend-protocol: GRPC nginx.ingress.kubernetes.io/ssl-redirect: "true" generation: 7 labels: name: <app> name: <svc-name> namespace: <ns> spec: ingressClassName: nginx rules: - host: <app>.development.<domain> http: paths: - backend: service: name: <svc> port: number: 80 path: / pathType: ImplementationSpecific tls: - hosts: - <app>.development.<domain> secretName: dev-tls status: loadBalancer: ingress: - hostname: <loadbalancer>
External DNS已在Route53中正确创建记录,cert-manager/LetsEncrypt也已成功获取证书,但使用grpcurl访问始终报"context deadline exceeded":
grpcurl -protoset-out=reflection.protoset <app>.development.<domain>:443 list Failed to dial target host "<app>.development.<domain>:443": context deadline exceeded
已做排查:
- 将TLS监听器的ALPN策略设为仅HTTP/2,无效
- 改用ALB Ingress控制器,问题依旧
- 用示例gRPC应用验证,排除应用本身问题
- 使用
Type=LoadBalancer的服务绕过Nginx-Ingress可正常访问,确定问题出在Nginx-Ingress配置
请问我遗漏了什么?
以下是几个优先级从高到低的配置排查点:
1. 解决双重TLS终止冲突
你同时在NLB和Ingress层配置了TLS(NLB绑定了<cert-arn>,Ingress通过cert-manager生成证书),双重TLS终止会导致协议不兼容,引发连接超时。
修正方案:移除NLB的SSL相关配置,让Ingress(Nginx)负责TLS终止,NLB仅做TCP转发。修改Helm配置如下:
controller: service: annotations: service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp service.beta.kubernetes.io/aws-load-balancer-type: nlb targetPorts: https: 443
保留Ingress的TLS配置,确保cert-manager已生成有效证书。
2. 启用Nginx的HTTP/2支持
gRPC依赖HTTP/2协议,需确保Nginx Controller启用了HTTP/2。添加Helm配置:
controller: config: http2: "on"
3. 添加gRPC专属超时配置
默认Nginx超时时间较短,无法适配gRPC请求,在Ingress资源中添加以下注解:
nginx.ingress.kubernetes.io/proxy-read-timeout: "300" nginx.ingress.kubernetes.io/proxy-send-timeout: "300" nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" nginx.ingress.kubernetes.io/grpc-timeout: "300s"
4. 验证后端Service端口映射
Ingress指向Service的80端口,需确认该Service已正确将80端口转发到gRPC应用的8080端口(端口转发时使用的是8080)。若端口映射错误,会导致Nginx无法连接后端应用。
5. 检查安全组规则
- 确认NLB的安全组允许443端口的入站流量
- 确认Nginx Controller所在节点的安全组允许NLB的443流量(目标端口443)进入
6. 查看Nginx Controller日志
获取具体错误信息,定位问题:
kubectl logs -n <ingress-namespace> <nginx-controller-pod-name> -f
日志中可能会显示连接后端的错误(如端口不匹配、协议错误等)。
内容的提问来源于stack exchange,提问作者jaxxstorm

