如何使用 nginx-ingress 控制器通过 TCP 公开多个服务?
Posted
技术标签:
【中文标题】如何使用 nginx-ingress 控制器通过 TCP 公开多个服务?【英文标题】:How to expose multiple services with TCP using nginx-ingress controller? 【发布时间】:2021-07-21 21:12:15 【问题描述】:我有多个运行 RDP 应用程序的部署,它们都通过 ClusterIP 服务公开。我在我的 k8s 集群中有 nginx-ingress 控制器,为了允许 tcp,我在 nginx-ingress 控制器部署中添加了--tcp-services-configmap
标志,并为其创建了一个配置映射,如下所示
apiVersion: v1
kind: ConfigMap
metadata:
name: tcp-services
namespace: ingress-nginx
data:
3389: “demo/rdp-service1:3389”
这将公开“rdp-service1”服务。而且我还有 10 个这样的服务需要在同一个端口号上公开,但是如果我像这样在同一个 configmap 中添加更多服务
...
data
3389: “demo/rdp-service1:3389”
3389: “demo/rdp-service2:3389”
然后它会删除之前的服务数据,因为这里我也在k8s中部署了external-dns,所以ingress使用host: ...
创建的所有记录都将开始指向configmap中新添加的服务所附加的部署。
现在我的最终要求是,只要我在入口中附加新创建的部署(RDP 应用程序)的规则,它就会开始允许 TCP 连接,那么有什么方法可以实现这一点。或者有没有其他可用的 Ingress 控制器可以解决这种类型的用例并且也可以很容易地与 external-dns 集成?
注意:- 我正在使用 AWS EKS 集群和带有外部 DNS 的 Route53。
【问题讨论】:
如果我对您的理解正确,您想公开多个Deployments
或RDP
应用,这些应用在单端口上使用TCP
流量和nginx-ingress
.您是否考虑过创建一个包含所有内容的Service
?您可以通过为每个Deployment
添加标签来做到这一点,例如connect: true
,并将其用作Configmap
(big-rdp-service:3389
) 中Service
的选择器。
@DawidKruk 在这里我也想做基于虚拟名称主机的路由,为此我必须在入口中创建一个规则来指定后端服务和主机名,所以在这里我无法创建服务这包括所有部署。
【参考方案1】:
将此答案发布为社区 wiki,以解释问题中的一些主题,并希望指出解决方案。
随意扩展/编辑它。
NGINX Ingress
主要职责是转发HTTP
/HTTPS
流量。通过添加tcp-services
/udp-services
,它还可以将TCP
/UDP
流量转发到各自的端点:
主要问题是 Kubernetes 中 Ingress
资源的基于 Host
的路由专门针对 HTTP
/HTTPS
流量,而不是 TCP
(RDP
)。
您可以实现以下场景:
Ingress controller
:
3389
- RDP
Deployment
#1
3390
- RDP
Deployment
#2
3391
- RDP
Deployment
#3
没有基于Host
的路由。它更像是端口转发。
附注! 此设置还取决于
LoadBalancer
分配端口的能力(这可能会受到云提供商规范的限制)
至于可能不太直接的解决方案,我会看看以下资源:
***.com: Questions: Nxing TCP forwarding based on hostname Doc.traefik.io: Traefik: Routing: Routers: Configuring TCP routers Github.com: Bolkedebruin: Rdpgw我还会检查以下链接:
Aws.amazon.con: Quickstart: Architecture: Rd gateway - AWS 特定
Docs.konghq.com: Kubernetes ingress controller: 1.2.X: Guides: Using tcpingress
代理:
Haproxy.com: Documentation: Aloha: 12-0: Deployment guides: Remote desktop: RDP gateway Haproxy.com: Documentation: Aloha: 10-5: Deployment guides: Remote desktop Haproxy.com: Blog: Microsoft remote desktop services rds load balancing and protection【讨论】:
感谢您的回复。实际上,我开始了解其他支持基于主机名使用 SNI SSL/TLS 终止的 TCP 路由的入口控制器。我已经尝试了这些入口控制器(Ambassador、Traefik、Kong)并设置了我的用例所需的所有东西,但仍然无法实现,因为我的 docker 映像是 RDP 服务器,所以当我尝试使用 DNS 连接 RDP 客户端时记录(即主机名)然后它无法连接。所以现在我很困惑RDP客户端是否将数据包中的SNI(即主机名)发送到服务器。 @AjayPathak 我无法回答你这个问题,但我认为这个关于 RDP 的问题可以在 Serverfault 上提出。【参考方案2】:其实,我真的不知道你为什么要使用那个 configmap。
据我所知,nginx-ingress-controller 正在路由来自同一端口的流量并基于主机进行路由。因此,如果您想在同一个端口上公开您的应用程序,请尝试使用:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: .Chart.Name -ingress
namespace: your-namespace
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: your-hostname
http:
paths:
- pathType: Prefix
path: "/"
backend:
serviceName: .Chart.Name -service
servicePort: .Values.service.nodeport.port
看你的需求,我觉得你需要一个LoadBalancer而不是Ingress
【讨论】:
感谢您的回复,但这并不能解决我的用例。实际上我有数百个部署,所以我不想用 LoadBalancer 公开每个部署。而且由于我的 docker 镜像是 RDP 桌面,所以使用 nginx-ingress 控制器我不能通过在 ingress 中创建正常规则来直接访问它,为此在 nginx-ingress 控制器中我们必须创建一个配置映射以允许 tcp 连接。这里的问题是,在一个 configmap 中,我们可以为一个 tcp 端口编写一项服务。 嗨@AjayPathak,所以你想通过1个端口公开你的一些部署。如果我理解正确,您可以创建一个 Nodeport 类型的服务,并通过填写“Selector”和“matchLabels”字段来注册要公开的部署 是的@AshBlake 我也试过了,但是如果我在 NodePort 上公开每个部署,那么我无法连接 pod 中的 RDP 应用程序,因为 RDP 客户端应用程序只能连接 3389 端口。跨度> 是的,我认为您应该找到一种方法来改变您的部署。因为您想公开具有 1 个端口、1 个 DNS 的多个部署,这是不可能的。以上是关于如何使用 nginx-ingress 控制器通过 TCP 公开多个服务?的主要内容,如果未能解决你的问题,请参考以下文章
GKE 是不是支持带有静态 ip 的 nginx-ingress?
nginx.conf 忽略了 nginx-ingress 配置映射片段
如何使用一个负载均衡器为两个域的两个入口配置 nginx-ingress