Estoy tratando de ejecutar una serie de servicios usando un archivo docker-compose. En primer lugar, supongamos que Docker, versión 20.10.3, se ejecuta en Red Hat Enterprise Linux versión 8.3.
Este es el archivo docker-compose:
version: "3.8" services: projmssql: image: "mcr.microsoft.com/mssql/server:2019-latest" container_name: proj-core-sqlserver environment: SA_PASSWORD: "mypassword" ACCEPT_EULA: "Y" ports: - "1401:1433" volumes: - type: bind source: ./data-mssql target: /var/opt/mssql/data - type : bind source: ./log-mssql target: /var/opt/mssql/log restart: always projelastic: image: docker.elastic.co/elasticsearch/elasticsearch:7.10.1 container_name: proj-core-elastic environment: - node.name=es01 - cluster.name=proj-docker-cluster - discovery.type=single-node - bootstrap.memory_lock=false - "ES_JAVA_OPTS=-Xms1g -Xmx1g" - path.repo=/usr/share/elasticsearch/backup - path.logs=/usr/share/elasticsearch/logs ulimits: memlock: soft: -1 hard: -1 volumes: - type: bind source: ./data-es01 target: /usr/share/elasticsearch/data - type : bind source: ./_backup-es01 target: /usr/share/elasticsearch/backup - type : bind source: ./logs-es01 target: /usr/share/elasticsearch/logs ports: - 9220:9200 - 9320:9300 projcerebro: image: lmenezes/cerebro container_name: proj-core-cerebro ports: - "9020:9000" command: - -Dhosts.0.host=http://projelastic:9200 projapi: image: proj/projcoreapp depends_on: - projmssql container_name: proj-core-api ports: - "8080:80" restart: always #Specify Environment Variables for the Api Service environment: - ASPNETCORE_ENVIRONMENT=DockerEl servicio projApi proviene de mi imagen local (proj/projcoreapp) creada con el siguiente Dockerfile:
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build-env WORKDIR /app COPY . ./ RUN dotnet publish proj.api.net -c Release -o out FROM mcr.microsoft.com/dotnet/aspnet:5.0 WORKDIR /app COPY --from=build-env /app/out . ENTRYPOINT ["dotnet", "Proj.Api.dll"]En mi aplicación .net core tengo un archivo appsettings.Docker.json dedicado
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "Elasticsearch": { "Server": "http://projelastic:9200", "DebugMode": true, "UpdateMapping": false }, "ConnectionStrings": { "DatabaseConnection": "Server=projmssql;Database=PROJ-NET;Persist Security Info=False;User ID=sa;Password=mypassword;MultipleActiveResultSets=True;TrustServerCertificate=False;Connection Timeout=30;" } } El .csproj del proyecto principal API .net
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net5.0</TargetFramework> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <DocumentationFile></DocumentationFile> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.AzureAD.UI" Version="5.0.5" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.0.0" /> <PackageReference Include="Microsoft.Identity.Web" Version="1.9.1" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.14" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\domain.net\Domain.csproj" /> </ItemGroup> </Project> El .csproj de la biblioteca de Dominios
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net5.0</TargetFramework> </PropertyGroup> <ItemGroup> <Compile Remove="Entities\Organisation.cs" /> <Compile Remove="Entities\OrganisationTeam.cs" /> <Compile Remove="Entities\OrganisationTeamRole.cs" /> </ItemGroup> <ItemGroup> <PackageReference Include="Elasticsearch.Net" Version="7.10.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.5" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.5" /> <PackageReference Include="NEST" Version="7.10.0" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> </ItemGroup> <ItemGroup> <Folder Include="Utilities\" /> <Folder Include="ViewModels\" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\filter.net\Filter.csproj" /> </ItemGroup> </Project> El .csproj de la biblioteca de filtros
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net5.0</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Elasticsearch.Net" Version="7.10.0" /> <PackageReference Include="GeoJSON.Net" Version="1.2.19" /> <PackageReference Include="NEST" Version="7.10.0" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> </ItemGroup> <ItemGroup> <Folder Include="Entities\" /> <Folder Include="Helpers\" /> <Folder Include="ViewModelMapper\" /> </ItemGroup> </Project>En mi inicio de .net core tengo la siguiente configuración
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<ProjdbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DatabaseConnection")) ); services.AddScoped<IProjUserService, ProjUserService>(); services.AddSingleton<IProjEntitiesService>(s => new ProjEntitiesService ( Configuration.GetValue<string>("Elasticsearch:Server"), Configuration.GetValue<bool>("Elasticsearch:DebugMode"), Configuration.GetValue<bool>("Elasticsearch:UpdateMapping") )); services.AddControllers(); services.AddSwaggerGen(c => {Ahora hablemos del problema: una vez que ejecuto el archivo docker-compose, todos los servicios se ejecutan correctamente y desde el host puedo interactuar con todos ellos. El servicio de API puede conectarse internamente a la base de datos, pero una vez que ejecuto algunas API para interactuar con el servicio de búsqueda elástica, aparece el siguiente error:
Elasticsearch.Net.UnexpectedElasticsearchClientException: The information requested is unavailable on the current platform. ---> System.PlatformNotSupportedException: The information requested is unavailable on the current platform. at System.Net.NetworkInformation.StringParsingHelpers.ParseActiveTcpConnectionsFromFiles(String tcp4ConnectionsFile, String tcp6ConnectionsFile) at System.Net.NetworkInformation.LinuxIPGlobalProperties.GetActiveTcpConnections() at Elasticsearch.Net.Diagnostics.TcpStats.GetStates() at Elasticsearch.Net.HttpConnection.Request[TResponse](RequestData requestData) at Elasticsearch.Net.RequestPipeline.CallElasticsearch[TResponse](RequestData requestData) at Elasticsearch.Net.Transport`1.Request[TResponse](HttpMethod method, String path, PostData data, IRequestParameters requestParameters) --- End of inner exception stack trace ---Como dije, todos los servicios funcionan correctamente e incluso el servicio Cerebro puede conectarse internamente al servicio elasticsearch, por lo que parece un problema relacionado solo con el servicio .net core.
No pude encontrar ningún tema con respecto al problema anterior, así que espero que alguien aquí pueda ayudarme a resolverlo.
PD: la API de .NET Core, implementada localmente en una máquina con Windows (servidor web Kestrel), se ejecuta correctamente conectándose a la base de datos y elasticsearch con ambos ejecutándose en Docker.
Actualizar:
Olvidé mencionar que la máquina se ejecuta detrás de un proxy corporativo. Teniendo eso en cuenta, quería verificar si mi servicio de API podía llegar al punto final del servicio de Elasticsearch: http://projelastic:9200 . Para hacer eso, ejecuté un shell bash interactivo en mi contenedor de servicio API: docker exec -it proj-core-api /bin/bash . Aquí noté que mis contenedores no tienen acceso a internet
root@8e7c81f98455:/app# apt-get update Err:1 http://security.debian.org/debian-security buster/updates InRelease Could not connect to security.debian.org:80 (111: Connection refused)Así que agregué al archivo docker-compose las variables para el servidor proxy, incluido el no_proxy para el dominio del servicio Elasticsearch.
projapi: image: proj/projcoreapp depends_on: - projmssql container_name: proj-core-api ports: - "8080:80" restart: always #Specify Environment Variables for the Api Service environment: - ASPNETCORE_ENVIRONMENT=Docker - http_proxy=http://user:pwd@address - https_proxy=http://user:pwd@address - no_proxy=projelasticCon el cambio anterior, pude instalar curl en mi contenedor API y realizar mi prueba inicial:
root@0573a44a6836:/app# curl -X GET http://projelastic:9200 { "name" : "es01", "cluster_name" : "proj-docker-cluster", "cluster_uuid" : "j7mdpxkrSRKxpHnktvnZIw", "version" : { "number" : "7.10.1", "build_flavor" : "default", "build_type" : "docker", "build_hash" : "1c34507e66d7db1211f66f3513706fdf548736aa", "build_date" : "2020-12-05T01:00:33.671820Z", "build_snapshot" : false, "lucene_version" : "8.7.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" } De todos modos, agregar las variables de proxy no solucionó el error inicial, por lo que, como prueba final, traje mi código fuente a una Windows 10 machine donde se ejecuta una Docker version 20.10.7 y sin proxy . Creé la imagen de la API y ejecuté docker-compose. Todos los servicios funcionan correctamente, por lo que sigo pensando que en la máquina Linux el proxy juega un papel importante en mi problema actual.
Actualización 2: pude solucionar ese problema gracias a la sugerencia de @AndrewSilver. Muchas gracias también a @kha por brindar más detalles.