Обновлено: см. Ниже
Я новичок в Docker и пытаюсь создать веб-API.NET Core 2.0 на хосте Ubuntu 18, используя Docker 18.05.0-ce (build f150324) и эти службы, все в одной сети:
Мой файл компоновки докеров предоставляет эти службы из соответствующих изображений, как сообщается ниже. Короче:
microsoft/mssql-server-linux
, порт 1433, sa
пароль пользователя устанавливается с помощью переменного окружения SA_PASSWORD
после принятия лицензионного соглашения через ACCEPT_EULA
;mongo
, порт 27017;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
. Вот соответствующий 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 в контейнере?
Это для меня похоже на ошибку безопасности MySQL. В основном вам нужно настроить MySQL для внешних подключений.
Там очень хороший поток здесь, что проходит через неприятность съемки шагов, чтобы это сортируется.