Ubuntu 上的 Docker 无法连接到本地主机,但可以连接到其 IP

ibe*_*dev 6 linux docker ubuntu-18.04

我运行的是 Ubuntu 18.04

\n\n
$ uname -r\n5.3.0-46-generic\n
Run Code Online (Sandbox Code Playgroud)\n\n

我已经安装了docker

\n\n
$ docker --version\nDocker version 19.03.8, build afacb8b7f0\n
Run Code Online (Sandbox Code Playgroud)\n\n

我有一个简单的 docker 映像,它公开端口 80。生成它的 Dockerfile 是

\n\n
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1\nCOPY publish .\nEXPOSE 80\nENTRYPOINT ["dotnet", "SampleWebApp.dll"]\n
Run Code Online (Sandbox Code Playgroud)\n\n

当我为此图像运行容器时,我可以看到以下内容:

\n\n
$ docker run myimage:latest -p 8080:80\ninfo: Microsoft.Hosting.Lifetime[0]\n      Now listening on: http://[::]:80\ninfo: Microsoft.Hosting.Lifetime[0]\n      Application started. Press Ctrl+C to shut down.\ninfo: Microsoft.Hosting.Lifetime[0]\n      Hosting environment: Production\ninfo: Microsoft.Hosting.Lifetime[0]\n      Content root path: /\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果我看到容器正在运行:

\n\n
$ docker ps\nCONTAINER ID        IMAGE                                                                              COMMAND                  CREATED             STATUS              PORTS               NAMES\n6f5bea7b329d        registry.gitlab.com/whatever/myimage:latest   "dotnet SampleWebApp\xe2\x80\xa6"   4 seconds ago       Up 2 seconds        80/tcp              dreamy_leavitt\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以我可以看到它在端口 80/tcp 上运行。\n不知道为什么它不在端口 8080 上运行,而这正是我想要映射它的地方。

\n\n

另外,http://[::]:80似乎令人困惑。我读过一些关于 IPv6 的内容。不知道这会产生什么后果,也不知道为什么普通的 IPv4 不起作用。

\n\n

我的界面信息:

\n\n
$ ifconfig\ndocker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500\n        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255\n        inet6 fe80::42:71ff:fe7f:305  prefixlen 64  scopeid 0x20<link>\n        ether 02:42:71:7f:03:05  txqueuelen 0  (Ethernet)\n        RX packets 131843  bytes 105630866 (105.6 MB)\n        RX errors 0  dropped 0  overruns 0  frame 0\n        TX packets 201439  bytes 268197990 (268.1 MB)\n        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0\n\nenp3s0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500\n        ether 1c:1b:0d:a4:83:16  txqueuelen 1000  (Ethernet)\n        RX packets 0  bytes 0 (0.0 B)\n        RX errors 0  dropped 0  overruns 0  frame 0\n        TX packets 0  bytes 0 (0.0 B)\n        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0\n\nlo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536\n        inet 127.0.0.1  netmask 255.0.0.0\n        inet6 ::1  prefixlen 128  scopeid 0x10<host>\n        loop  txqueuelen 1000  (Local Loopback)\n        RX packets 118628  bytes 17999594 (17.9 MB)\n        RX errors 0  dropped 0  overruns 0  frame 0\n        TX packets 118628  bytes 17999594 (17.9 MB)\n        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0\n\nvethca5fd09: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500\n        inet6 fe80::3c56:d6ff:fe0c:846  prefixlen 64  scopeid 0x20<link>\n        ether 3e:56:d6:0c:08:46  txqueuelen 0  (Ethernet)\n        RX packets 7  bytes 533 (533.0 B)\n        RX errors 0  dropped 0  overruns 0  frame 0\n        TX packets 52  bytes 7342 (7.3 KB)\n        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0\n\nwlp6s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500\n        inet 192.168.1.135  netmask 255.255.255.0  broadcast 192.168.1.255\n        inet6 fe80::8a58:c682:3833:3bb1  prefixlen 64  scopeid 0x20<link>\n        ether e4:be:ed:4f:0f:21  txqueuelen 1000  (Ethernet)\n        RX packets 519710  bytes 524989683 (524.9 MB)\n        RX errors 0  dropped 0  overruns 0  frame 0\n        TX packets 439859  bytes 165781721 (165.7 MB)\n        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以..docker接口似乎有地址172.17.0.1

\n\n

但是我无法使用以下网址访问我的容器:

