在没有选择器的情况下访问包装在服务中的外部数据库资源

时间:2019-07-03 13:04:27

标签: postgresql kubernetes google-cloud-platform

我在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

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

第三步,我创建了一个带有'partlab / ubuntu-postgresql'docker-image的容器。我做了一个'kctrl exec -it ...',并且可以使用

访问我的Postgres数据库。
psql -h postgres-bla-bla ...

所以基本上可以。但是我确信我的解决方案存在一些缺陷。 我能做得更好吗?如何解决问题2中的问题?

2 个答案:

答案 0 :(得分:3)

here中讨论了该问题,并且有一种解决方案,可以通过在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

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

答案 1 :(得分:0)

虽然可以使用service without selectors访问集群中的服务,但可能适合您特定情况的另一种方法是使用ExternalName Service

  

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

另外,考虑到您正在GCP上使用Cloud SQL,一种更可靠的连接数据库而无需将节点IP地址列入白名单的方法将使用Cloud SQL proxy

  

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

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

如前所述,执行Pod的Shell会话可以使您访问PostgreSQL服务,因为Pod在集群网络中并且可以与服务通信。 您可以使用任何Kubernetes service exposing method 公开数据库服务,然后使用本地客户端访问公开的服务,以便将通信中继到您的数据库。