1

我使用的是旧版本的 Docker Toolbox for Windows,因此我将其卸载并安装了最新的稳定版 Docker for Windows。

我有两个在自己的容器上运行的 Java 应用程序:

两个应用程序中使用的Dockerfile

FROM frolvlad/alpine-oraclejdk8:slim
VOLUME /tmp
ADD archimedes-0.0.1-SNAPSHOT.jar app.jar
RUN sh -c 'touch /app.jar'
ENV JAVA_OPTS="-Xms750m -Xmx750m"
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]

我修改了我的 Windows /etc/hosts以使 archimedes1\2 映射 127.0.0.1(使用以前的 Docker Toolbox 映射 192.168.99.100):

127.0.0.1           archimedes1
127.0.0.1           archimedes2

这就是我启动容器的方式(注意使用 --add-host 使容器知道主机名):

docker run -e "SPRING_PROFILES_ACTIVE=archimedes1" -p 8761:8761 --name archimedes1 --add-host archimedes1:127.0.0.1 --add-host archimedes2:127.0.0.1 -d storyteller/archimedes 
docker run -e "SPRING_PROFILES_ACTIVE=archimedes2" -p 8762:8762 --name archimedes2 --add-host archimedes1:127.0.0.1 --add-host archimedes2:127.0.0.1 -d storyteller/archimedes

这适用于 Docker Toolbox,但由于我为 Windows 安装了 Docker 容器,因此在相互联系时会显示 Connection Refused 错误。在这种情况下,阿基米德斯 2 尝试调用阿基米德斯 1:

2017-01-25 13:10:27.406 DEBUG 5 --- [t_archimedes1-2] c.n.d.shared.MonitoredConnectionManager  : Get connection: {}->http://archimedes1:8761, timeout = 200
2017-01-25 13:10:27.406 DEBUG 5 --- [t_archimedes1-2] c.n.d.shared.NamedConnectionPool         : [{}->http://archimedes1:8761] total kept alive: 0, total issued: 0, total allocated: 0 out of 1000
2017-01-25 13:10:27.406 DEBUG 5 --- [t_archimedes1-2] c.n.d.shared.NamedConnectionPool         : No free connections [{}->http://archimedes1:8761][null]
2017-01-25 13:10:27.406 DEBUG 5 --- [t_archimedes1-2] c.n.d.shared.NamedConnectionPool         : Available capacity: 500 out of 500 [{}->http://archimedes1:8761][null]
2017-01-25 13:10:27.406 DEBUG 5 --- [t_archimedes1-2] c.n.d.shared.NamedConnectionPool         : Creating new connection [{}->http://archimedes1:8761]
2017-01-25 13:10:27.407 DEBUG 5 --- [t_archimedes1-2] c.n.d.shared.MonitoredConnectionManager  : Released connection is not reusable.
2017-01-25 13:10:27.407 DEBUG 5 --- [t_archimedes1-2] c.n.d.shared.NamedConnectionPool         : Releasing connection [{}->http://archimedes1:8761][null]
2017-01-25 13:10:27.407 DEBUG 5 --- [t_archimedes1-2] c.n.d.shared.NamedConnectionPool         : Notifying no-one, there are no waiting threads
2017-01-25 13:10:27.407 ERROR 5 --- [t_archimedes1-2] c.n.e.cluster.ReplicationTaskProcessor   : Network level connection to peer archimedes1; retrying after delay

com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused (Connection refused)
        at com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle(ApacheHttpClient4Handler.java:187) ~[jersey-apache-client4-1.19.1.jar!/:1.19.1]
        at com.netflix.eureka.cluster.DynamicGZIPContentEncodingFilter.handle(DynamicGZIPContentEncodingFilter.java:48) ~[eureka-core-1.4.12.jar!/:1.4.12]
        at com.netflix.discovery.EurekaIdentityHeaderFilter.handle(EurekaIdentityHeaderFilter.java:27) ~[eureka-client-1.4.12.jar!/:1.4.12]
        at com.sun.jersey.api.client.Client.handle(Client.java:652) ~[jersey-client-1.19.1.jar!/:1.19.1]
        at com.sun.jersey.api.client.WebResource.handle(WebResource.java:682) ~[jersey-client-1.19.1.jar!/:1.19.1]
        at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74) ~[jersey-client-1.19.1.jar!/:1.19.1]
        at com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:570) ~[jersey-client-1.19.1.jar!/:1.19.1]
        at com.netflix.eureka.transport.JerseyReplicationClient.submitBatchUpdates(JerseyReplicationClient.java:116) ~[eureka-core-1.4.12.jar!/:1.4.12]
        at com.netflix.eureka.cluster.ReplicationTaskProcessor.process(ReplicationTaskProcessor.java:71) ~[eureka-core-1.4.12.jar!/:1.4.12]
        at com.netflix.eureka.util.batcher.TaskExecutors$BatchWorkerRunnable.run(TaskExecutors.java:187) [eureka-core-1.4.12.jar!/:1.4.12]
        at java.lang.Thread.run(Thread.java:745) [na:1.8.0_121]
Caused by: java.net.ConnectException: Connection refused (Connection refused)

我在容器中启动了一个 sh 并从 archimedes2 的容器中对 archimedes1 执行 ping 操作,它确实回答了

-> docker exec -it archimedes2 sh
/ # ping archimedes1
PING archimedes1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: seq=0 ttl=64 time=0.072 ms

但是,如果我执行telnet,则会拒绝连接:

docker exec -it archimedes2 sh
/ # telnet archimedes1 8761
telnet: can't connect to remote host (127.0.0.1): Connection refused

如果我对自己的容器进行远程登录,它可以工作:

C:\Users\jinga4x>docker exec -it archimedes2 sh
/ # telnet archimedes2 8762

这里发生了什么?

更新:

我也对此进行了测试:将 archimedes1 启动为 Windows 上的普通 Java 应用程序,并在 container 中启动 archimedes2

阿基米德1可以联系阿基米德2,但阿基米德2在尝试连接阿基米德1 时被拒绝连接。

更新 2:

这是我的docker network inspect bridge信息:

[
    {
        "Name": "bridge",
        "Id": "546e7a5ef627c8d23e8ffdc05911fcae096167a359701fa4ee08ada0f7e1ae7f",
        "Created": "2017-01-25T11:09:27.651777Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Containers": {
            "58634d0c4430895cf0dfbee294c3ea75ca38921441684d614a670421661eb628": {
                "Name": "archimedes2",
                "EndpointID": "b2f40396b4c0f8210ca667d93c7d787296f3dad2d0eb295c31d4f01bfe3b39e1",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "85f70520ad900e729944dc768f8c6951e9221650269b5669a2d0269506a4c16b": {
                "Name": "archimedes1",
                "EndpointID": "651bf095eed639ecc61a24ffdaf2130bddd338f38f42f47a6c54b460c3a979ab",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

archimedes1 容器 ifconfig:

eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:133 errors:0 dropped:0 overruns:0 frame:0
          TX packets:105 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:13158 (12.8 KiB)  TX bytes:345156 (337.0 KiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:64 errors:0 dropped:0 overruns:0 frame:0
          TX packets:64 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:3200 (3.1 KiB)  TX bytes:3200 (3.1 KiB)

阿基米德1猫等/主机:

127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
127.0.0.1       archimedes1
127.0.0.1       archimedes2
172.17.0.2      a8045a473784

更新 3:

容器可以使用内部私有 IP 相互访问,但不能使用公共 IP (127.0.0.1)。

更新 4:

我启动了一个代理监控 archimedes1:22233 并将其流量发送到 archimedes1:8761。archimedes2 尝试通过代理进行通信,但没有流量到达它。

4

1 回答 1

0

要获得正确的 IP 地址,您需要使用docker-machine ip.

对于适用于 Windows 10 的新 Docker,获取容器 ID,docker ps然后在(== 要检查的容器 ID)IPAddress的输出中查找。docker inspect $CID$CID

背景:Docker 无法在 Windows 上运行容器。Docker 是一个纯 Linux 软件。它需要一个正在运行的 Linux 内核才能工作。Docker for Windows 使用的解决方法是在你的计算机上安装一个虚拟机(VirtualBox),它可以模拟整个 PC——包括网卡、硬盘驱动器、CPU 和所有东西。较新版本的软件使用类似的 Hyper-V。

在该虚拟 PC 内部,安装了完整的 Linux 和 Docker。Windows 工具将连接到该虚拟 PC 以与内部运行的 Docker 通信。

实际上,地址127.0.0.1不会离开容器——它甚至不会意味着“Docker 正在其中运行的虚拟 PC”。Ping 当然有效,因为每台计算机都会响应地址127.0.0.1- 这并不意味着它是您认为应该是的同一台计算机。

[编辑]文件/etc/hosts看起来不对:

10.0.75.1       archimedes1
10.0.75.1       archimedes2

那是两个不同的容器;他们应该有不同的IP地址。

我认为你的docker run. --add-host archimedes2:10.0.75.1应该--add-host archimedes2:10.0.75.2

于 2017-01-25T12:47:50.130 回答