【问题标题】:Containers with docker-compose have different behavior depending on machine where they are executed使用 docker-compose 的容器具有不同的行为,具体取决于执行它们的机器
【发布时间】:2020-11-23 09:39:31
【问题描述】:

早安,

我正在尝试使以下 docker-compose 在我的机器上运行,但是在尝试从容器 B 访问容器 A 的 url 时遇到一些 404 错误的问题。

先验的唯一不在源代码管理中的是对主机文件的修改,我必须在其中添加以下行。

127.0.0.1 idsrv4admin.traefik.me
127.0.0.1 idsrv4adminApi.traefik.me
127.0.0.1 login.traefik.me

我从源代码管理中获得了所有资源,并且在我朋友的机器上运行良好。 也许我的机器上有不同的配置,但我不知道它是什么。

如果我尝试直接从浏览器访问“http://login.traefik.me/.well-known/openid-configuration”,我可以访问它:

{"issuer":"http://login.traefik.me","authorization_endpoint":"http://login.traefik.me/connect/authorize","token_endpoint":"http://login.traefik.me/connect/token","userinfo_endpoint":"http://login.traefik.me/connect/userinfo","end_session_endpoint":"http://login.traefik.me/connect/endsession","check_session_iframe":"http://login.traefik.me/connect/checksession","revocation_endpoint":"http://login.traefik.me/connect/revocation","introspection_endpoint":"http://login.traefik.me/connect/introspect","device_authorization_endpoint":"http://login.traefik.me/connect/deviceauthorization","frontchannel_logout_supported":true,"frontchannel_logout_session_supported":true,"backchannel_logout_supported":true,"backchannel_logout_session_supported":true,"scopes_supported":["roles","openid","profile","email","address","identity_admin_api","offline_access"],"claims_supported":["role","sub","updated_at","locale","zoneinfo","birthdate","gender","website","picture","preferred_username","nickname","middle_name","given_name","family_name","name","profile","email","email_verified","address"],"grant_types_supported":["authorization_code","client_credentials","refresh_token","implicit","password","urn:ietf:params:oauth:grant-type:device_code"],"response_types_supported":["code","token","id_token","id_token token","code id_token","code token","code id_token token"],"response_modes_supported":["form_post","query","fragment"],"token_endpoint_auth_methods_supported":["client_secret_basic","client_secret_post"],"subject_types_supported":["public"],"code_challenge_methods_supported":["plain","S256"],"request_parameter_supported":true}

如果我从容器管理员连接并尝试在同一个 url 上卷曲,我会收到 404 并显示以下错误消息:

* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x560c38473f50)
* Connected to login.traefik.me (127.0.0.1) port 80 (#0)
> GET /.well-known/openid-configuration HTTP/1.1
> Host: login.traefik.me
> User-Agent: curl/7.64.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Date: Mon, 23 Nov 2020 08:34:58 GMT
< Content-Length: 0
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Frame-Options: SameOrigin
< Referrer-Policy: no-referrer
< Content-Security-Policy: script-src 'self' 'unsafe-inline' 'unsafe-eval';style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/ https://fonts.gstatic.com/;font-src 'self' https://fonts.googleapis.com/ https://fonts.gstatic.com/
<
* Connection #0 to host login.traefik.me left intact

下面是 docker-compose:

version: "3.4"

services:
  traefik:
    image: "traefik:latest"
    container_name: "traefik"
    command:
      - "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.traefik.address=:9090"
    ports:
      - "80:80"
      - "443:443"
      - "9090:9090"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - proxy

  admin:
    image: ${DOCKER_REGISTRY-}admin:latest
    build:
      context: .
      dockerfile: src/IdentityServer/Admin/Dockerfile
    container_name: is4-admin
    hostname: idsrv4admin.traefik.me
    expose:      
      - '80'
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.identityserver4Admin.rule=Host(`idsrv4admin.traefik.me`)"
      - "traefik.http.routers.identityserver4Admin.entrypoints=web"
    environment:
      - VIRTUAL_HOST=idsrv4admin.traefik.me
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:80
      - DOTNET_USE_POLLING_FILE_WATCHER=1
      - "AdminConfiguration__IdentityAdminRedirectUri=http://idsrv4admin.traefik.me/signin-oidc"
      - "AdminConfiguration__IdentityServerBaseUrl=http://login.traefik.me"
      - "AdminConfiguration__RequireHttpsMetadata=false"
    depends_on:
      - sts.identity
      - admin.api
    networks:
      - proxy

  admin.api:
    image: ${DOCKER_REGISTRY-}admin-api:latest
    build:
      context: .
      dockerfile: src/IdentityServer/Admin.Api/Dockerfile
    container_name: is4-admin-api
    hostname: idsrv4adminApi.traefik.me
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.identityserver4AdminApi.rule=Host(`idsrv4adminApi.traefik.me`)"
      - "traefik.http.routers.identityserver4AdminApi.entrypoints=web"
    environment:
      - VIRTUAL_HOST=idsrv4adminApi.traefik.me
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:80
      - DOTNET_USE_POLLING_FILE_WATCHER=1
      - "AdminApiConfiguration__RequireHttpsMetadata=false"
      - "AdminApiConfiguration__ApiBaseUrl=http://idsrv4adminApi.traefik.me"
      - "AdminApiConfiguration__IdentityServerBaseUrl=http://login.traefik.me"
    depends_on:
      - sts.identity
    networks:
      - proxy

  sts.identity:
    image: ${DOCKER_REGISTRY-}sts-identity:latest
    build:
      context: .
      dockerfile: src/IdentityServer/STS.Identity/Dockerfile
    container_name: is4-sts-identity
    hostname: login.traefik.me
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.identityserver4STS.rule=Host(`login.traefik.me`)"
      - "traefik.http.routers.identityserver4STS.entrypoints=web"
    environment:
      - VIRTUAL_HOST=login.traefik.me
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:80
      - DOTNET_USE_POLLING_FILE_WATCHER=1
      - "AdminConfiguration__IdentityAdminBaseUrl=http://idsrv4admin.traefik.me"
    networks:
      - proxy

networks:
  proxy:
    driver: bridge

有人有想法吗?

提前致谢

【问题讨论】:

    标签: docker asp.net-core docker-compose traefik


    【解决方案1】:

    您正在尝试连接到 127.0.0.1 Connected to login.traefik.me (127.0.0.1) port 80 (#0),这会将您发送到管理容器内的 127.0.0.1,而不是您的机器上

    要使其正常工作,您需要将 login.traefik.me 映射到您的本地地址 (192.168.x.x)

    另外,如果你用服务名称调用那个端点会更好,因为所有容器都在同一个网络中,你可以替换这个环境变量

    - "AdminApiConfiguration__IdentityServerBaseUrl=http://login.traefik.me"
    

    - "AdminApiConfiguration__IdentityServerBaseUrl=http://sts.identity:80"
    

    【讨论】:

    • 谢谢,如果我将 127.0.0.1 更改为我的 IP 地址,它可以工作,但是如何在他的机器上使用这个设置?他和我唯一的区别是他在linux机器上,而我在windows上
    • 我猜,根据两台机器上使用的 docker 版本,你的(windows)上的 127.0.0.1 解析为内部容器,而在另一个(linux)上它解析为机器主机地址
    • dev.to/natterstefan/… On Docker for Linux, the IP address of the gateway between the Docker host and the bridge network is 172.17.0.1 if you are using default networking. 另外,请查看 Andreas Jägle 的回答。
    【解决方案2】:

    您正在使用 traefik.me 服务提供的主机名,该服务(类似于 xip.io)通过根据子域模式将域解析为 IP 来提供通配符 DNS 服务。

    例如,对 myapp.1.2.3.4.traefik.me 的 dns 查询将解析为在子域 1.2.3.4 中编码的 IP 地址。如果您没有在子域中指定 IP 地址(也没有使用十六进制表示法),此服务会自动解析为 127.0.0.1,这在大多数情况下适用于主机到容器的设置。

    在您的主机上运行,​​使用此 IP 地址(本地主机)指向您的主机。由于您使用 docker compose 公开了 traefik,因此从本地计算机到本地计算机的请求被映射到容器(由于您为 traefik 定义的 ports 映射)。

    在容器本身内部运行时情况并非如此。查看 curl 命令的日志输出:

    * Connected to login.traefik.me (127.0.0.1) port 80 (#0)

    从其中一个容器内运行完全相同的请求也将解析为 127.0.0.1 IP,但在容器内,此 IP 地址不再是您的主机地址,而是容器网络接口的环回适配器。所以基本上你在使用容器时遇到了一个很常见的问题,即127.0.0.1 的含义,这里已经回答了几次:

    因此,如果您需要一个适用于主机和容器的单个 dns 名称,您需要切换到类似 login.192.168.1.123.traefik.me 的名称,假设 192.168.1.123 是您的主机 IP 地址。但正如您所注意到的,这需要针对每个开发人员进行调整,即使您更改了所连接的网络/wifi。

    所以,如果您想使用完全相同的域名进行公共访问和容器间调用,我想没有使用这种通配符 dns 服务的首选解决方案。在生产场景中,主机名将解析为全局有效的公共 IP 地址,该地址在从容器内部访问时也可以工作,因为它将通过 traefik 进行完整的往返,但这对于这样的开发设置来说并不是一个好的选择。

    在这种情况下,您确实需要指定不同的域,具体取决于您是发出重定向(使用全局有效域)还是使用从一个容器到另一个容器的直接调用。这些可以使用 docker-compose 内部服务名称访问,例如像 http://sts.identity 或 - 不太喜欢 - 容器名称 (http://is4-sts-identity)。您可以通过相应地配置环境变量AdminApiConfiguration__IdentityServerBaseUrl 来指定使用这些网址而不是公共网址吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-30
      • 1970-01-01
      • 1970-01-01
      • 2016-08-31
      • 2010-09-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多