\n\n
$ curl http://localhost:8080\ncurl: (7) Failed to connect to localhost port 8080: Connection refused\n\n$ curl http://localhost:80\ncurl: (7) Failed to connect to localhost port 80: Connection refused\n\n$ curl http://0.0.0.0:80\ncurl: (7) Failed to connect to 0.0.0.0 port 80: Connection refused\n\n$ curl http://0.0.0.0:8080\ncurl: (7) Failed to connect to 0.0.0.0 port 8080: Connection refused\n\n$ curl http://172.17.0.1:8080\ncurl: (7) Failed to connect to 172.17.0.1 port 8080: Connection refused\n\n$ curl http://172.17.0.1:80\ncurl: (7) Failed to connect to 172.17.0.1 port 80: Connection refused\n\n$ curl http://127.0.0.1:8080\ncurl: (7) Failed to connect to 127.0.0.1 port 8080: Connection refused\n\n$ curl http://127.0.0.1:80\ncurl: (7) Failed to connect to 127.0.0.1 port 80: Connection refused\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此无法使用localhost127.0.0.1或 docker 接口 IP 进行访问。

\n\n

如果我检查容器:

\n\n
sasw@Z3:~$ docker inspect 6f5bea7b329d\n[\n    {\n        "Id": "6f5bea7b329d05bcb534953745f376da9c7efbe54de5532f8648b618152b722a",\n        "Created": "2020-04-20T13:06:37.883347676Z",\n        "Path": "dotnet",\n        "Args": [\n            "SampleWebApp.dll",\n            "-p",\n            "8080:80"\n        ],\n        "State": {\n            "Status": "running",\n            "Running": true,\n            "Paused": false,\n            "Restarting": false,\n            "OOMKilled": false,\n            "Dead": false,\n            "Pid": 30636,\n            "ExitCode": 0,\n            "Error": "",\n            "StartedAt": "2020-04-20T13:06:38.295411125Z",\n            "FinishedAt": "0001-01-01T00:00:00Z"\n        },\n        "Image": "sha256:e00403d6c5eb3ccbe3c5c7b6ec8cf8289158e4c9fbe6ff5872ea932e69d60f38",\n        "ResolvConfPath": "/var/lib/docker/containers/6f5bea7b329d05bcb534953745f376da9c7efbe54de5532f8648b618152b722a/resolv.conf",\n        "HostnamePath": "/var/lib/docker/containers/6f5bea7b329d05bcb534953745f376da9c7efbe54de5532f8648b618152b722a/hostname",\n        "HostsPath": "/var/lib/docker/containers/6f5bea7b329d05bcb534953745f376da9c7efbe54de5532f8648b618152b722a/hosts",\n        "LogPath": "/var/lib/docker/containers/6f5bea7b329d05bcb534953745f376da9c7efbe54de5532f8648b618152b722a/6f5bea7b329d05bcb534953745f376da9c7efbe54de5532f8648b618152b722a-json.log",\n        "Name": "/dreamy_leavitt",\n        "RestartCount": 0,\n        "Driver": "overlay2",\n        "Platform": "linux",\n        "MountLabel": "",\n        "ProcessLabel": "",\n        "AppArmorProfile": "docker-default",\n        "ExecIDs": null,\n        "HostConfig": {\n            "Binds": null,\n            "ContainerIDFile": "",\n            "LogConfig": {\n                "Type": "json-file",\n                "Config": {}\n            },\n            "NetworkMode": "default",\n            "PortBindings": {},\n            "RestartPolicy": {\n                "Name": "no",\n                "MaximumRetryCount": 0\n            },\n            "AutoRemove": false,\n            "VolumeDriver": "",\n            "VolumesFrom": null,\n            "CapAdd": null,\n            "CapDrop": null,\n            "Capabilities": null,\n            "Dns": [],\n            "DnsOptions": [],\n            "DnsSearch": [],\n            "ExtraHosts": null,\n            "GroupAdd": null,\n            "IpcMode": "private",\n            "Cgroup": "",\n            "Links": null,\n            "OomScoreAdj": 0,\n            "PidMode": "",\n            "Privileged": false,\n            "PublishAllPorts": false,\n            "ReadonlyRootfs": false,\n            "SecurityOpt": null,\n            "UTSMode": "",\n            "UsernsMode": "",\n            "ShmSize": 67108864,\n            "Runtime": "runc",\n            "ConsoleSize": [\n                0,\n                0\n            ],\n            "Isolation": "",\n            "CpuShares": 0,\n            "Memory": 0,\n            "NanoCpus": 0,\n            "CgroupParent": "",\n            "BlkioWeight": 0,\n            "BlkioWeightDevice": [],\n            "BlkioDeviceReadBps": null,\n            "BlkioDeviceWriteBps": null,\n            "BlkioDeviceReadIOps": null,\n            "BlkioDeviceWriteIOps": null,\n            "CpuPeriod": 0,\n            "CpuQuota": 0,\n            "CpuRealtimePeriod": 0,\n            "CpuRealtimeRuntime": 0,\n            "CpusetCpus": "",\n            "CpusetMems": "",\n            "Devices": [],\n            "DeviceCgroupRules": null,\n            "DeviceRequests": null,\n            "KernelMemory": 0,\n            "KernelMemoryTCP": 0,\n            "MemoryReservation": 0,\n            "MemorySwap": 0,\n            "MemorySwappiness": null,\n            "OomKillDisable": false,\n            "PidsLimit": null,\n            "Ulimits": null,\n            "CpuCount": 0,\n            "CpuPercent": 0,\n            "IOMaximumIOps": 0,\n            "IOMaximumBandwidth": 0,\n            "MaskedPaths": [\n                "/proc/asound",\n                "/proc/acpi",\n                "/proc/kcore",\n                "/proc/keys",\n                "/proc/latency_stats",\n                "/proc/timer_list",\n                "/proc/timer_stats",\n                "/proc/sched_debug",\n                "/proc/scsi",\n                "/sys/firmware"\n            ],\n            "ReadonlyPaths": [\n                "/proc/bus",\n                "/proc/fs",\n                "/proc/irq",\n                "/proc/sys",\n                "/proc/sysrq-trigger"\n            ]\n        },\n        "GraphDriver": {\n            "Data": {\n                "LowerDir": "/var/lib/docker/overlay2/8f56c544522ccb6556358601706cb900c405c19b47e54c25d8b3dac979100e5b-init/diff:/var/lib/docker/overlay2/81bfee49e33d9761a6ca78dfd6f3f9a54a9333b4d4fc9986e8084f6b45232f04/diff:/var/lib/docker/overlay2/c2add2cb2d687126c6826c7dd9e1c85be1473a53d6b878554aa87615701344a0/diff:/var/lib/docker/overlay2/ebd0b92c5111423fb8d1219f757e41013a1473bdbe5cf3553cecbd4337f76766/diff:/var/lib/docker/overlay2/9197af6ebe4c70f0a84c7c267b1ba069aa710d917abe9fb3fee13320a17ab765/diff:/var/lib/docker/overlay2/1f463e8667b6eecc7c251ac05316b8d5d32840bff13d9f5cb7853c88e6f1f40e/diff:/var/lib/docker/overlay2/b7c9450f53334bef02f50cc854b33140b97f4ff3d2343b3fcac7b20f647c454e/diff",\n                "MergedDir": "/var/lib/docker/overlay2/8f56c544522ccb6556358601706cb900c405c19b47e54c25d8b3dac979100e5b/merged",\n                "UpperDir": "/var/lib/docker/overlay2/8f56c544522ccb6556358601706cb900c405c19b47e54c25d8b3dac979100e5b/diff",\n                "WorkDir": "/var/lib/docker/overlay2/8f56c544522ccb6556358601706cb900c405c19b47e54c25d8b3dac979100e5b/work"\n            },\n            "Name": "overlay2"\n        },\n        "Mounts": [],\n        "Config": {\n            "Hostname": "6f5bea7b329d",\n            "Domainname": "",\n            "User": "",\n            "AttachStdin": false,\n            "AttachStdout": true,\n            "AttachStderr": true,\n            "ExposedPorts": {\n                "80/tcp": {}\n            },\n            "Tty": false,\n            "OpenStdin": false,\n            "StdinOnce": false,\n            "Env": [\n                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",\n                "ASPNETCORE_URLS=http://+:80",\n                "DOTNET_RUNNING_IN_CONTAINER=true"\n            ],\n            "Cmd": [\n                "-p",\n                "8080:80"\n            ],\n            "Image": "registry.gitlab.com/ddd-malaga/continuous-deployment-gitlab-docker-dotnet:latest",\n            "Volumes": null,\n            "WorkingDir": "",\n            "Entrypoint": [\n                "dotnet",\n                "SampleWebApp.dll"\n            ],\n            "OnBuild": null,\n            "Labels": {}\n        },\n        "NetworkSettings": {\n            "Bridge": "",\n            "SandboxID": "4e53bd2bc6cb83b7c0cba9fcdf07eb564a11ca6b955514670ba3f464aa0a96b7",\n            "HairpinMode": false,\n            "LinkLocalIPv6Address": "",\n            "LinkLocalIPv6PrefixLen": 0,\n            "Ports": {\n                "80/tcp": null\n            },\n            "SandboxKey": "/var/run/docker/netns/4e53bd2bc6cb",\n            "SecondaryIPAddresses": null,\n            "SecondaryIPv6Addresses": null,\n            "EndpointID": "83976112bb202b79880777563cd1b06ef27781fd288b210b19fb499e3bf51c90",\n            "Gateway": "172.17.0.1",\n            "GlobalIPv6Address": "",\n            "GlobalIPv6PrefixLen": 0,\n            "IPAddress": "172.17.0.2",\n            "IPPrefixLen": 16,\n            "IPv6Gateway": "",\n            "MacAddress": "02:42:ac:11:00:02",\n            "Networks": {\n                "bridge": {\n                    "IPAMConfig": null,\n                    "Links": null,\n                    "Aliases": null,\n                    "NetworkID": "7589efd57cea8d2b04823657fcfc54225991bc58c93ff0e463b6f12acb28b853",\n                    "EndpointID": "83976112bb202b79880777563cd1b06ef27781fd288b210b19fb499e3bf51c90",\n                    "Gateway": "172.17.0.1",\n                    "IPAddress": "172.17.0.2",\n                    "IPPrefixLen": 16,\n                    "IPv6Gateway": "",\n                    "GlobalIPv6Address": "",\n                    "GlobalIPv6PrefixLen": 0,\n                    "MacAddress": "02:42:ac:11:00:02",\n                    "DriverOpts": null\n                }\n            }\n        }\n    }\n]\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

我可以看到 IP 地址172.17.0.2。再说一遍,我不知道这是从哪里来的。

\n\n

但现在我可以尝试在我告诉它映射的端口访问容器 IP:

\n\n
$ curl http://172.17.0.2:8080\ncurl: (7) Failed to connect to 172.17.0.2 port 8080: Connection refused\n
Run Code Online (Sandbox Code Playgroud)\n\n

令人惊讶的是,如果我访问相同的容器 IP,但暴露的端口 80 它可以工作

\n\n
sasw@Z3:/$ curl http://172.17.0.2:80\nHello World!\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果我停止并删除完整的容器和图像,然后使用以下随机端口重试:

\n\n
$ docker run myimage:latest -p 1234:1234\nStatus: Downloaded newer image for registry.gitlab.com/myimage:latest\ninfo: Microsoft.Hosting.Lifetime[0]\n      Now listening on: http://[::]:80\ninfo: Microsoft.Hosting.Lifetime[0]\n      Application started. Press Ctrl+C to shut down.\ninfo: Microsoft.Hosting.Lifetime[0]\n      Hosting environment: Production\ninfo: Microsoft.Hosting.Lifetime[0]\n      Content root path: /\n
Run Code Online (Sandbox Code Playgroud)\n\n

似乎这些端口被完全忽略,它仍然监听容器 IP 和端口 80

\n\n
$ curl http://172.17.0.2:80\nHello World!\n
Run Code Online (Sandbox Code Playgroud)\n\n

很明显,我在这里缺少一些知识,并且我发现的链接不是很有用,或者让我了解有关 IPv6 的内容,例如https://docs.docker.com/config/daemon/ipv6/,其中提到了一些有关我什/etc/docker/daemon.json至没有。

\n\n

有人能指出正确的方向来理解发生了什么以及为什么吗?谢谢!

\n

ibe*_*dev 8

问题似乎是我的论点都没有docker run生效,因为我把它们放在图像后面。疯狂的!

所以这:

docker run myimage:latest -p 8080:80 --name whatever
Run Code Online (Sandbox Code Playgroud)

将运行容器,完全忽略端口映射和容器分配的名称。

然而这个:

docker run -p 8080:80 --name whatever myimage:latest
Run Code Online (Sandbox Code Playgroud)

将端口 80 映射到我的 localhost:8080,以便 Web 应用程序可以在https://localhost:8080上使用

  • 这是预期的行为。如果你输入 `docker run --help` 你会发现 `docker run [OPTIONS] IMAGE [COMMAND] [ARG...]` 和 `-p` 是一个必须出现在镜像之前的选项。 (2认同)