从 minikube 集群内部连接到本地数据库
Connect to local database from inside minikube cluster
我正在尝试从 minikube pod 中访问本地主机上 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 中卷曲地址 "mysql-db-svc",它无法解析主机名。
任何人都可以请教一个沮丧的新手吗?
这是因为您的服务类型是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
如果我没记错的话,您还应该为此服务创建一个端点,因为它是外部服务。
在您的情况下,端点定义应如下所示:
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 文档上阅读有关外部资源的信息。
我将 ubuntu 与 Minikube 一起使用,我的数据库在 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"
希望这是有道理的。
以上解决方案对我不起作用。最后它在 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 pods 的主机 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'
(例如,g "192.168.65.2"
)的原始 IP 地址可以直接用作服务主机,而不是 127.0.0.1/localhost
代码。不再需要以上配置。
我也遇到了类似的问题,我需要将 minikube 中的 POD 与机器上的 SQL 服务器容器连接起来。
我注意到 minikube 本身就是本地 docker 环境中的一个容器,在它的设置过程中它会创建一个本地 docker 网络 minikube
。我使用 docker network connect minikube <SQL Server Container Name> --ip=<any valid IP on the minikube network subent>
.
将本地 SQL 服务器容器连接到此 minikube
docker 网络
我现在可以使用 minikube
网络上的 IP 地址访问本地 SQL 服务器容器。
作为@Crou 的插件 from 2018, In 2022, kubernetes docs say ExternalName takes in a string
and not an address. So, in case ExternalName
doesn't work, you can also use the simpler option of services-without-selectors
您还可以参考此 Google 云技术 video 了解此 services-without-selectors
概念的工作原理
我正在尝试从 minikube pod 中访问本地主机上 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 中卷曲地址 "mysql-db-svc",它无法解析主机名。
任何人都可以请教一个沮丧的新手吗?
这是因为您的服务类型是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
如果我没记错的话,您还应该为此服务创建一个端点,因为它是外部服务。
在您的情况下,端点定义应如下所示:
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 文档上阅读有关外部资源的信息。
我将 ubuntu 与 Minikube 一起使用,我的数据库在 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"
希望这是有道理的。
以上解决方案对我不起作用。最后它在 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 pods 的主机 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'
(例如,g "192.168.65.2"
)的原始 IP 地址可以直接用作服务主机,而不是 127.0.0.1/localhost
代码。不再需要以上配置。
我也遇到了类似的问题,我需要将 minikube 中的 POD 与机器上的 SQL 服务器容器连接起来。
我注意到 minikube 本身就是本地 docker 环境中的一个容器,在它的设置过程中它会创建一个本地 docker 网络 minikube
。我使用 docker network connect minikube <SQL Server Container Name> --ip=<any valid IP on the minikube network subent>
.
minikube
docker 网络
我现在可以使用 minikube
网络上的 IP 地址访问本地 SQL 服务器容器。
作为@Crou 的插件string
and not an address. So, in case ExternalName
doesn't work, you can also use the simpler option of services-without-selectors
您还可以参考此 Google 云技术 video 了解此 services-without-selectors
概念的工作原理