Обновлено: см. Ниже
Я новичок в Docker и пытаюсь создать веб-API .NET Core 2.0 на хосте Ubuntu 18, используя Docker 18.05.0-ce (build f150324) и все эти службы в одной сети:
- база данных SQL Server;
- база данных MySql (https://github.com/docker-library/docs/tree/master/mysql/);
- база данных Mongo.
Мой составной файл Docker предоставляет эти службы из их соответствующих образов, как указано ниже. Вкратце:
Конечно, доступ к веб-APIэти сервисы используют другие учетные данные в своей среде разработки, но я переопределяю ихia переменные среды для настройки системы на Docker (в ASPNET Core 2, как видно из https://github.com/aspnet/MetaPackages/blob/dev/src/Microsoft.AspNetCore/WebHost.cs, метод CreateDefaultBuilder
уже включает переменные среды в качестве источника конфигурации):
DATA__DEFAULTCONNECTION__CONNECTIONSTRING
: строка подключения к Sql Server с использованием 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 (сокращенный), который показывает пути, соответствующие именам переменных среды:
{
"Data": {
"DefaultConnection": {
"ConnectionString": "..."
}
},
"Serilog": {
"ConnectionString": "...",
"TableName": "Log",
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Information",
"System": "Warning"
}
}
},
"Lex": {
"ConnectionString": "..."
},
"Zax": {
"ConnectionString": "..."
},
"Environment": {
"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
.
Кто-нибудь может помочь? Вотсценарий моего композитора:
version: '3.4'</p>
<p>services:
# SQL Server at default port
lexminmssql:
image: microsoft/mssql-server-linux
container_name: sqlserver
environment:
ACCEPT_EULA: Y
SA_PASSWORD: "P4ss-W0rd!"
ports:
- 1433:1433
networks:
- lexminnetwork</p>
<p># MongoDB - at default port
lexminmongo:
image: mongo
container_name: mongo
ports:
- 27017:27017
networks:
- lexminnetwork</p>
<p># MySql at default port
lexminmysql:
image: mysql/mysql-server
container_name: mysql
environment:
# the password that will be set for the MySQL root superuser account
MYSQL_ROOT_PASSWORD: "password"
ports:
- 3306:3306
networks:
- lexminnetwork</p>
<p># Web API
lexminapi:
image: naftis/lexminapi
ports:
- 58942:58942
depends_on:
- lexminmssql:
condition: service_healthy
- lexminmongo:
condition: service_healthy
- lexminmysql:
condition: service_healthy
build:
context: .
dockerfile: LexminApi/Dockerfile
environment:
# for Windows use : as separator, for non Windows use __
# (see <a href="https://github.com/aspnet/Configuration/issues/469" rel="nofollow noreferrer">https://github.com/aspnet/Configuration/issues/469</a>)
DATA__DEFAULTCONNECTION__CONNECTIONSTRING: "Server=sqlserver\sqlexpress,1433;Database=lexmin;User Id=SA;Password=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: locate BIN directories in Linux
ENVIRONMENT__MONGODIRECTORY: ""
ENVIRONMENT__MYSQLDIRECTORY: ""
ENVIRONMENT__MYSQLDUMPUSER: "root"
ENVIRONMENT__MYSQLDUMPPASSWORD: "password"
networks:
- lexminnetwork
volumes:
- ./zax-users.xml:/etc/lexmin/zax-users.xml</p>
<p># Web app
# TODO</p>
<p>networks:
lexminnetwork:
driver: bridge
ADDITION
Спасибо, я пытаюсь работать над этими проблемами соединения по одному,как я узнал, что то же самое происходит с 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)
.
Когда службы запускались, я пытался подключиться к ним с моего хоста (Ubuntu) Docker с IP 127.0.0.1.Я установил SQL Operations Studio и подключился к 127.0.0.1\sqlexpress,1433
с именем пользователя SA
и паролем, указанным в файле compose, и это прекрасно работает.Итак, как получается, что одни и те же параметры аутентификации не работают при использовании из моего приложения ASP.NET Core в его контейнере?