我正在Hetzner Cloud上创建一个Kubernetes集群,其配置与我在Azure AKS上使用的配置相同,但我面临着与Neo4j的连接问题。在Hetzner集群上,虽然我可以从我在Ingress中定义的路径访问Neo4J浏览器,但我无法使用bolt+s连接server.mydomain.com:7687 URL连接到Neo4j服务器,我的Node.js服务器pod中的Neo4j驱动程序也无法连接到Neo4j服务器(第二个连接有点解决,请参阅最后的更新)。AKS集群的情况并非如此。
从Neo4j浏览器debbug连接中,我看到握手失败:
Browser will attempt to open a websocket connection to bolt+s://server.mydomain.com:7687 and do an encrypted and an unencrypted bolt handshake.
bolt handshake
Status:
Error
encrypted bolt handshake
Status:
Error
从Chrome控制台,我看到2个错误:
Mixed Content: The page at 'https://server.mydomain.com/neo4j/browser/' was loaded over HTTPS, but requested an insecure resource 'http://server.mydomain.com:7687/'. This request has been blocked; the content must be served over HTTPS.
WebSocket connection to 'wss://server.mydomain.com:7687/' failed:
两个集群之间的一个区别是ingress控制器的负载均衡器配置,在Hetzner上,我在ingress-nginx Helm图表中设置了注解如下:
nginx:
controller:
watchIngressWithoutClass: true
kind: DaemonSet
config:
use-forwarded-headers: "true"
compute-full-forwarded-for: "true"
use-proxy-protocol: "true"
service:
annotations:
load-balancer.hetzner.cloud/name: server-lb
load-balancer.hetzner.cloud/use-private-ip: "true"
load-balancer.hetzner.cloud/disable-private-ingress: "true"
load-balancer.hetzner.cloud/location: fsn1
load-balancer.hetzner.cloud/type: lb11
load-balancer.hetzner.cloud/uses-proxyprotocol: "true"
load-balancer.hetzner.cloud/http-redirect-https: "true"
load-balancer.hetzner.cloud/hostname: server.mydomain.com
# nginx.ingress.kubernetes.io/websocket-services: neo4j
extraArgs:
default-ssl-certificate: "default/tls-secret"
# nodeSelector:
# server-type: server
tcp:
7687: "default/neo4j:7687"
7474: "default/neo4j:7474"
AFAIK ingress-nginx
控制器(我正在使用)自动处理WebSockets,不像nginx-ingress
,它应该使用nginx.ingress.kubernetes.io/websocket-services: neo4j
这样的注解Map到服务,我尝试使用注解,但没有什么区别。
我对Hetzner集群使用的完整过程是:我使用k3 s v1.27.4+ k3 s1在Hetzner Cloud上创建了一个Kubernetes单节点集群,安装了ingress-nginx v4.7.1,将TCP端口7474和7687暴露给Neo4j服务,如您在上面看到的(负载均衡器TCP端口暴露且健康)和Cert-manager v1.12.3 Helm charts。
在我的域DNS管理器中,我创建了一个指向负载均衡器IPv4的A记录,主机设置为sever
,以便在我的Certificate
和Ingress
清单中使用它作为server.mydomain.com
。正确创建tls-secret
。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-service
annotations:
nginx.ingress.kubernetes.io/use-regex: 'true'
nginx.ingress.kubernetes.io/rewrite-target: /$2$3$4
ingress.kubernetes.io/ssl-redirect: 'true'
nginx.ingress.kubernetes/cluster-issuer: letsencrypt-issuer
spec:
ingressClassName: nginx
tls:
- hosts:
- server.mydomain.com
secretName: tls-secret
rules:
### Node.js server
- http:
paths:
- path: /(/|$)(.*)
# pathType: Prefix
pathType: ImplementationSpecific
backend:
service:
name: server-clusterip-service
port:
number: 80
- http:
paths:
- path: /server(/|$)(.*)
# pathType: Prefix
pathType: ImplementationSpecific
backend:
service:
name: server-clusterip-service
port:
number: 80
##### Neo4j
- http:
paths:
- path: /bolt(/|$)(.*)
# pathType: Prefix
pathType: ImplementationSpecific
backend:
service:
name: neo4j
port:
number: 7687
- http:
paths:
# show browser
- path: /neo4j(/|$)(.*)
# pathType: Prefix
pathType: ImplementationSpecific
backend:
service:
name: neo4j
port:
number: 7474
- http:
paths:
- path: /neo4j-admin(/|$)(.*)
# pathType: Prefix
pathType: ImplementationSpecific
backend:
service:
name: neo4j-admin
port:
number: 7474
为了安装Neo4j chart,我为Neo4j配置设置了以下值:
config:
server.bolt.enabled: 'true'
server.bolt.tls_level: 'REQUIRED'
server.bolt.listen_address: '0.0.0.0:7687'
dbms.ssl.policy.bolt.client_auth: 'NONE'
dbms.ssl.policy.bolt.enabled: 'true'
# dbms.connector.bolt.advertised_address: '0.0.0.0:7687' #server.mydomain.com:7687 # new for hetzner (no connection still)
## apoc
server.directories.plugins: '/var/lib/neo4j/labs'
dbms.security.procedures.unrestricted: 'apoc.*'
server.config.strict_validation.enabled: 'false'
dbms.security.procedures.allowlist: 'gds.*,apoc.*'
### apoc config
dbms.directories.plugins: "/var/lib/neo4j/labs"
dbms.config.strict_validation: "false"
apoc_config:
apoc.trigger.enabled: "true"
apoc.jdbc.neo4j.url: "jdbc:foo:bar"
apoc.import.file.enabled: "true"
startupProbe:
failureThreshold: 1000
periodSeconds: 50
ssl:
# setting per "connector" matching neo4j config
bolt:
privateKey:
secretName: tls-secret
subPath: tls.key
publicCertificate:
secretName: tls-secret
subPath: tls.crt
trustedCerts:
sources: []
revokedCerts:
sources: []
我尝试使用任何IP 0.0.0.0:7687
值和特定的dns server.mydomain.com:7687
值来设置dbms.connector.bolt.advertised_address
(Azure上的dough未设置),但这也没有什么区别。在Hetzner防火墙规则中,我为端口80(http)和443(https)创建了规则,以允许端口7474和7687。我也尝试禁用防火墙作为测试,但仍然无法达到Neo4j服务器。你能发现一些其他的配置,我需要添加或更改此设置?非常感谢
更新
我注意到Azure上的nginx-ingress-controller External IP实际上显示了来自负载均衡器的IPv4地址,而在Hetzner上它显示了DNS名称server.mydomain.com
,所以我从ingress-nginx
服务注解 Helm 图表中删除了load-balancer.hetzner.cloud/hostname: server.mydomain.com
注解,没有它,我的Node.js服务器Pod中的Neo4j驱动程序成功连接到Neo4j。
不幸的是,我在网络浏览器中从Neo4j Browser应用程序连接时仍然会遇到两个错误:
Mixed Content: The page at 'https://server.mydomain.com/neo4j/browser/' was loaded over HTTPS, but requested an insecure resource 'http://server.mydomain.com:7687/'. This request has been blocked; the content must be served over HTTPS.
WebSocket connection to 'wss://server.mydomain.com:7687/' failed:
更新二
我重新开始,在颁发Let'sEncrypt证书时,如果我不使用注解load-balancer.hetzner.cloud/hostname: server.mydomain.com
,证书颁发会挂起,而它会按预期完成。
我完全在这里兜圈子。
1条答案
按热度按时间dkqlctbz1#
我联系了Neo4j团队,显然这个问题可能与Hetzner网络或他们的负载均衡器有关,所以我的实现在Azure上工作时将2个tcp端口暴露给neo4j默认服务(如下所述),在Hetzner上不起作用。
还有其他选项,例如可以配置为支持TCP连接的nginx-ingress控制器,但在本指南中,我们将尽可能简单地使用标准Kubernetes资源类型。
现在,我最终使用的解决方案是首选的Neo4j方式,即使用专用的LoadBalancer服务,并使用注解,就像我在ingress-nginx图表中所做的那样,我创建了另一个Hetzner负载均衡器,这意味着为它创建第二个tls证书颁发,当然是一个更昂贵的解决方案。
服务类型:LoadBalancer是Neo4j唯一合适的选项。无法使用Ingress,因为Neo4j的驱动程序协议在TCP级别进行通信,而大多数Ingress仅支持HTTP通信。节点端口服务不能与静态IP地址相关联,这使得设置DNS和SSL非常困难。使用NodePort可能会给一些Neo4j应用程序带来配置挑战,这些应用程序希望使用端口7687专门与Neo4j通信。因此,我们建议只使用LoadBalancer服务。
当Neo4j在Ingress后面时,他们正在努力使其无缝工作,其中之一是使用类似Haproxy的东西,他们正在创建Helm Chart,但现在他们只是评估各种方法。目前还没有定论。