简体   繁体   English

Docker 容器在 docker compose 中无法看到彼此,主机也无法看到

[英]Docker containers are not able to see each other in docker compose, nor is host

There are couple of issues that I have encountered while working with Docker.我在使用 Docker 时遇到了几个问题。

  1. Host (Windows 10) is not able to access any resources hosted by containers.主机 (Windows 10) 无法访问容器托管的任何资源。
  2. Containers themselves are also not seeing each other.容器本身也看不到对方。

My config:我的配置:

version: '3.7'
services:
  chrome:
    build: ./chrome
    container_name: chrome_container
    ports:
      - "9223:9223"

  dotnetapp:
    depends_on:
       - chrome
    build: ./dotnetapp
    container_name: live_container
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
    stdin_open: true
    tty: true

Dockerfile for chrome (all it does - starts Chrome with debugging, enabled on port 9223):用于 chrome 的Dockerfile (它所做的一切 - 以调试方式启动 Chrome,在端口 9223 上启用):

FROM debian:buster-slim

# preparation
RUN apt-get update; apt-get clean
RUN apt-get install -y wget
RUN apt-get install -y gnupg2

# installing xvfb
RUN apt-get install -y xvfb

# installing Chrome
RUN wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
RUN apt-get update && apt-get install -y google-chrome-beta

EXPOSE 9223

COPY ./docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh / # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["test"]

docker-entrypoint.sh

#!/bin/bash
set -e

if [ "$1" = 'test' ]; then
    rm -f /tmp/.X99-lock
fi

xvfb-run -e /dev/stdout --server-args='-screen 0, 2560x1440x16' google-chrome --window-size=2560,1440 --no-sandbox --remote-debugging-port=9223 --user-data-dir=remote-profile https://www.google.com/

Dockerfile for second app (is used just for docker internal network testing)用于第二个应用程序的Dockerfile (仅用于Dockerfile内部网络测试)

FROM mcr.microsoft.com/dotnet/core/runtime:2.2

# run app
CMD ["/bin/bash"]

So, now, to elaborate on point 1:所以,现在,详细说明第 1 点:

I can launch chrome container by running: docker-compose up --build chrome .我可以通过运行来启动 chrome 容器: docker-compose up --build chrome

On host system I then try to open a browser either localhost:9223 or http://172.17.0.2:9223/ and in both cases I get "page could not be reached error".在主机系统上,我然后尝试打开浏览器localhost:9223http://172.17.0.2:9223/并且在这两种情况下我都得到“无法访问页面错误”。 Ps I got IP from docker inspect command. Ps 我从docker inspect命令获得了 IP。

在此处输入图片说明

On the other hand, if I try to go into running container docker exec -it chrome_container bash and execute command curl localhost:9223 then it shows a SUCCESS result.另一方面,如果我尝试运行容器docker exec -it chrome_container bash并执行命令curl localhost:9223那么它会显示 SUCCESS 结果。

在此处输入图片说明

At this point if I try using other address like curl chrome:9223 or curl http://chrome:9223 or curl chrome_container:9223 or curl http://chrome_container:9223 then they also FAIL.此时,如果我尝试使用其他地址,例如curl chrome:9223curl http://chrome:9223curl chrome_container:9223curl http://chrome_container:9223那么它们也会失败。 According to documentation - all containers within internal network shall be accessible by the service host name .根据文档 - 内部网络中的所有容器都可以通过服务主机名访问 This is simply false in my scenario.在我的场景中,这完全是错误的。

I also tried starting the image without relying on docker compose like this docker run -p 9223:9223 -it --rm all_chrome but the result is the same.我也试着开始图像,而不依赖于docker compose这样的docker run -p 9223:9223 -it --rm all_chrome但结果是一样的。 The resource is not available from within host system.该资源在主机系统内不可用。

Now, to elaborate on issue 2.现在,详细说明问题 2。

