【问题标题】:How to access ports in docker custom bridge networks如何访问 docker 自定义桥接网络中的端口
【发布时间】:2016-01-17 03:52:28
【问题描述】:

新的Docker 文档说您仍然可以在默认的bridge 网络中使用--link,但创建自己的bridge network 更安全。然后它说在自定义bridge 网络中,您不能再使用--link 在内部映射port

所以我想创建一个安全隔离的自定义bridge 网络,可以与彼此的端口通信。

例如,我在bridge 网络中有一个nginx 容器,但它也是包含angular 应用程序的private network 的一部分。如何在不全局公开angular 端口的情况下将proxynginx 调用到angular container 上的指定端口(例如port 8080)?

更新:

我了解如何在同一网络中创建容器,然后使用它们的容器名称通过ping 相互连接。我不明白的是如何访问另一个容器的port。例如,如果web2nginx 都在同一个网络上,我可以从nginx ping web2 很好,但是如果我从nginx 运行curl web2:4200,我会得到Failed to connect to web2 port 4200: Connection refused。如何在不将port 4200 暴露给外界的情况下打开port 4200

nginx 配置文件

upstream web {
    server web2:4200;
}

upstream api {
    server api:3000;
}



server {
    listen       80;
    server_name  url.com;

    location /api {
        proxy_pass http://api;
    }

    location / {
        proxy_pass http://web;
    }
}

web 2 网络设置

 "NetworkSettings": {
        "Bridge": "",
        "SandboxID": "f290157dd8f9b181bd544ee0b9814b1581adf61cee05c07e67a93df6bf85ecd3",
        "HairpinMode": false,
        "LinkLocalIPv6Address": "",
        "LinkLocalIPv6PrefixLen": 0,
        "Ports": {},
        "SandboxKey": "/var/run/docker/netns/f290157dd8f9",
        "SecondaryIPAddresses": null,
        "SecondaryIPv6Addresses": null,
        "EndpointID": "",
        "Gateway": "",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "IPAddress": "",
        "IPPrefixLen": 0,
        "IPv6Gateway": "",
        "MacAddress": "",
        "Networks": {
            "application-network": {
                "EndpointID": "622f0afd4016eafc525b45c32c465c58b89ab543358ba860d31edac8ce877d83",
                "Gateway": "172.19.0.1",
                "IPAddress": "172.19.0.2",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "MacAddress": "02:42:ac:13:00:02"
            }
        }
    }

nginx 网络设置

"NetworkSettings": {
    "Bridge": "",
    "SandboxID": "94f2d21562f6af5334547110893470b3bece02a081620daec98446ecd7b3f14b",
    "HairpinMode": false,
    "LinkLocalIPv6Address": "",
    "LinkLocalIPv6PrefixLen": 0,
    "Ports": {
        "443/tcp": null,
        "80/tcp": null
    },
    "SandboxKey": "/var/run/docker/netns/94f2d21562f6",
    "SecondaryIPAddresses": null,
    "SecondaryIPv6Addresses": null,
    "EndpointID": "cfe8ec49e341aed2dd56bd61d1dff6867ddd0246c5a04ff8cebdeee571475bdb",
    "Gateway": "172.17.0.1",
    "GlobalIPv6Address": "",
    "GlobalIPv6PrefixLen": 0,
    "IPAddress": "172.17.0.3",
    "IPPrefixLen": 16,
    "IPv6Gateway": "",
    "MacAddress": "02:42:ac:11:00:03",
    "Networks": {
        "application-network": {
            "EndpointID": "6242229877c5a29bfae1c0742d558daedf50fbe607b42722449367e5dda79371",
            "Gateway": "172.19.0.1",
            "IPAddress": "172.19.0.3",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "MacAddress": "02:42:ac:13:00:03"
        },
        "bridge": {
            "EndpointID": "cfe8ec49e341aed2dd56bd61d1dff6867ddd0246c5a04ff8cebdeee571475bdb",
            "Gateway": "172.17.0.1",
            "IPAddress": "172.17.0.3",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "MacAddress": "02:42:ac:11:00:03"
        }
    }
}

我已将此问题移至此处以进一步隔离问题:docker container in same network cannot reach other container in same network

