最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - Access Dns from ASP.NET Core 8 Web API in Docker container - Stack Overflow

programmeradmin4浏览0评论

I have built an ASP.NET Core 8.0 Web API that gets the hostname of the connected client with the following code:

String? ip = Request.HttpContext.Connection.RemoteIpAddress?.ToString();

if (String.IsNullOrEmpty(ip))
{
    throw new ArgumentNullException("No Ip found.");
}

String hostname = Dns.GetHostEntry(ip).HostName;

if (String.IsNullOrEmpty(hostname))
{
    return ip;
}

return hostname;

This code worked just fine as long as I ran it in Visual Studio.

Now I want to deploy my API to a Docker container and this function returns the following exception:

System.Net.Sockets.SocketException (00000005, 0xFFFDFFFF): Name or service not known

at System.Net.Dns.GetHostEntryOrAddressesCore(IPAddress address, Boolean justAddresses, AddressFamily addressFamily, Nullable`1 startingTimestamp)
at System.Net.Dns.GetHostEntry(String hostNameOrAddress, AddressFamily family)
at[my Code above]

Maybe it's noteworthy that the DNS is a company DNS and I am trying to get the hostnames for internal IPs.

I either need to get this to work or figure out another way to resolve the remote hostname from my API.

I have tried adding the DNS to the Docker run command and changed the docker daemon DNS settings as follows:

docker run -t -d -p 50000:8080 -p 50001:8081 -e ASPNETCORE_ENVIRONMENT=Development --dns=[dns_ip] --name testcontainer [my_image]:latest

daemon.json:

{
  "builder": {
    "gc": {
      "defaultKeepStorage": "20GB",
      "enabled": true
    }
  },
  "dns-opts": [
    "ndots:15"
  ],
  "experimental": false
}

And my Dockerfile is pretty much the stock file you get when Visual Studio creates one for you:

FROM mcr.microsoft/dotnet/aspnet:8.0 AS base
USER app
WORKDIR /app
EXPOSE 8080
EXPOSE 8081

FROM mcr.microsoft/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Debug
WORKDIR /src
COPY ["MyProj/MyProj.csproj", "MyProj/"]
COPY ["MyLib/MyLib.csproj", "MyLib/"]
RUN dotnet restore "./MyProj/MyProj.csproj"
COPY . .
WORKDIR "/src/MyProj"
RUN dotnet build "./MyProj.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Debug
RUN dotnet publish "./MyProj.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyProj.dll"]

(I use debug as the Container will assist in some tests)

My image is created by running

dotnet publish -t:PublishContainer

I have also tried using Docker Desktops exec to resolve a hostname from within the container but the shell doesn't know the commands I was able to find so far.

I am quite new to Docker so I am already out of Ideas and would really appreciate some help.

I have built an ASP.NET Core 8.0 Web API that gets the hostname of the connected client with the following code:

String? ip = Request.HttpContext.Connection.RemoteIpAddress?.ToString();

if (String.IsNullOrEmpty(ip))
{
    throw new ArgumentNullException("No Ip found.");
}

String hostname = Dns.GetHostEntry(ip).HostName;

if (String.IsNullOrEmpty(hostname))
{
    return ip;
}

return hostname;

This code worked just fine as long as I ran it in Visual Studio.

Now I want to deploy my API to a Docker container and this function returns the following exception:

System.Net.Sockets.SocketException (00000005, 0xFFFDFFFF): Name or service not known

at System.Net.Dns.GetHostEntryOrAddressesCore(IPAddress address, Boolean justAddresses, AddressFamily addressFamily, Nullable`1 startingTimestamp)
at System.Net.Dns.GetHostEntry(String hostNameOrAddress, AddressFamily family)
at[my Code above]

Maybe it's noteworthy that the DNS is a company DNS and I am trying to get the hostnames for internal IPs.

I either need to get this to work or figure out another way to resolve the remote hostname from my API.

I have tried adding the DNS to the Docker run command and changed the docker daemon DNS settings as follows:

docker run -t -d -p 50000:8080 -p 50001:8081 -e ASPNETCORE_ENVIRONMENT=Development --dns=[dns_ip] --name testcontainer [my_image]:latest

daemon.json:

{
  "builder": {
    "gc": {
      "defaultKeepStorage": "20GB",
      "enabled": true
    }
  },
  "dns-opts": [
    "ndots:15"
  ],
  "experimental": false
}

And my Dockerfile is pretty much the stock file you get when Visual Studio creates one for you:

FROM mcr.microsoft/dotnet/aspnet:8.0 AS base
USER app
WORKDIR /app
EXPOSE 8080
EXPOSE 8081

FROM mcr.microsoft/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Debug
WORKDIR /src
COPY ["MyProj/MyProj.csproj", "MyProj/"]
COPY ["MyLib/MyLib.csproj", "MyLib/"]
RUN dotnet restore "./MyProj/MyProj.csproj"
COPY . .
WORKDIR "/src/MyProj"
RUN dotnet build "./MyProj.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Debug
RUN dotnet publish "./MyProj.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyProj.dll"]

(I use debug as the Container will assist in some tests)

My image is created by running

dotnet publish -t:PublishContainer

I have also tried using Docker Desktops exec to resolve a hostname from within the container but the shell doesn't know the commands I was able to find so far.

I am quite new to Docker so I am already out of Ideas and would really appreciate some help.

Share Improve this question edited Mar 8 at 7:06 marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked Mar 8 at 6:58 Juli KrajewskiJuli Krajewski 111 bronze badge 2
  • First of all, do you need docker at all? If you will publish your app without docker, this is unnecessary hustle. Secondly, if it works without Docker, it is clear that there are some networking issues with Docker. You need to try to debug it in docker then. If any outgoing DNS names can be found, for example google. I am sure you would find something along the way – Michał Turczyn Commented Mar 8 at 7:03
  • @MichałTurczyn yes, I really need Docker as it will also be used for deployment later. As far as testing from inside the container goes, whenever I use network commands with docker exec it tells me that the commands are not found (might be an issue of the base image) – Juli Krajewski Commented Mar 8 at 15:11
Add a comment  | 

1 Answer 1

Reset to default 0

Actually, I could reproduce it by simply using such code (I used google IP addres):

app.MapGet("/", () =>
{
    var ip = "142.250.203.206";
    if (string.IsNullOrEmpty(ip))
    {
        throw new ArgumentNullException("No Ip found.");
    }

    var hostname = Dns.GetHostEntry(ip).HostName;
    if (string.IsNullOrEmpty(hostname))
    {
        return ip;
    }

    return hostname;
})
.WithName("DnsTest")
.WithOpenApi();

Without docker, it finds hostname correctly, inside docker, it throws "Name or service not known" exception.

And I found relevant help in this post (upvote is due :) ).

Solution directly in Visual Studio

As I found out, we need just --dns setting for docker run. Such parameters can be provided in .csproj file, as posted in docker run command for ASP.NET Core and Visual Studio 2017:

<PropertyGroup>
    <DockerfileRunArguments>--dns 8.8.8.8</DockerfileRunArguments>
</PropertyGroup>

This solved the issue :) Of course, I used Google's DNS server IP 8.8.8.8, you need to use your company's internal DNS server.

Setting DNS servers in Docker Desktop (UI)

So, I am on windows, so i went to docker desktop configuration and changed DNS setting there:

After that adjustment, i got it working correctly, just as it was working without docker.

Of course, in your case, you need to add there IP of your company's internal DNS server.

发布评论

评论列表(0)

  1. 暂无评论