nginx - 从同一个入口暴露 TCP 和 UDP

标签 nginx kubernetes

在 kubernetes 中,我有以下服务:

apiVersion: v1
kind: Service
metadata:
  name: test-service
  namespace: default
spec:
  ports:
    - name: tcp
      protocol: TCP
      port: 5555
      targetPort: 5555    
    - name: udp
      protocol: UDP
      port: 5556
      targetPort: 5556
  selector:
    tt: test

它公开了两个端口,5555 用于 TCP,5556 用于 UDP。如何使用同一个入口在外部公开这些端口?我尝试使用 nginx 来做类似下面的事情,但它不起作用。它提示不支持混合端口。

apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-services
  namespace: ingress-nginx
data:
  5555: "default/test-service:5555"
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: udp-services
  namespace: ingress-nginx
data:
  5556: "default/test-service:5556"
---
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  type: LoadBalancer
  ports:
    - name: tcp
      port: 5555
      targetPort: 5555
      protocol: TCP
    - name: udp
      port: 5556
      targetPort: 5556
      protocol: UDP
  args:
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

有办法吗?

最佳答案

大多数云提供商不支持 UDP 负载平衡或混合协议(protocol),并且可能有特定于云的方法来绕过此问题。

The DigitalOcean CPI does not support mixed protocols in the Service definition, it accepts TCP only for load balancer Services. It is possible to ask for HTTP(S) and HTTP2 ports with Service annotations.

Summary: The DO CPI is the current bottleneck with its TCP-only limitation. As long as it is there the implementation of this feature will have no effect on the DO bills.

查看更多:do-mixed-protocols .

可能会解决您的问题的一个简单解决方案是创建反向 独立服务器上的代理系统 - 使用 Nginx 和路由 UDP 和 TCP 流量直接到您的 Kubernetes 服务。

按照以下两个步骤:

1.创建一个NodePort服务应用

2. 创建一个小型服务器实例并在其上运行带有 LB 配置的 Nginx

使用NodePort一种服务类型,它将在集群节点上公开您的应用程序,并使它们可以通过静态端口上的节点 IP 访问。这种类型支持多协议(protocol)服务。阅读有关服务的更多信息 here .

apiVersion: v1
kind: Service
metadata:
  name: test-service
  namespace: default
spec:
  type: NodePort
  ports:
  - name: tcp
    protocol: TCP
    port: 5555
    targetPort: 5555
    nodePort: 30010    
  - name: udp
    protocol: UDP
    port: 5556
    targetPort: 5556
    nodePort: 30011
  selector:
    tt: test

例如,此服务公开了 test pod 的端口 5555 通过 nodeIP:30010使用 TCP 协议(protocol)和端口 5556 通过 nodeIP:30011使用 UDP。请根据您的需要调整端口,这只是一个示例。

然后创建一个小型服务器实例并运行Nginx使用 LB 配置。

对于这一步,您可以从任何云提供商处获得一台小型服务器。 一旦你有了服务器,ssh在里面并运行以下命令来安装 Nginx:

$ sudo yum install nginx

在下一步中,您将需要您的节点 IP 地址,您可以通过运行以下命令获取该地址:

$ kubectl get nodes -o wide.

注意:如果您的私有(private)集群无法从外部访问您的节点,则必须为此用途设置一个入口点(例如 NAT 网关)。

然后您必须将以下内容添加到您的 nginx.conf (运行命令 $ sudo vi /etc/nginx/nginx.conf ):

worker_processes 1;  
events {  
    worker_connections  1024;  
}  
stream {  
  upstream tcp_backend {  
    server <node ip 1>:30010;  
    server <node ip 2>:30010;  
    server <node ip 3>:30010;  
         ...  
  }  
  upstream udp_backend {  
    server <node ip 1>:30011;  
    server <node ip 2>:30011;  
    server <node ip 3>:30011;  
         ...  
  }  
  server {  
      listen 5555;  
      proxy_pass tcp_backend;  
      proxy_timeout 1s; }  
  server {  
      listen 5556 udp;  
      proxy_pass udp_backend;  
      proxy_timeout 1s;  
  }  
}

现在您可以使用命令启动您的 Nginx 服务器:

$ sudo /etc/init.d/nginx start

如果您在对配置文件应用更改之前已经启动了 Nginx 服务器,则必须重新启动它 - 执行以下命令:

$ sudo netstat -tulpn    # Get the PID of nginx.conf program  
$ sudo kill -2 <PID of nginx.conf>  
$ sudo service nginx restart

现在您有了可以通过 <server IP>:<nodePort> 访问的 UDP/TCP LoadBalancer .

查看更多:tcp-udp-loadbalancer .

关于nginx - 从同一个入口暴露 TCP 和 UDP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65094464/

相关文章:

docker - Docker和Kubernetes之间的主要区别是什么

kubernetes - Rancher 与 Kubernetes 有何不同

networking - Kubernetes 的动态通配符子域入口

https - HTTPS负载均衡器以在Google Kubernetes上公开工作负载

docker - 使用 nginx、kubernetes 和 docker 服务 Assets

django - django 应用程序的 uWSGI + nginx 避免 pylibmc 多线程并发问题?

php - 通过 nginx/php-fpm exec 调用时 npm 不运行

c# - 在我的 Rpi 上加载资源时出现 SSL 问题

ruby-on-rails - 多个 redmine 实例最佳实践

kubernetes - 无法覆盖 GKE 中的默认 Pod 安全策略