在GCP GKE上使用Nginx Ingress处理CONNECT请求
首先明确一点:你不能用GCP原生的Ingress资源(因为它底层依赖GCP LB,确实不支持CONNECT请求),但如果用的是NGINX Ingress Controller for Kubernetes(基于Nginx的自定义Ingress控制器),完全可以实现你要的CONNECT请求负载均衡,而且能复用你现有Nginx stream模块的配置思路。
下面是具体的实现步骤和注意点:
1. 启用Stream模块
默认情况下,GKE上部署的Nginx Ingress Controller可能未启用stream模块,你需要通过ConfigMap开启这个功能:
apiVersion: v1 kind: ConfigMap metadata: name: nginx-ingress-controller namespace: ingress-nginx # 替换为你的Ingress Controller所在命名空间 data: enable-stream: "true"
更新这个ConfigMap后,重启Nginx Ingress Controller的Pod,让配置生效。
2. 配置Stream转发规则
普通Ingress资源仅支持HTTP/HTTPS规则,因此你需要通过自定义ConfigMap添加stream块配置,或是修改Nginx模板注入你的stream规则。比如下面是一个实现CONNECT请求负载均衡的ConfigMap示例:
apiVersion: v1 kind: ConfigMap metadata: name: nginx-stream-config namespace: ingress-nginx data: stream-snippets: | server { listen 443; proxy_connect_timeout 10s; proxy_timeout 1m; proxy_pass proxy_backend; } upstream proxy_backend { least_conn; server your-proxy-service.default.svc.cluster.local:8080; # 替换为你的代理Service地址 }
这个配置会让Nginx监听443端口,接收CONNECT请求后,通过least_conn策略转发到你的代理服务器集群。
3. 暴露Stream监听端口
接下来需要修改Nginx Ingress Controller的Service,把stream监听的端口(比如上面的443)暴露出去,让外部流量能接入:
apiVersion: v1 kind: Service metadata: name: nginx-ingress-controller namespace: ingress-nginx spec: type: LoadBalancer ports: - name: https-stream port: 443 targetPort: 443 protocol: TCP selector: app: nginx-ingress
这里用LoadBalancer类型的Service,GCP会自动创建一个TCP负载均衡器,将外部443端口的流量转发到Nginx Ingress Controller的443端口(即我们配置的stream监听端口)。
关键注意事项
- 后端代理服务器需要以Kubernetes Service的形式存在,确保Nginx能通过集群DNS解析到这个Service。
- 如果你的CONNECT请求用于HTTPS隧道,Nginx不需要在这里终止TLS,仅需透明转发流量即可,因此stream配置里无需添加TLS相关指令。
- 建议开启Nginx的stream日志方便排查问题:可以在ConfigMap里添加
log-format-stream: "$remote_addr [$time_local] $protocol $status $bytes_sent $bytes_received $session_time"来定义日志格式。
内容的提问来源于stack exchange,提问作者apriscott

