Neo4j 集群的外部暴露

本章介绍如何将来自外部世界或互联网的流量路由到在 Kubernetes 上运行的 4.3.0 或更高版本上的 Neo4j 集群。

如果您运行的是早于 4.3.0 的 Neo4j 版本,则这些说明不适用。查看 客户端路由的外部暴露说明

概述

默认情况下,当您使用 Neo4j Labs Helm 图表安装 Neo4j 时,创建的任何服务都无法从 Kubernetes 集群外部访问。要从 Kubernetes 集群外部访问 Neo4j,我们需要一个外部有效的 DNS 名称或 IP 地址,客户端可以连接到该地址。该外部地址需要将查询定向到 Kubernetes LoadBalancer 服务,该服务在 Neo4j 内核上进行负载均衡。

具有 type: LoadBalancer 的服务是 Neo4j 唯一合适的选项。无法使用 Ingress,因为 Neo4j 的驱动程序协议在 TCP 级别进行通信,而大多数 Ingress 仅支持 HTTP 通信。NodePort 服务无法与静态 IP 地址关联,这使得设置 DNS 和 SSL 非常困难。使用 NodePort 还会为某些期望使用端口 7687 与 Neo4j 通信的 Neo4j 应用程序创建配置挑战。因此,我们建议只使用 LoadBalancer 服务。

创建用于入站集群流量的静态 IP 地址

我正在使用 GCP,因此它是这样完成的。这里的重要说明是,在 GCP 上,区域必须与您的 GKE 区域匹配,并且网络层级必须是高级。在其他云上,这里概念性的步骤相同,但细节会有所不同:您只需为整个 Neo4j 集群分配 1 个静态 IP 地址。

# Customize these next 2 for the region of your GKE cluster,
# and your GCP project ID
REGION=us-central1
PROJECT=my-gcp-project-id

gcloud compute addresses create \
  neo4j-static-ip --project=$PROJECT \
  --network-tier=PREMIUM --region=$REGION

echo "IP:"
gcloud compute addresses describe neo4j-static-ip \
  --region=$REGION --project=$PROJECT --format=json | jq -r '.address'

如果您正在使用 Azure,请注意,静态 IP 地址必须与您的 Kubernetes 集群位于同一资源组中,并且可以使用 az network public-ip create 创建,如下所示(仅一个示例):az network public-ip create -g resource_group_name -n core01 --sku standard --dns-name neo4jcluster --allocation-method Static。使用的 Azure SKU 必须是标准 SKU,您需要的资源组可以在 Kubernetes Load Balancer 中找到,该负载均衡器通过 [按照 Azure 教程](https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough) 为您设置。

在本教程的其余部分,让我们假设我分配的内核 IP 地址如下

export IP=35.202.123.82

安装 Helm 图表

从此仓库的根目录,导航到 stable/neo4j,并执行此命令以安装具有部署名称“graph”的 Helm 图表。

export DEPLOYMENT=graph
helm install $DEPLOYMENT . \
  --set core.numberOfServers=3 \
  --set acceptLicenseAgreement=yes \
  --set neo4jPassword=mySecretPassword

外部暴露

几分钟后,您将拥有一个完全形成的集群,其 pod 显示为就绪状态,您可以从 Kubernetes 内部连接到该集群,**但是**它仍然无法从 Kubernetes 集群外部访问。因此,我们接下来需要做的是创建一个负载均衡器,并将 loadBalancerIP 设置为我们在之前步骤中保留的静态 IP 地址。

load-balancer.yaml 文件已提供作为模板,以下是如何为给定的静态 IP 地址创建一个文件

export DEPLOYMENT=graph

# Reuse IP from the earlier step here.
# These *must be IP addresses* and not hostnames, because we're
# assigning load balancer IP addresses to bind to.

echo $DEPLOYMENT with IP $IP ;
cat tools/external-exposure/load-balancer.yaml | envsubst | kubectl apply -f -

在这些服务内部,我们使用 externalTrafficPolicy: Local。为了避免在 Kubernetes 内部添加来自额外网络跳跃的额外延迟。有关此主题的更多信息,请参阅 Kubernetes 文档

还有其他选项,例如 nginx-ingress 控制器,可以将其配置为支持 TCP 连接,但本指南旨在提供尽可能简单的操作方法,您可以使用标准的 Kubernetes 资源类型来完成这些操作。

潜在的绊脚石:在 GKE 上,将静态 IP 与负载均衡器关联所需的唯一操作是在 YAML 中添加此 loadBalancerIP 字段。在其他云上,可能需要额外的步骤才能将静态 IP 分配到 Kubernetes 集群。请查阅您的本地云文档。

将所有内容整合在一起

我们可以像这样验证我们的服务是否正常运行

$ kubectl get service | grep neo4j-external
zeke-neo4j-external   LoadBalancer   10.0.5.183   35.202.123.82     7687:30529/TCP,74.3.140843/TCP,7473:30325/TCP   115s

完成所有这些步骤后,您应该最终拥有一个正确暴露的集群。我们可以像这样恢复我们的密码,并连接到静态 IP。

export NEO4J_PASSWORD=$(kubectl get secrets graph-neo4j-secrets -o yaml | grep password | sed 's/.*: //' | base64 -d)
cypher-shell -a neo4j://34.66.183.174:7687 -u neo4j -p "$NEO4J_PASSWORD"

此外,由于我们公开了端口 7474,因此您可以访问任何静态 IP 上的端口 7474,最终将使用 Neo4j 浏览器,并能够连接。

安全:这些方法在没有加密的情况下发送您的 Neo4j 凭据。要保护与 Neo4j 的通信,您还必须设置 SSL。

接下来去哪里

  • 如果您有静态 IP,那么您当然可以将 DNS 与它们关联起来

  • 设置好 DNS 后,您可以获取签名的 SSL 证书。SSL 证书可直接用于 Neo4j(请参阅 Neo4j 操作手册的 SSL 框架 部分)。或者,在许多情况下,SSL 证书也可以注册到负载均衡器。

  • 这反过来将允许您使用 https 和 neo4j+s 协议与 Neo4j 通信。