Доступ к MySQL в одном контейнере из другого контейнера - PullRequest
1 голос
/ 19 июня 2019

Я пытаюсь сделать следующее:

  • вращать MySQL 5.5 в одном контейнере с незащищенным портом, скажем, 4200.
  • вращать MySQL 5.7 в одном контейнерес открытым портом, скажем, 4300.
  • вращать контейнер golang для запуска моего приложения.

Идея в том, что мне нужны мои тесты для запуска на разных версиях базы данных.

Для этого мне нужно иметь возможность общаться с каждым из контейнеров sql из моего контейнера golang.

Что я пробовал:

Метод 1- Использование --link:

MYSQL CONTAINER:

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

GO LANG APP CONTAINER

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 (мостовая сеть и хост): Создать мост nw

docker network mynw

MYSQL CONTAINER:

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

GO LANG APP CONTAINER

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"

Вместо создания собственной сети мостов я такжеустал

- чистый хост

Я могу подключиться к контейнерам sql с хоста - mysql workbench.Но golangapp получает ошибку «Отказано в соединении» при попытке подключения к серверам mysql внутри контейнеров.

Все контейнеры находятся на одном хосте.

Я не используюdockerfile или docker составляют:

  • , пытаясь выполнить вышеизложенное с помощью команд docker cli для простой интеграции jenkins с использованием официальных образов docker.

Перейти код для подключения к БД с помощью config 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 комбинации, которые я попробовал в config:

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

  • dbname = "somename"

Как мы можем смотреть на вышесказанное?Предложения о лучших методах или новых методах для достижения моей цели приветствуются :) Нужна помощь!Спасибо:)

Ответы [ 2 ]

5 голосов
/ 19 июня 2019

Это должно работать, выполните следующие действия:

  • Запустить MySQL контейнер docker run --name mysql55c -p 4200:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.5
  • Создать 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()

}
  • Создание изображения контейнера golang с использованием docker build -t goapp .
  • Запустить контейнер Голанг 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 тогда строка подключения mysql в вашем коде golang должна быть root:root@tcp(mydb:4200)/mysql

Попробуйте и дайте мне знать.

1 голос
/ 24 июня 2019

Благодаря приведенным выше ответам мне удалось решить мою проблему.

Любой, кто разбирается в основах докерских сетей и просто хочет, чтобы решение могло полностью проигнорировать этот ответ.

Я пишу этот ответ для тех, кто, возможно, только начинает докер и не имеет четкого понимания сетей докеров.

Проблема: Связь между различными докерамиконтейнеры.

Чтобы установить связь между n различными контейнерами в Docker, нам нужно сначала понять, как работает сеть Docker:

  • Всякий раз, когда мы устанавливаем Docker на наш хост, виртуальный интерфейс / мост docker0 являетсясоздано.По сути, это мост Virtual Ethernet, который автоматически связывается с любыми другими сетевыми интерфейсами, подключенными к нему.
  • Интерфейс Docker 0 имеет IP-адрес, скажем, 172.0.0.x.
  • Последующие подсети контейнеров с этого IP-адреса.
  • Поэтому любая связь между контейнерами может происходить либо через докерский мост, либо с использованием частного IP-адреса хоста.

Docker Networks

Приведенная выше диаграмма может помочь вам лучше понять ее.

Docker0: Интерфейс Docker0 с IP.

Docker0

Теперь, чтобы войти в команды:

Используйте эту команду для получения IP-адреса контейнера:

Как получить IP-адрес контейнера Docker от хоста?

docker inspect -f '{{range .NetworkSettings.Networks}} {{. IPAddress}} {{end}} 'container_name_or_id

SQL-контейнер:

запуск Docker --name mysql55c -p 4500: 3306 -e MYSQL_ROOT_PASSWORD = root -e MYSQL_DATABASE = db_ngen -d mysql: 5.5

Приведенная выше команда создает контейнер с именем mysql55c с подключением по ip из netcker0.

Контейнер Golang

Docker run -w / go / src / app -it -d - имя golangapp --link mysql55c: db -v $ (pwd): / go / src / app golang bash

Приведенный выше контейнер создает контейнер с именем golangapp.

Важная вещь, которую необходимо соблюдать, - это команда --link.
ЭтоКоманда позволяла обоим контейнерам обнаруживать друг друга.
Но после того, как была введена функция Docker Network, это можно сделать с помощью сети моста Docker по умолчанию или пользовательских сетей.

Ip контейнера:

dockercontainer ips

Теперь мы можем видеть, что мы можем связываться между контейнерами, используястандартная сеть Docker Bridge.

Для справки:

Оверлейная сеть

enter image description here

Определяемый пользователем мост

enter image description here

Мостовая сеть по умолчанию

enter image description here

Надеюсь, что вышесказанное поможет, не стесняйтесь поправлять меня, если я где-то ошибаюсь.

Спасибо:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...