如何在K3s上配置Traefik Proxy以通过HTTP/1.1(h2c)连接gRPC Pod
问题分析
你遇到的net::ERR_CONNECTION_REFUSED问题核心出在HTTP入口的Traefik路由配置和客户端请求地址不匹配上——HTTPS能正常工作,说明后端gRPC服务、Service的h2c配置本身是没问题的。具体问题点:
- 客户端请求端口错误(你用了Service的8081端口,但应该指向Traefik的HTTP入口端口)
- 动态IP场景下用Host匹配规则完全失效,且当前固定IP的Host匹配也未正确触发
解决步骤
1. 修正Traefik HTTP IngressRoute配置
针对动态IP场景,改用路径匹配(或全请求匹配),同时确保路由正确关联h2c服务:
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: product-grpc namespace: default spec: entryPoints: - web # 对应Traefik默认HTTP入口,端口为80 routes: - match: PathPrefix(`/`) # 匹配所有HTTP请求,适配动态IP kind: Rule services: - name: product-connector namespace: default port: 8081 scheme: h2c # 和HTTPS版本一致,指定与后端用h2c通信 priority: 10 # 确保优先级高于其他可能的路由
如果需要更精确匹配gRPC请求,可结合Method过滤:
match: PathPrefix(`/`) && Method(`POST`)
2. 修正客户端请求地址
客户端必须指向Traefik的HTTP入口端口(默认80,而非内部Service的8081),因为Traefik是集群流量入口,负责转发请求到内部服务:
// 替换为你的Traefik动态IP,端口用80(若Traefik的web入口改了端口则对应调整) const url = 'http://172.16.6.81'; const transport = new GrpcWebFetchTransport({ baseUrl: url, });
3. 验证Traefik配置有效性
- 确认Traefik部署已将
web入口的80端口暴露到集群外部(比如用NodePort、LoadBalancer或端口转发方式) - 查看Traefik日志,检查路由匹配情况:
确认是否有对应HTTP请求的路由匹配记录kubectl logs -n kube-system <traefik-pod-name>
4. 可选:清理不必要的Pod配置
你的Deployment启用了hostNetwork: true,若无特殊需求建议移除,避免端口冲突或网络隔离问题:
spec: # hostname: product-connector # 非必需,可移除 # hostNetwork: true # 移除后使用K8s默认网络 containers: - name: product-connector image: mph_product_connector imagePullPolicy: Never ports: - containerPort: 50054
验证流程
- 应用修改后的配置:
kubectl apply -f <你的配置文件>.yaml - 重启Traefik确保配置生效(可选,Traefik通常支持热加载):
kubectl rollout restart deployment traefik -n kube-system - 测试客户端连接,确认连接拒绝错误是否消失
内容的提问来源于stack exchange,提问作者Kevin Chewning
相关产品推荐
相关产品推荐

