Невозможно подключить мое приложение к службе MySql в сети Docker composer

0

Обновлено: см. Ниже

Я новичок в Docker и пытаюсь создать веб-API.NET Core 2.0 на хосте Ubuntu 18, используя Docker 18.05.0-ce (build f150324) и эти службы, все в одной сети:

  1. База данных SQL Server;
  2. База данных MySql (https://github.com/docker-library/docs/tree/master/mysql/);
  3. Монго.

Мой файл компоновки докеров предоставляет эти службы из соответствующих изображений, как сообщается ниже. Короче:

  • SQL Server из образа microsoft/mssql-server-linux, порт 1433, sa пароль пользователя устанавливается с помощью переменного окружения SA_PASSWORD после принятия лицензионного соглашения через ACCEPT_EULA;
  • MongoDB из изображения mongo, порт 27017;
  • MySql из образа mysql/mysql-server, порт 3306, пароль для пользователя root установленного через переменную среды MYSQL_ROOT_PASSWORD. Я по существу использовал эти источники для настройки службы: https://github.com/docker-library/docs/tree/master/mysql#mysql_database и https://docs.docker.com/samples/library/mysql/#environment -переменные.

Конечно, веб-API, получающий доступ к этим службам, использует другие учетные данные в своей среде разработки, но я переопределяю их через переменные среды, чтобы настроить систему на Docker (в ASPNET Core 2, как вы можете видеть на https://github.com/aspnet/MetaPackages/blob/dev/src/Microsoft.AspNetCore/WebHost.cs, метод CreateDefaultBuilder уже включает переменные среды в качестве источника конфигурации):

  • DATA__DEFAULTCONNECTION__CONNECTIONSTRING: строка подключения к серверу Sql с использованием SA с тем же паролем, установленным для службы Docker (см. Выше): "Server=sqlserver\\sqlexpress,1433;Database=lexmin;User Id=SA;Password=P4ss-W0rd!;MultipleActiveResultSets=true". Обратите внимание, что для Windows мы используем : как разделитель иерархии конфигурации, но для не-ОС Windows мы должны использовать __ (найденный на https://github.com/aspnet/Configuration/issues/469).
  • SERILOG__CONNECTIONSTRING - это то же соединение, которое используется регистратором Serilog.
  • LEX__CONNECTIONSTRING - это строка подключения MongoDB: mongodb://mongo:27017/lex_catalog.
  • ZAX__CONNECTIONSTRING - это строка подключения MySql: Server=mysql;Database=zax_master;Uid=root;Pwd=password;SslMode=none.
  • другие переменные среды предназначены для использования инструментов командной строки MySql и Mongo для сброса базы данных, так как я должен вызывать ее из моего API (как вы можете видеть из сценария, мне все же нужно выяснить точное местоположение этих исполняемых файлов в Ubuntu, но это детализация).

Вот соответствующий appsettings.json в моем веб-API (сокращен), который показывает пути, соответствующие именам переменных среды:

 {
"Данные": {
 "DefaultConnection": {
 "ConnectionString": "..."
 }
},
"Serilog": {
 "ConnectionString": "...",
 "TableName": "Log",
 "MinimumLevel": {
 "По умолчанию": "Отладка",
 "Переопределить": {
 "Microsoft": "Информация",
 "Система": "Предупреждение"
 }
 }
},
"Лекс": {
 "ConnectionString": "..."
},
"Zax": {
 "ConnectionString": "..."
},
"Среда": {
 "MongoDirectory": "...",
 "MySqlDirectory": "...",
 "MySqlDumpUser": "root",
 "MySqlDumpPassword": "..."
}
 }

Теперь, когда я запускаю docker-compose up, все сервисы начинаются с нуля, включая MySql; тем не менее, мое приложение выдает исключение при попытке подключиться к MySql: Application startup exception: MySql.Data.MySqlClient.MySqlException(0x80004005): Host '172.19.0.5' is not allowed to connect to this MySQL server.

Может ли кто-нибудь помочь? Вот мой сценарий для композитора:

 версия: '3.4'

Сервисы: # SQL Server по умолчанию lexminmssql: image: microsoft/mssql-server-linux container_name: sqlserver среда: ACCEPT_EULA: Y SA_PASSWORD: "P4ss-W0rd!" порты: - 1433: 1433 сети: - lexminnetwork

# MongoDB - по умолчанию порт lexminmongo: изображение: mongo container_name: mongo порты: - 27017: 27017 сети: - lexminnetwork

# MySql в порту по умолчанию lexminmysql: image: mysql/mysql-server container_name: mysql среда: # пароль, который будет установлен для учетной записи суперпользователя root root MYSQL_ROOT_PASSWORD: "пароль" порты: - 3306: 3306 сети: - lexminnetwork

# Web API lexminapi: изображение: naftis/lexminapi порты: - 58942: 58942 зависит от: - lexminmssql: состояние: service_healthy - lexminmongo: состояние: service_healthy - lexminmysql: состояние: service_healthy построить: контекст:. dockerfile: LexminApi/Dockerfile среда: # для использования в Windows: как разделитель, для использования без использования Windows __ # (см. https://github.com/aspnet/Configuration/issues/469) DATA__DEFAULTCONNECTION__CONNECTIONSTRING: "Server = sqlserver\sqlexpress, 1433; Database = lexmin; Идентификатор пользователя = SA; Пароль = P4ss-W0rd!; MultipleActiveResultSets = true" SERILOG__CONNECTIONSTRING: "Server = sqlserver\sqlexpress, 1433; Database = lexmin; User Id = SA; Password = P4ss-W0rd!; MultipleActiveResultSets = true" LEX__CONNECTIONSTRING: "mongodb://mongo: 27017/lex_catalog" ZAX__CONNECTIONSTRING: "Server = mysql; Database = zax_master; Uid = root; Pwd = password; SslMode = none" # TODO: найти каталоги BIN в Linux ОКРУЖАЮЩАЯ СРЕДА: МОНГОДИКАЦИЯ: "" ENVIRONMENT__MYSQLDIRECTORY: "" ENVIRONMENT__MYSQLDUMPUSER: "root" ENVIRONMENT__MYSQLDUMPPASSWORD: "пароль" сети: - lexminnetwork объемы: -./zax-users.xml: /etc/lexmin/zax-users.xml

# Веб-приложение # СДЕЛАТЬ

сети: lexminnetwork: драйвер: мост

Сложение

Спасибо, я пытаюсь работать над этими проблемами подключения по одному, так как я узнал, что то же самое происходит для SQL Server в моих контейнерах. Поэтому я также распространяю вопрос на SQL Server, но я полагаю, что лучше поддерживать обсуждение в том же сообщении, поскольку проблемы кажутся похожими.

Я начал с меньшего набора контейнеров, избавившись от MySql в настоящее время. Мой композитор:

version: '3.4'

services:
  # SQL Server
  cadmusmssql:
    image: microsoft/mssql-server-linux
    container_name: cadmussqlserver
    environment:
      ACCEPT_EULA: Y
      SA_PASSWORD: "P4ss-W0rd!"
    ports:
      - 1433:1433
    networks:
      - cadmusnetwork

  # MongoDB
  cadmusmongo:
    image: mongo
    container_name: cadmusmongo
    environment:
      - MONGO_DATA_DIR=/data/db
      - MONGO_LOG_DIR=/dev/null
    ports:
      - 27017:27017
    command: mongod --smallfiles --logpath=/dev/null # --quiet
    networks:
      - cadmusnetwork

  cadmusapi:
    image: ...myprivaterepoimage...
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
    ports:
      - 60304:60304
    depends_on:
      - cadmusmssql
      - cadmusmongo
    environment:
      DATA__DEFAULTCONNECTION__CONNECTIONSTRING: "Server=127.0.0.1\\sqlexpress,1433;Database=cadmusapi;User Id=SA;Password=P4ss-W0rd!;MultipleActiveResultSets=true"
      SERILOG__CONNECTIONSTRING: "Server=127.0.0.1\\sqlexpress,1433;Database=cadmusapi;User Id=SA;Password=P4ss-W0rd!;MultipleActiveResultSets=true"
    networks:
      - cadmusnetwork

networks:
  cadmusnetwork:
    driver: bridge

По ходу поиска я обнаружил, что требуется явно указать номер порта в строке подключения. Таким образом, даже если в настоящее время я переопределяю переменные окружения в файле компоновки docker, я добавил их в свой appsettings.Production.json. В моем Program.cs Main метода, я настройка конфигурации, как это (для Serilog: см http://www.carlrippon.com/?p=1118):

IConfiguration configuration = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    .AddJsonFile(
        $"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json",
        optional: true)
    .Build();

Таким образом, это переопределяет файл appsettings.json с appsettings.Production.json если ASPNETCORE_ENVIRONMENT не указан. Во всяком случае, только для того, чтобы сделать это яснее, в моем композиторе я добавил его:

environment:
  + ASPNETCORE_ENVIRONMENT=Production

Чтобы проверить переменные среды, я добавил код, чтобы сбрасывать его при запуске приложения. Дамп имеет ожидаемые строки подключения:

cadmusapi_1    | ASPNETCORE_PKG_VERSION = 2.0.8
cadmusapi_1    | ASPNETCORE_URLS = http://+:80
cadmusapi_1    | DATA__DEFAULTCONNECTION__CONNECTIONSTRING = Server=127.0.0.1\sqlexpress,1433;Database=cadmusapi;User Id=SA;Password=P4ss-W0rd!;MultipleActiveResultSets=true
cadmusapi_1    | DOTNET_DOWNLOAD_SHA = d8f6035a591b5500a8b81188d834ed4153c4f44f1618e18857c610d0b332d636970fd8a980af7ae3fbff84b9f1da53aa2f45d8d305827ea88992195cd5643027
cadmusapi_1    | DOTNET_DOWNLOAD_URL = https://dotnetcli.blob.core.windows.net/dotnet/Runtime/2.0.7/dotnet-runtime-2.0.7-linux-x64.tar.gz
cadmusapi_1    | DOTNET_RUNNING_IN_CONTAINER = true
cadmusapi_1    | DOTNET_VERSION = 2.0.7
cadmusapi_1    | HOME = /root
cadmusapi_1    | HOSTNAME = 29884ca26699
cadmusapi_1    | PATH = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
cadmusapi_1    | SERILOG__CONNECTIONSTRING = Server=127.0.0.1\sqlexpress,1433;Database=cadmusapi;User Id=SA;Password=P4ss-W0rd!;MultipleActiveResultSets=true

Вот код дампа, возможно, он может быть полезен для быстрого копирования и вставки:

private static void DumpEnvironment()
{
    IDictionary dct = Environment.GetEnvironmentVariables();
    List<string> keys = new List<string>();
    var enumerator = dct.GetEnumerator();
    while (enumerator.MoveNext())
    {
        keys.Add(((DictionaryEntry)enumerator.Current).Key.ToString());
    }

    foreach (string key in keys.OrderBy(s => s))
        Console.WriteLine($"{key} = {dct[key]}");
}

Тем не менее, я продолжаю получать ошибку соединения с SqlServer, например: Application startup exception: System.Data.SqlClient.SqlException(0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 35 - An internal exception was caught) Application startup exception: System.Data.SqlClient.SqlException(0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 35 - An internal exception was caught) Application startup exception: System.Data.SqlClient.SqlException(0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 35 - An internal exception was caught).

По мере запуска служб я попытался подключиться к ним с моего хоста (Ubuntu) Docker с IP 127.0.0.1. Я установил SQL Operations Studio и подключился к 127.0.0.1\sqlexpress,1433 с именем пользователя SA и паролем, указанным в файле компоновки, и это отлично работает. Итак, как получается, что одни и те же параметры аутентификации не работают при использовании моего приложения ASP.NET Core в контейнере?

Теги:
sql-server
asp.net-core
docker-compose

1 ответ

1

Это для меня похоже на ошибку безопасности MySQL. В основном вам нужно настроить MySQL для внешних подключений.

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

  • 0
    Спасибо, я обновил свой вопрос, так как похоже, что такая же проблема возникает для любого подключения к базе данных. Что выглядит странным для меня, так это то, что я могу подключиться с моего хоста Docker, но не с моего сервиса в том же сетевом мосту, но используя те же параметры аутентификации.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню