无需选择器即可访问包装在服务中的外部数据库资源

Tho*_*hen 7 postgresql google-cloud-platform kubernetes

我在 Google Cloud 中创建了一个托管 Postgres 数据库。该数据库获得了外部 IP 地址。第二步,我创建了一个 Kubernetes 集群。在 k8s 中,我想访问这个外部数据库。因此,我创建了一个没有标签选择器的服务,但有一个指向我的 Postgres 数据库的外部端点。

我必须允许 Postgres 数据库从(三个)集群节点访问。我在 Google Cloud Console (SQL) 中进行了配置。

我的第一个问题:这是集成外部数据库的正确方法吗?特别是这个IP访问配置?

为了测试我对数据库的连接,我的第一次尝试是从本地主机建立端口转发。我的想法是通过我的 Database-IDE(datagrip)访问这个数据库。但是,当尝试建立端口转发时,出现以下错误:

error: cannot attach to *v1.Service: invalid service 'postgres-bla-bla': Service is defined without a selector
Run Code Online (Sandbox Code Playgroud)

第二个问题:如何在本地访问该服务?

在第三步中,我使用 'partlab/ubuntu-postgresql' docker-image 创建了一个 pod。我做了一个 'kctrl exec -it ... ' 并且可以访问我的 Postgres 数据库

psql -h postgres-bla-bla ...
Run Code Online (Sandbox Code Playgroud)

所以基本上它有效。但我确信我的解决方案有一些缺陷。我可以做什么更好?如何解决问题 2 中的问题?

Ald*_*ein 7

这里讨论了这个问题,有一个解决方案可以通过在 K8s 内部署代理 pod 来设置端口转发到没有选择器/pod 的服务(例如 ExternalName 服务):

kubectl -n production run mysql-tunnel-$USER -it --image=alpine/socat --tty --rm --expose=true --port=3306 tcp-listen:3306,fork,reuseaddr tcp-connect:your-internal-mysql-server:3306
kubectl -n production port-forward svc/mysql-tunnel-$USER 3310:3306
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,MySQL 服务器your-internal-mysql-server:3306localhost:3310在您的计算机上可用。


yyy*_*hir 5

虽然使用不带选择器的服务来访问集群内的服务是可以的,但可能适合您的特定场景的替代方法是使用ExternalName Service

ExternalName 类型的服务将服务映射到 DNS 名称,而不是典型的选择器,例如 my-service 或 cassandra

此外,考虑到您在 GCP 上使用 Cloud SQL,无需将节点 IP 地址列入白名单即可连接到数据库的更可靠方法是使用Cloud SQL 代理

Cloud SQL 代理提供对 Cloud SQL 第二代实例的安全访问,无需将 IP 地址列入白名单或配置 SSL。

关于第二个问题,由于当前连接到数据库的服务仅存在于集群中,因此您需要访问集群网络,以便能够访问映射到其中的任何外部端点。

正如您所提到的,执行 pod 的 shell 会话允许您访问 PostgreSQL 服务,因为 pod 位于集群网络内并且可以与该服务通信。您可以使用任何Kubernetes 服务公开方法公开数据库服务,然后使用本地客户端访问公开的服务,以便它将通信中继到您的数据库。