从另一个容器访问一个容器中的MySQL

时间:2019-06-19 12:15:53

标签: docker jenkins containers devops dockerhub

我正在尝试以下操作:

  • 将MySQL 5.5旋转到一个带有暴露端口(例如4200)的容器中。
  • 将MySQL 5.7旋转到一个带有暴露端口(例如4300)的容器中。
  • 旋转golang容器以运行我的应用。

我的想法是我需要针对不同的数据库版本运行测试。

为此,我需要能够与golang容器中的每个sql容器进行对话。

我尝试过的事情:

方法1-使用--link:

MYSQL容器:

docker run --name mysql55c -p 127.0.0.1:4200:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.5

GO LANG应用程序容器

docker run -w /go/src/app -it --link mysql55c -d --name golangapp -v $(pwd):/go/src/app golang bash -c "go get github.com/go-sql-driver/mysql;go build main.go; go test -v
--config ./config.ini"

方法2-使用--net(网桥和主机): 创建网桥

  

docker network mynw

MYSQL容器:

docker run --name mysql55c --net mynw -p 127.0.0.1:4200:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.5

GO LANG应用程序容器

docker run -w /go/src/app -it --net mynw -d --name golangapp -v $(pwd):/go/src/app golang bash -c "go get github.com/go-sql-driver/mysql;go build main.go; go test -v
--config ./config.ini"

我没有建立自己的桥接网络,我也很累

  

-网络主机

我能够从主机-mysql workbench连接到sql容器。 但是,尝试连接到容器内的mysql服务器时,golangapp出现连接拒绝错误。

所有容器都在同一主机上。

我没有使用dockerfile或docker compose为:

  • 尝试使用docker cli命令完成上述操作,以便使用官方docker映像轻松实现jenkins集成。

使用配置url转到连接数据库的代码

func dbconn() (*sql.DB, error) {
    opendb, err := sql.Open("mysql", *dsn + *dbname) //coming from flag
    if err != nil {
        return nil, err
    }
    return opendb, nil
}
我在配置中尝试过的

dsn url组合:

  • dsn =“ root:root @ tcp(localhost:4200)/”
  • dsn =“ root:root @ tcp(172.17.0.0.x:4200)/”(docker0 ip)

  • dbname =“ somename”

我们如何看待以上内容? 欢迎提供有关实现我的目标的最佳做法或新方法的建议:) 需要帮忙!! 谢谢:)

2 个答案:

答案 0 :(得分:5)

这应该可行,请按照下列步骤操作:

  • 运行mysql容器docker run --name mysql55c -p 4200:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.5
  • 使用以下内容为golang创建Dockerfile
FROM golang:latest

COPY . /
RUN go get "github.com/go-sql-driver/mysql"
CMD go run /main.go
  • 使用以下内容创建main.go
package main

import(
        _ "github.com/go-sql-driver/mysql"
        "database/sql"
        "log"
)

func main() {
    // Open up our database connection.
    db, err := sql.Open("mysql", "root:root@tcp(192.168.0.33:4200)/mysql")

    // if there is an error opening the connection, handle it
    if err != nil {
        log.Print(err.Error())
    } else {
        log.Print("DB connected successfully")
    }

    defer db.Close()

}
  • 使用docker build -t goapp .
  • 构建golang容器映像
  • 运行golang容器docker run -itd goapp
  • 检查golang容器的日志:
$ docker logs dbd5294abd61
2019/06/19 13:24:17 DB connected successfully

注意::我运行了mysql容器,该容器暴露在主机的4200端口上。在golang代码中,我的连接字符串为root:root@tcp(192.168.0.33:4200)/mysql,其中192.168.0.33是我的计算机的专用ip。

您的主要收获应该是您的数据库连接字符串应指向主机的私有/公共ip。如果您在没有容器链接的情况下运行golang。

如果在运行golang时使用了容器链接 docker run -itd --link mysql55c:mydb goapp,然后您的golang代码中的mysql连接字符串应为root:root@tcp(mydb:4200)/mysql

尝试一下,让我知道。

答案 1 :(得分:1)

由于上述回答,我得以解决自己的问题。

了解docker网络基础知识并且只希望解决方案的任何人都可以完全忽略此答案。

我正在为可能只是启动docker而对docker网络不了解的任何人编写此答案。

问题::不同Docker容器之间的通信。

要在docker中的n个不同容器之间进行通信,我们首先需要了解docker网络的工作原理:

  • 每当我们在主机中安装docker时,都会创建一个docker0虚拟接口/网桥。 基本上,这是一个虚拟以太网桥,可以自动与连接到它的任何其他网络接口通信。
  • docker 0界面具有ip地址,例如172.0.0.x。
  • 此IP的后续容器子网。
  • 因此,容器之间的任何通信都可以通过docker bridge或使用主机私有IP进行。

Docker Networks

上面的图可以帮助您更好地理解它。

Docker0: 具有IP的Docker0接口。

Docker0

现在,进入命令:

使用此命令获取容器的IP:

How to get a Docker container's IP address from the host?

  

docker inspect -f'{{范围   .NetworkSettings.Networks}} {{。IPAddress}} {{end}}'container_name_or_id

SQL容器:

  

docker run --name mysql55c -p 4500:3306 -e MYSQL_ROOT_PASSWORD = root -e   MYSQL_DATABASE = db_ngen -d mysql:5.5

上面的命令创建了一个名为mysql55c的容器,其ip从docker0子网入网。

Golang容器

  

docker run -w / go / src / app -it -d --name golangapp --link mysql55c:db   -v $ {pwd):/ go / src / app golang bash

以上容器创建了一个名为golangapp的容器。

要注意的重要事项是--link命令。
此命令允许两个容器相互发现。
但是在引入docker网络功能之后,可以使用docker默认网桥网络或用户定义的网络来完成此操作。

容器Ip:

dockercontainer ips

现在,我们可以看到我们可以使用默认的docker bridge网络在容器之间进行通信了。

供参考:

覆盖网络

enter image description here

用户定义的网桥

enter image description here

默认桥接网络

enter image description here

希望以上说明对您有帮助,如果我在任何地方出错,都可以随时纠正我。

谢谢:)