Nginx 入口:TCP 端口上基于主机的路由
Nginx ingress : Host based routing on TCP port
Rabbitmq 5672 使用相同的 TCP 端口并根据基于主机的路由将请求传输到不同的namespaces/rabbitmq_service
。
什么有效:
chart: nginx-git/ingress-nginx
version: 3.32.0
values:
- tcp:
5672: "cust1namespace/rabbitmq:5672"
块反映在 nginx.conf:
server {
preread_by_lua_block {
ngx.var.proxy_upstream_name="tcp-cust1namespace-services-rabbitmq-5672";
}
listen :5672;
proxy_pass upstream_balancer;
}
注意:这会将所有到达端口 5672 的请求转移到 cust1namespace/rabbitmq:5672
,而不管客户端域名是什么,我们希望基于域名的基于主机的路由。
期望值:
chart: nginx-git/ingress-nginx
version: 3.32.0
values:
- tcp:
cust1domainname:5672: "cust1namespace/rabbitmq:5672"
cust2domainname:5672: "cust2namespace/rabbitmq:5672"
错误:
Failed to render chart: exit status 1: Error: unable to build kubernetes objects from release manifest: error validating "": error validating data: [ValidationError(Service.spec.ports[3].port): invalid type for io.k8s.api.core.v1.ServicePort.port: got "string", expected "integer", ValidationError(Service.spec.ports[4].port): invalid type for io.k8s.api.core.v1.ServicePort.port: got "string", expected "integer"]
最后的 nginx.conf 应该是这样的:
server {
preread_by_lua_block {
ngx.var.proxy_upstream_name="tcp-cust1namespace-services-rabbitmq-5672";
}
listen cust1domainname:5672;
proxy_pass upstream_balancer;
}
server {
preread_by_lua_block {
ngx.var.proxy_upstream_name="tcp-cust2namespace-services-rabbitmq-5672";
}
listen cust2domainname:5672;
proxy_pass upstream_balancer;
}
一点理论
由于网络协议的实施以及它们之间的差异,您尝试实施的方法是不可能的。
TCP
协议在传输层工作,它有源和目标 IP 和端口,它 没有 有任何主机信息。反过来 HTTP
协议在位于 TCP
之上的应用程序层上工作,它确实有关于主机的信息,这个请求将被发送到哪里。
请熟悉OSI model and protocols which works on these levels。这将有助于避免混淆为什么这种方式有效而不是其他方式。
还有一个good answer on quora about difference between HTTP and TCP protocols。
回答
此时你有两个选择:
- 使用 ingress 在应用层工作,让它将流量引导至基于
request body
中提供的主机的服务。所有流量都应通过入口端点(通常是暴露在集群外部的负载均衡器)。
请查找带有
的示例
- 使用入口处理传输层并为每个 service/customer 公开单独的 TCP 端口。在这种情况下,流量将通过入口直接传递到服务。
根据您的示例,它看起来像:
chart: nginx-git/ingress-nginx
version: 3.32.0
values:
- tcp:
5672: "cust1namespace/rabbitmq:5672" # port 5672 for customer 1
5673: "cust2namespace/rabbitmq:5672" # port 5673 for customer 2
...
Rabbitmq 5672 使用相同的 TCP 端口并根据基于主机的路由将请求传输到不同的namespaces/rabbitmq_service
。
什么有效:
chart: nginx-git/ingress-nginx
version: 3.32.0
values:
- tcp:
5672: "cust1namespace/rabbitmq:5672"
块反映在 nginx.conf:
server {
preread_by_lua_block {
ngx.var.proxy_upstream_name="tcp-cust1namespace-services-rabbitmq-5672";
}
listen :5672;
proxy_pass upstream_balancer;
}
注意:这会将所有到达端口 5672 的请求转移到 cust1namespace/rabbitmq:5672
,而不管客户端域名是什么,我们希望基于域名的基于主机的路由。
期望值:
chart: nginx-git/ingress-nginx
version: 3.32.0
values:
- tcp:
cust1domainname:5672: "cust1namespace/rabbitmq:5672"
cust2domainname:5672: "cust2namespace/rabbitmq:5672"
错误:
Failed to render chart: exit status 1: Error: unable to build kubernetes objects from release manifest: error validating "": error validating data: [ValidationError(Service.spec.ports[3].port): invalid type for io.k8s.api.core.v1.ServicePort.port: got "string", expected "integer", ValidationError(Service.spec.ports[4].port): invalid type for io.k8s.api.core.v1.ServicePort.port: got "string", expected "integer"]
最后的 nginx.conf 应该是这样的:
server {
preread_by_lua_block {
ngx.var.proxy_upstream_name="tcp-cust1namespace-services-rabbitmq-5672";
}
listen cust1domainname:5672;
proxy_pass upstream_balancer;
}
server {
preread_by_lua_block {
ngx.var.proxy_upstream_name="tcp-cust2namespace-services-rabbitmq-5672";
}
listen cust2domainname:5672;
proxy_pass upstream_balancer;
}
一点理论
由于网络协议的实施以及它们之间的差异,您尝试实施的方法是不可能的。
TCP
协议在传输层工作,它有源和目标 IP 和端口,它 没有 有任何主机信息。反过来 HTTP
协议在位于 TCP
之上的应用程序层上工作,它确实有关于主机的信息,这个请求将被发送到哪里。
请熟悉OSI model and protocols which works on these levels。这将有助于避免混淆为什么这种方式有效而不是其他方式。
还有一个good answer on quora about difference between HTTP and TCP protocols。
回答
此时你有两个选择:
- 使用 ingress 在应用层工作,让它将流量引导至基于
request body
中提供的主机的服务。所有流量都应通过入口端点(通常是暴露在集群外部的负载均衡器)。
请查找带有
的示例- 使用入口处理传输层并为每个 service/customer 公开单独的 TCP 端口。在这种情况下,流量将通过入口直接传递到服务。
根据您的示例,它看起来像:
chart: nginx-git/ingress-nginx
version: 3.32.0
values:
- tcp:
5672: "cust1namespace/rabbitmq:5672" # port 5672 for customer 1
5673: "cust2namespace/rabbitmq:5672" # port 5673 for customer 2
...