从Kubernetes访问外部数据库

问题描述

我有一个带有1个服务(负载均衡器)和2个Pod的kubernetes(v1.18.6):

apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  selector:
    app: app
  ports:
  - protocol: "TCP"
    port: 6000
    targetPort: 5000
  type: LoadBalancer

访问Intenert的网络策略(对我来说是必需的):

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: internet-access
spec:
  podSelector:
    matchLabels:
      networking/allow-internet-access: "true"
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - {}

部署配置文件

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  progressDeadlineSeconds: 120
  selector:
    matchLabels:
      app: app
  replicas: 2
  template:
    metadata:
      labels:
        app: app
    spec:
      imagePullSecrets:
        - name: myregistrykey
      containers:
      - name: app
        image: app
        imagePullPolicy: Always
        ports:
        - containerPort: 5000

它正常工作。但是现在,我想将此图像连接到外部数据库(在另一个网络中,只能通过Internet访问)。为此,我使用以下服务:

apiVersion: v1
kind: Service
metadata:
  name: postgresql
spec:
  clusterIP: None
  ports:
  - port: 25060


---
apiVersion: v1
kind: Endpoints
metadata:
  name: postgresql
subsets:
  - addresses:
        - ip: 206............
    ports:
      - port: 25060
        name: postgresql

这是所有服务:

NAME                TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
app-service         LoadBalancer   10.245.134.137   206...........   6000:31726/TCP   2d4h
kubernetes          ClusterIP      10.245.0.1       <none>           443/TCP          3d7h
postgresql          ClusterIP      None             <none>           25060/TCP        19h

但是当我尝试连接时,收到数据库超时错误,例如无法连接到数据库。

图片中有Internet连接。

我找到了解决方案,问题是数据库的入站规则。我必须添加Kubernetes的IP。

谢谢。

解决方法

服务定义应更正。默认服务类型是clusterIP,不适用于外部数据库。您需要按照以下说明更新服务类型

类型:ExternalName

还确保服务名称和端点名称应该匹配。您的Yaml有所不同。请检查

,

这对我有用:

定义服务,但是设置clusterIP: None,因此不会创建endpooint。

然后使用“ SAME NAME”作为您的服务自己创建一个端点,并设置数据库的IP和端口。

在您的示例中,您的端点中有一个类型:端点的名称是postgresql而不是postgresSql。

我的例子:

---
service.yaml
kind: Service
apiVersion: v1
metadata:
  name: backend-mobile-db-service
spec:
  clusterIP: None
  ports:
  - port: 5984
---
kind: Endpoints
apiVersion: v1
metadata:
  name: backend-mobile-db-service
subsets:
  - addresses:
        - ip: 192.168.1.50
    ports:
      - port: 5984
        name: backend-mobile-db-service

,

如果我理解正确,那么您的群集中包含应用程序,并且该群集在Digital Ocean云上,而您的PostgreSQL在该群集之外。

在您的Application Deployment application service中,您使用了services with selectors,因此您无需手动创建Endpoints

在您的external database service中,您使用过services without selectors,因此必须手动创建Endpoint

由于数据库为external service,因此使用clusterIP: None是毫无意义的,因为它将尝试匹配集群中的Pod。我猜您在阅读this docs时添加了它。

最后是在Endpoint中设置的ip: 206...与应用程序服务LoadBalancer ip相同吗?

NAME                TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
app-service         LoadBalancer   10.245.134.137   206...........   6000:31726/TCP   2d4h

subsets:
  - addresses:
      - ip: 206............
    

这只是信息的一部分,所以我猜。但是,在这一部分中,您应该提供所需的database IP,而不是应用程序Loadbalancer IP。

现在可以根据情况连接:

  • 具有IP地址的群集外的数据库
  • 带有URI的远程托管数据库
  • 具有URI和端口重新映射的远程托管数据库

您可以在Kubernetes best practices: mapping external services

中找到有关上述场景的详细信息

根据您当前的配置,我假设您想使用scenario 1

如果此databasecluster位于云中,则可以使用internal Database IP。如果没有,则应提供托管该数据库的计算机的IP。

您也可以阅读Kubernetes Access External Services文章。

请让我知道更改IP后是否仍然存在问题

,

为了更好的可见性,我放置了问题中提到的答案 OP:

我找到了解决方案,问题是数据库的入站规则。我必须添加Kubernetes的IP

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...