【问题标题】:Connect to local database from inside minikube cluster从 minikube 集群内部连接到本地数据库
【发布时间】:2018-11-29 19:47:12
【问题描述】:

我正在尝试从 minikube pod 内部访问托管在 localhost 上的 docker 容器中的 MySQL 数据库,但收效甚微。我尝试了Minikube expose MySQL running on localhost as service 描述的解决方案,但没有效果。我已经根据我们在 AWS 上使用的服务对我的解决方案进行了建模,但它似乎不适用于 minikube。我的服务内容如下

apiVersion: v1

kind: Service

metadata: 

  name: mysql-db-svc

  namespace: external

spec: 
  type: ExternalName
  ExternalName: 172.17.0.2

...我尝试使用端口 3306 上的“mysql-db-svc”从 pod 内部连接到我的数据库,但无济于事。如果我尝试从 pod 中 CURL 地址“mysql-db-svc”,它无法解析主机名。

任何人都可以请一个沮丧的新手建议吗?

【问题讨论】:

    标签: kubernetes minikube


    【解决方案1】:

    我正在使用带有 Minikube 的 ubuntu,并且我的数据库在 docker 容器内的 minikube 之外运行,并且可以从 localhost @ 172.17.0.2 访问。我的外部 mysql 容器的 Kubernetes 服务如下所示:

    kind: Service
    apiVersion: v1
    metadata:
      name: mysql-db-svc
      namespace: external
    spec: 
      type: ExternalName
      externalName: 10.0.2.2
    

    然后在我的 .env 项目中,我的 DB_HOST 被定义为

    mysql-db-svc.external.svc
    

    ...服务名称“mysql-db-svc”后跟其命名空间“external”和“svc”

    希望这是有道理的。

    【讨论】:

    • 您能否提供更多有关您如何使用它的详细信息?
    • 谢谢!但这并没有帮助,我在 Mac 上并且在本地部署了 mysql。我想从运行在 Minikube 上的 Spring Boot 应用程序访问它。
    • @prime 这令人印象深刻,但是您是如何找出神奇的 externalName 的呢? 10.0.2.2从哪里来?
    • 没关系,这解释了它:stackoverflow.com/a/34732276/1035008
    • 运行mysql的端口怎么样。
    【解决方案2】:

    如果我没记错的话,您还应该为此服务创建一个端点,因为它是外部的。

    在您的情况下,端点定义应如下所示:

    kind: "Endpoints"
    apiVersion: "v1"
    metadata:
      name: mysql-db-svc
      namespace: external
    subsets: 
    - addresses:
      - ip: "10.10.1.1"
      ports:
        port: 3306
    

    您可以在 Kubernetes Defining a service docs 上阅读外部资源。

    【讨论】:

    • 在 2022 年,kubernetes 文档说 ExternalName 接受 string 而不是地址。所以,万一ExternalName不起作用,你也可以使用services-without-selectors这个更简单的选项
    【解决方案3】:

    这是因为您的服务类型是 ExternalName,它只适用于 AWS 和 GKE 等云环境。要在本地运行您的服务,请将服务类型更改为NodePort,这将分配一个介于 30000-32767 之间的静态 NodePort。如果您需要自己分配静态端口,以便 minikube 不会为您选择随机端口,请在端口部分下的服务定义中定义该端口,例如 nodePort: 32002。

    而且我在您的服务定义中没有看到任何指向您的 MySQL 部署的选择器。因此,在spec 部分下的服务定义中包含相应的选择器密钥对(例如app: mysql-server)。该选择器应与您在 MySQL 部署定义中定义的选择器匹配。

    所以你的服务定义应该是这样的:

    kind: Service
    apiVersion: v1
    metadata:
      name: mysql-db-svc
      namespace: external
    spec:
      selector:
        app: mysql-server
      ports:
      - protocol: TCP
        port: 3306
        targetPort: 3306
        nodePort: 32002
      type: NodePort
    

    部署服务后,您可以通过 http://{minikube ip}:32002 访问 MySQL 服务,将 {minikube ip} 替换为实际的 minikube ip。

    否则您可以使用以下命令获取服务的访问 URL

    minikube service <SERVICE_NAME> --url
    

    将 替换为服务的实际名称。你的情况是mysql-db-svc

    【讨论】:

    • 感谢您的反馈,非常感谢。但是 mysql 实例不在集群内部,它在 minikube 外部。
    【解决方案4】:

    我也遇到了类似的问题,我需要将 minikube 内的 POD 与机器上的 SQL Server 容器连接起来。

    我注意到 minikube 本身就是本地 docker 环境中的一个容器,并且在设置期间它会创建一个本地 docker 网络 minikube。我使用 docker network connect minikube &lt;SQL Server Container Name&gt; --ip=&lt;any valid IP on the minikube network subent&gt; 将我的本地 SQL Server 容器连接到这个 minikube docker 网络。

    我现在可以使用minikube 网络上的 IP 地址访问本地 SQL Server 容器。

    【讨论】:

      【解决方案5】:

      以上解决方案不知何故对我不起作用。最后它在 terraform 中运行

      resource "kubernetes_service" "host" {
          metadata {
              name = "minikube-host"
      
              labels = {
                  app = "minikube-host"
              }
      
              namespace = "default"
          }
      
          spec {
              port {
                  name = "app"
                  port = 8082
              }
              cluster_ip = "None"
          }
      }
      
      resource "kubernetes_endpoints" "host" {
          metadata {
              name = "minikube-host"
              namespace = "default"
          }
          subset {
              address {
                  // This ip comes from command: minikube ssh 'grep host.minikube.internal /etc/hosts | cut -f1'
                  ip = "192.168.65.2"
              }
      
              port {
                  name     = "app"
                  port     = 8082
              }
          }
      }
      

      然后我可以通过 k8s pod 使用主机 minikube-host.default.svc.cluster.local 在我的 mac 中访问本地服务(例如 postgres 或 mysql)。

      可以在issue 找到纯 yaml 文件版本和更多详细信息。

      minikube主机访问host.minikube.internal详情可以be found here。

      另一方面,来自命令minikube ssh 'grep host.minikube.internal /etc/hosts | cut -f1'(例如"192.168.65.2")的原始IP地址可以直接用作服务主机,而不是代码中的127.0.0.1/localhost。并且不需要以上配置。

      【讨论】:

        【解决方案6】:

        作为 2018 年以来 @Crou 的 answer 的插件,2022 年,kubernetes 文档说 ExternalName 接受 string 而不是地址。所以,万一ExternalName不起作用,你也可以使用services-without-selectors这个更简单的选项

        您还可以参考此 Google Cloud Tech video,了解此 services-without-selectors 概念的工作原理

        【讨论】:

          猜你喜欢
          • 2021-09-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-05-10
          • 2020-12-14
          • 2020-08-10
          • 2020-08-15
          • 2022-06-15
          相关资源
          最近更新 更多