Kubernetes:如何通过Ingress将非HTTP请求路由至容器
嘿,这个问题问得很实在!Nginx Ingress Controller默认确实是为HTTP/HTTPS流量设计的,但它完全支持通过TCP/UDP端口转发来处理非HTTP类的请求——比如数据库(MySQL、PostgreSQL这类)或者CORBA这类基于TCP的协议。下面我给你一步步讲怎么在Docker Desktop的Kubernetes集群上配置:
核心思路
Nginx Ingress Controller允许通过ConfigMap定义TCP/UDP端口与后端K8s服务的映射,然后让Ingress Controller加载这个配置,把外部的非HTTP流量转发到对应的容器服务。
第一步:创建TCP服务映射的ConfigMap
首先,我们需要创建一个ConfigMap来定义“外部端口→K8s服务”的映射关系。这个ConfigMap要和Ingress Controller部署在同一个命名空间(通常是ingress-nginx)。
创建一个tcp-services.yaml文件:
apiVersion: v1 kind: ConfigMap metadata: name: tcp-services namespace: ingress-nginx data: # 格式规则:外部端口号: 目标命名空间/服务名称:服务端口号 3306: "default/mysql-db-service:3306" # 示例:把本地3306转发到default命名空间的mysql服务 1234: "corba-system/corba-server-service:1234" # 示例:CORBA服务的端口映射
然后应用这个ConfigMap:
kubectl apply -f tcp-services.yaml
如果是UDP协议的请求,只需要创建名为udp-services的ConfigMap,格式和上面一致,后续挂载路径会不同。
第二步:修改Ingress Controller的Deployment/DaemonSet
接下来要让Ingress Controller加载我们刚才创建的ConfigMap,同时暴露对应的端口。Docker Desktop上的Nginx Ingress Controller一般是Deployment,我们用kubectl edit来修改:
kubectl edit deployment nginx-ingress-controller -n ingress-nginx
需要做两处修改:
添加端口暴露:在
spec.template.spec.containers[0].ports下新增要转发的TCP端口:ports: # 保留原有HTTP/HTTPS端口,新增下面的TCP端口 - name: tcp-3306 containerPort: 3306 hostPort: 3306 # 直接绑定Mac本地的端口,这样可以用localhost:3306访问 - name: tcp-1234 containerPort: 1234 hostPort: 1234注:如果不想用hostPort(比如怕端口冲突),也可以用NodePort模式,后续在Service里配置即可。
挂载ConfigMap到容器:让Nginx能读取我们的TCP配置:
- 在
spec.template.spec.containers[0].volumeMounts下新增:volumeMounts: # 保留原有挂载项,新增下面的 - name: tcp-services mountPath: /etc/nginx/tcp-services.d readOnly: true - 在
spec.template.spec.volumes下新增:volumes: # 保留原有卷,新增下面的 - name: tcp-services configMap: name: tcp-services
- 在
保存退出后,K8s会自动重启Ingress Controller的Pod来加载新配置。
第三步:更新Ingress Controller的Service
最后,我们需要把新增的TCP端口暴露到Ingress Controller的Service上,确保外部流量能进入:
kubectl edit service nginx-ingress-controller -n ingress-nginx
在spec.ports下新增对应的TCP端口:
ports: # 保留原有HTTP/HTTPS端口,新增下面的 - name: tcp-3306 port: 3306 targetPort: 3306 protocol: TCP - name: tcp-1234 port: 1234 targetPort: 1234 protocol: TCP
验证配置
现在你就可以测试非HTTP流量的转发了:
- 比如用MySQL客户端连接
localhost:3306,应该能直接访问到K8s集群里default/mysql-db-service对应的Pod。 - CORBA客户端可以连接
localhost:1234,访问到对应的CORBA服务容器。
注意事项
- 确保Mac本地的端口(比如3306、1234)没有被其他本地服务占用,否则会导致Ingress Controller Pod启动失败。
- 如果是UDP协议,只需要把上面的
tcp换成udp:ConfigMap名为udp-services,挂载路径是/etc/nginx/udp-services.d,端口配置的protocol设为UDP即可。 - 目标K8s服务必须已经存在,并且端口配置正确(ClusterIP服务即可,不需要NodePort)。
内容的提问来源于stack exchange,提问作者Matthias M