【问题讨论】:

  • 你不必打开(发布)80端口,只要nginx容器监听80端口(例如listen 0.0.0.0:80),网络中的其他容器就可以连接到它。你用的是官方的nginx图片吗?因为这对我来说是开箱即用的
  • @thaJeztah 我会运行docker run -it -H 0.0.0.0:80 nginx 让它监听那个端口吗?如何在端口 80 上将 nginx 获取到 listen
  • -H 仅用于守护进程,用于指定 API 可访问的 IP 地址。对于官方的 nginx 镜像,不需要配置。这行得通; docker network create adocker run -d --name=web2 --net=a nginxdocker run --rm --net=a ubuntu sh -c "apt-get install -yq curl && curl web2"
  • 此时已经超出了Docker配置的范围,在nginx的配置中。 nginx 在server 指令中是否有listen 80; 之类的行?
  • @AndyShinn 好的,我添加了 nginx 配置文件

标签: networking nginx docker digital-ocean


【解决方案1】:

如果两个容器都连接到同一个网络,它们可以通过名称相互访问。

例如;

  1. 创建你自己的“桥”网络(桥是默认的)

    docker network create mybridge
    
  2. 在此网络上启动一个容器,并将其命名为containera

    docker run -d --net=mybridge --name=containera nginx
    
  3. 在同一网络上启动另一个容器,并尝试“ping”容器a

    docker run -it --rm --net=mybridge ubuntu
    
    root@1331cebaa93a:/# ping -w 4 containera
    PING containera (172.20.0.2) 56(84) bytes of data.
    64 bytes from containera.mybridge (172.20.0.2): icmp_seq=1 ttl=64 time=0.087 ms
    64 bytes from containera.mybridge (172.20.0.2): icmp_seq=2 ttl=64 time=0.129 ms
    64 bytes from containera.mybridge (172.20.0.2): icmp_seq=3 ttl=64 time=0.130 ms
    64 bytes from containera.mybridge (172.20.0.2): icmp_seq=4 ttl=64 time=0.130 ms
    
    --- containera ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 3130ms
    rtt min/avg/max/mdev = 0.087/0.119/0.130/0.018 ms
    

在此处阅读有关 docker 网络的更多信息:https://docs.docker.com/engine/userguide/networking/dockernetworks/

docker 1.10 中的容器“别名”

目前(docker 1.9.1),只能使用它们的“名称”作为主机来访问容器。但是,docker 1.10 将支持为容器添加别名,无论是网络范围还是容器范围,使用与当前 --link 相同的语法; --link <container>:<alias>.

有关即将推出的容器别名功能的更多信息,请点击此处; https://github.com/docker/docker/blob/master/docs/userguide/networking/work-with-networks.md#linking-containers-in-user-defined-networks

【讨论】:

    【解决方案2】:

    链接不是必需的,因为自定义网络中的容器可以通过 DNS 发现(它们的条目被填充到 /etc/hosts 文件中)。这是一个例子:

    创建一个新网络:

    docker network create test
    

    在该网络中启动一个无所事事的容器:

    docker run -d --name sleeper --net test alpine sh -c "while true; do echo $(date); sleep 20; done"
    

    使用交互式 shell 运行另一个容器并检查 hosts 文件和与 sleeper 容器的连接:

    docker run -i -t --net test alpine sh
    / # cat /etc/hosts
    172.18.0.4  cc90db123006
    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
    172.18.0.2  test3
    172.18.0.2  test3.test
    172.18.0.3  sleeper
    172.18.0.3  sleeper.test
    / # ping sleeper
    PING sleeper (172.18.0.3): 56 data bytes
    64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.103 ms
    64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.107 ms
    ^C
    --- sleeper ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.103/0.105/0.107 ms
    

    因此,在此示例中,sleeper 容器类似于您的 angular 容器。 Nginx 只会代理到angular 以及它在容器内运行的端口。无需端口映射。

    您使用的端口将是angular 应用程序正在侦听的端口。因此,如果该应用程序在端口 80 上运行 nginx,那么您只需连接到端口 80。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-05
    • 2018-11-25
    • 1970-01-01
    • 1970-01-01
    • 2018-12-28
    • 2019-01-14
    • 1970-01-01
    相关资源
    最近更新 更多