When I run both applications like this docker-compose up .当我运行这两个应用程序时docker-compose up And log-into second app by docker exec -it live_container bash .并通过docker exec -it live_container bash登录第二个应用程序。 And then try to access first container using above mentioned URLS - all of them fail ( curl localhost:9223 or curl 0.0.0.0:9223 or curl chrome:9223 or curl http://chrome:9223 or curl chrome_container:9223 or curl http://chrome_container:9223 ).然后尝试使用上述 URLS 访问第一个容器 - 它们都失败( curl localhost:9223curl 0.0.0.0:9223curl chrome:9223curl http://chrome:9223curl chrome_container:9223curl http://chrome_container:9223 )。

I tried restarting Docker a couple of times and tried different ports.我尝试重新启动 Docker 几次并尝试了不同的端口。 How can I figure out these things?我怎样才能弄清楚这些事情?

  1. How to access resource at 9223 port at Host system?如何在主机系统的 9223 端口访问资源?

  2. Why isn't the second service able to see the first service using the host name, as documented here ?为什么第二个服务不能使用主机名查看第一个服务,如此处所述

I am using Docker on Windows 10.我在 Windows 10 上使用 Docker。

在此处输入图片说明

EDIT: More details.编辑:更多细节。

  • When accessing by localhost - following error is showed:通过本地主机访问时 - 显示以下错误:

在此处输入图片说明

  • When accessing by IP- following error is showed:通过IP访问时-显示以下错误:

在此处输入图片说明

So it seems like something is happening when accessing by localhost on a Host system (win 10).因此,在主机系统(win 10)上通过本地主机访问时似乎发生了一些事情。

Just found the information in a topic , that Chrome simply does not accept connections from outside of localhost network while in debug mode.刚刚在一个主题中找到信息, Chrome在调试模式下根本不接受来自本地主机network外部的连接。

So, starting the container as:因此,启动容器为:

docker run -p 5656:5656 -it --rm all_chrome

And then to solve the issue I have to use a proxy.然后为了解决这个问题,我必须使用代理。 Here is an example:下面是一个例子:

socat tcp-listen:5656,fork tcp:localhost:9223

After that - accessing through localhost works fine:之后 - 通过 localhost 访问工作正常:

在此处输入图片说明

I am yet to figure out how to start socat in daemon mode so I can make it a part of startup script in docker .. but that's a minor thing.我还没有搞清楚如何开始socat守护进程方式,所以我可以使它在启动脚本的一部分docker ..但是这是一个次要的事情。

Edit.编辑。 Couple of notes.几个笔记。

Accessing Chrome container from another container从另一个容器访问 Chrome 容器

If you tried to access the debug session from another container using the IP, then that would work just fine:如果您尝试使用 IP 从另一个容器访问调试会话,那么这将正常工作:

curl 172.19.0.2:5656

Otherwise, if you tried to use a host name - you would see an error.否则,如果您尝试使用主机名 - 您会看到错误。

curl chrome:5656

error:错误:

Host header is specified and is not an IP address or localhost.root@38f2b5fa34ca:/app# curl chrome:5656主机标头已指定且不是 IP 地址或 localhost.root@38f2b5fa34ca:/app# curl chrome:5656

This can be sovled, by stripping down Host header value:这可以通过剥离Host标头值来解决:

curl chrome:5656 -H 'Host: '

The problem, still, is that this is not very convenient approach.问题仍然是,这不是很方便的方法。 Because application do not always have the possibility to remove the header from the request.因为应用程序并不总是有可能从请求中删除标头。 For exampe - a chromedriver .例如 - 一个chromedriver Therefore, a solution would be to make a configuration on chrome docker container, that would remove Host header value for all incoming requests.. I tried doing it using squid proxy, but without success.. So, instead, I came up with another solution.因此,解决办法是让Chrome泊坞窗容器上的配置,这将删除主机头值对所有传入的请求。我试图做它用squid代理,但都没有成功。所以,相反,我想出了另一种解决方案.

The solution is to use a static, fixed IP address for containers' internal network.. In that way - you can always be sure that docker will be using the same address and therefore, your application can use it in their calls.解决方案是为容器的内部网络使用一个静态的、固定的 IP 地址。这样 - 您始终可以确保 docker 将使用相同的地址,因此您的应用程序可以在它们的调用中使用它。

The config is following:配置如下:

version: '3.7'
services:
  chrome:
    networks:
        front:
            ipv4_address: 172.16.238.5 
  app2:
    networks:
        front:
            ipv4_address: 172.16.238.10 
networks:
  front:
    driver: bridge
    ipam:
     config:
       - subnet: 172.16.238.0/24

Now in app2 you can make calls using the fixed IP:现在在 app2 中,您可以使用固定 IP 拨打电话:

CURL 172.16.238.5:5656

This is so far the easiest solution..这是迄今为止最简单的解决方案..

ps If you are running chrome in headless mode, then you can provide additional argument which in theory will solve some of your problems --remote-debugging-address . ps 如果您在无头模式下运行 chrome,那么您可以提供额外的参数,理论上可以解决您的一些问题--remote-debugging-address Try it.尝试一下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM