Openshift 路由 AMQP 直通
Openshift route AMQP passthrough
我想创建到 RabbitMQ 的 Openshift 路由。
据我了解 https://docs.openshift.com/container-platform/3.11/architecture/networking/routes.html 上的文档,“带 SNI 的 TLS”支持应该能够检查 SNI header,然后将流量路由到适当的服务。
不幸的是,我在边缘终止和重新加密终止方面都遇到了问题。在这两种情况下,HAProxy 似乎都在检查流量并抛出错误,因为内容不是 HTTP。
通过使用 AMQP Java 库的简单 Java 应用程序,我可以看到以下流量:
javax.net.ssl|DEBUG|01|main|2021-02-26 13:35:47.001 CET|SSLSocketOutputRecord.java:331|WRITE: TLS12 application_data, length = 8
javax.net.ssl|DEBUG|01|main|2021-02-26 13:35:47.001 CET|SSLCipher.java:1770|Plaintext before ENCRYPTION (
0000: 41 4D 51 50 00 00 09 01 AMQP....
)
javax.net.ssl|DEBUG|0D|AMQP Connection 192.168.0.1:443|2021-02-26 13:35:47.044 CET|SSLSocketInputRecord.java:249|READ: TLSv1.2 application_data, length = 211
javax.net.ssl|DEBUG|0D|AMQP Connection 192.168.0.1:443|2021-02-26 13:35:47.045 CET|SSLCipher.java:1672|Plaintext after DECRYPTION (
0000: 48 54 54 50 2F 31 2E 30 20 34 30 30 20 42 61 64 HTTP/1.0 400 Bad
0010: 20 72 65 71 75 65 73 74 0D 0A 43 61 63 68 65 2D request..Cache-
0020: 43 6F 6E 74 72 6F 6C 3A 20 6E 6F 2D 63 61 63 68 Control: no-cach
0030: 65 0D 0A 43 6F 6E 6E 65 63 74 69 6F 6E 3A 20 63 e..Connection: c
0040: 6C 6F 73 65 0D 0A 43 6F 6E 74 65 6E 74 2D 54 79 lose..Content-Ty
0050: 70 65 3A 20 74 65 78 74 2F 68 74 6D 6C 0D 0A 0D pe: text/html...
0060: 0A 3C 68 74 6D 6C 3E 3C 62 6F 64 79 3E 3C 68 31 .<html><body><h1
0070: 3E 34 30 30 20 42 61 64 20 72 65 71 75 65 73 74 >400 Bad request
0080: 3C 2F 68 31 3E 0A 59 6F 75 72 20 62 72 6F 77 73 </h1>.Your brows
0090: 65 72 20 73 65 6E 74 20 61 6E 20 69 6E 76 61 6C er sent an inval
00A0: 69 64 20 72 65 71 75 65 73 74 2E 0A 3C 2F 62 6F id request..</bo
00B0: 64 79 3E 3C 2F 68 74 6D 6C 3E 0A dy></html>.
)
(输出是用
java -Djavax.net.debug=all -jar rabbitmqtest-1.0-SNAPSHOT-all.jar amqps://myroute:443 2> output.txt
)
流量没有路由到 RabbitMQ。如果我在网络浏览器中打开路由器,RabbitMQ 会收到一个连接请求(但当然无法理解,因为它是 HTTP 流量)。
Helm 路由模板是:
{{- if .Values.route.enabled }}
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: rabbitmq
spec:
host: rabbitmq-{{ .Values.route.identifier}}.{{ .Values.route.host }}
port:
targetPort: amqp-ssl
tls:
termination: reencrypt
destinationCACertificate: {{ .Values.tls.ca_crt | quote }}
to:
kind: Service
weight: 100
name: rabbitmq
status:
ingress: []
{{- end }}
有什么方法可以将路由器用作原始 TCP 代理吗?我不想使用节点端口,因为我必须在 RabbitMQ 上管理 SSL 证书(目前我已经安装了 long-lived 自签名证书)。
理论上,在这种情况下使用 Ingress Controller 应该可行,因为您将 TLS 与 SNI 结合使用。然而,它可能需要在基础设施方面进行额外的工作(向负载均衡器添加额外的端口、防火墙)。使用“标准”端口 443 将不起作用(如您所述),因为路由器需要该端口上的 HTTP 流量。
备选方案是使用 externalIP (non-cloud environments) or exposing services using loadbalancers(云环境)。
我想创建到 RabbitMQ 的 Openshift 路由。
据我了解 https://docs.openshift.com/container-platform/3.11/architecture/networking/routes.html 上的文档,“带 SNI 的 TLS”支持应该能够检查 SNI header,然后将流量路由到适当的服务。
不幸的是,我在边缘终止和重新加密终止方面都遇到了问题。在这两种情况下,HAProxy 似乎都在检查流量并抛出错误,因为内容不是 HTTP。
通过使用 AMQP Java 库的简单 Java 应用程序,我可以看到以下流量:
javax.net.ssl|DEBUG|01|main|2021-02-26 13:35:47.001 CET|SSLSocketOutputRecord.java:331|WRITE: TLS12 application_data, length = 8
javax.net.ssl|DEBUG|01|main|2021-02-26 13:35:47.001 CET|SSLCipher.java:1770|Plaintext before ENCRYPTION (
0000: 41 4D 51 50 00 00 09 01 AMQP....
)
javax.net.ssl|DEBUG|0D|AMQP Connection 192.168.0.1:443|2021-02-26 13:35:47.044 CET|SSLSocketInputRecord.java:249|READ: TLSv1.2 application_data, length = 211
javax.net.ssl|DEBUG|0D|AMQP Connection 192.168.0.1:443|2021-02-26 13:35:47.045 CET|SSLCipher.java:1672|Plaintext after DECRYPTION (
0000: 48 54 54 50 2F 31 2E 30 20 34 30 30 20 42 61 64 HTTP/1.0 400 Bad
0010: 20 72 65 71 75 65 73 74 0D 0A 43 61 63 68 65 2D request..Cache-
0020: 43 6F 6E 74 72 6F 6C 3A 20 6E 6F 2D 63 61 63 68 Control: no-cach
0030: 65 0D 0A 43 6F 6E 6E 65 63 74 69 6F 6E 3A 20 63 e..Connection: c
0040: 6C 6F 73 65 0D 0A 43 6F 6E 74 65 6E 74 2D 54 79 lose..Content-Ty
0050: 70 65 3A 20 74 65 78 74 2F 68 74 6D 6C 0D 0A 0D pe: text/html...
0060: 0A 3C 68 74 6D 6C 3E 3C 62 6F 64 79 3E 3C 68 31 .<html><body><h1
0070: 3E 34 30 30 20 42 61 64 20 72 65 71 75 65 73 74 >400 Bad request
0080: 3C 2F 68 31 3E 0A 59 6F 75 72 20 62 72 6F 77 73 </h1>.Your brows
0090: 65 72 20 73 65 6E 74 20 61 6E 20 69 6E 76 61 6C er sent an inval
00A0: 69 64 20 72 65 71 75 65 73 74 2E 0A 3C 2F 62 6F id request..</bo
00B0: 64 79 3E 3C 2F 68 74 6D 6C 3E 0A dy></html>.
)
(输出是用
java -Djavax.net.debug=all -jar rabbitmqtest-1.0-SNAPSHOT-all.jar amqps://myroute:443 2> output.txt
)
流量没有路由到 RabbitMQ。如果我在网络浏览器中打开路由器,RabbitMQ 会收到一个连接请求(但当然无法理解,因为它是 HTTP 流量)。
Helm 路由模板是:
{{- if .Values.route.enabled }}
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: rabbitmq
spec:
host: rabbitmq-{{ .Values.route.identifier}}.{{ .Values.route.host }}
port:
targetPort: amqp-ssl
tls:
termination: reencrypt
destinationCACertificate: {{ .Values.tls.ca_crt | quote }}
to:
kind: Service
weight: 100
name: rabbitmq
status:
ingress: []
{{- end }}
有什么方法可以将路由器用作原始 TCP 代理吗?我不想使用节点端口,因为我必须在 RabbitMQ 上管理 SSL 证书(目前我已经安装了 long-lived 自签名证书)。
理论上,在这种情况下使用 Ingress Controller 应该可行,因为您将 TLS 与 SNI 结合使用。然而,它可能需要在基础设施方面进行额外的工作(向负载均衡器添加额外的端口、防火墙)。使用“标准”端口 443 将不起作用(如您所述),因为路由器需要该端口上的 HTTP 流量。
备选方案是使用 externalIP (non-cloud environments) or exposing services using loadbalancers(云环境)。