从Docker容器内连接宿主机的localhost

从Docker容器内连接宿主机的localhost

技术背景

在使用Docker进行开发和部署时,经常会遇到需要从容器内部连接到宿主机上运行的服务的场景。例如,一个运行在Docker容器内的Nginx实例需要连接到宿主机上运行的MySQL数据库。由于容器有自己独立的网络命名空间,默认情况下,容器内的localhost指向容器自身,而不是宿主机。因此,需要一些特定的配置和方法来实现从容器内连接到宿主机的localhost

实现步骤

不同操作系统和Docker版本的通用方法

Docker v 20.10及以上(所有平台)
  • 开发环境中,可以使用特殊的DNS名称host.docker.internal,它会解析为宿主机使用的内部IP地址。
    • Linux系统:在docker run命令中添加--add-host=host.docker.internal:host-gateway参数,或者在docker-compose.yml文件的容器定义中添加以下内容:
extra_hosts:
    - "host.docker.internal:host-gateway"
- **注意**:部分用户反馈,该特殊DNS名称仅在Docker的默认桥接网络中有效,在自定义网络中可能无法使用。
旧版本的macOS和Windows Docker
  • Docker v 18.03及以上:同样可以使用host.docker.internal。不过在Linux系统中,当时还不支持该特性。
  • Docker for Mac v 17.12至v 18.02:使用docker.for.mac.host.internal
  • Docker for Mac v 17.06至v 17.11:使用docker.for.mac.localhost
  • Docker for Mac 17.05及以下
    1. 为网络接口附加一个IP地址别名,例如:
sudo ifconfig lo0 alias 123.123.123.123/24
2. 确保服务监听该IP地址或`0.0.0.0`。如果服务仅监听`localhost`(`127.0.0.1`),将无法接受连接。
3. 在容器中指向该IP地址,即可访问宿主机。可以在容器内运行`curl -X GET 123.123.123.123:3000`进行测试。
4. 该别名在每次重启后会重置,如有需要,可以创建一个启动脚本。

Docker网络模式相关方法

--network="bridge"(默认模式)
  1. Docker默认会创建一个名为docker0的桥接网络。可以在宿主机上使用sudo ip addr show docker0查看其IP地址:
[vagrant@docker:~] $ sudo ip addr show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.1/16 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::5484:7aff:fefe:9799/64 scope link
       valid_lft forever preferred_lft forever
这里宿主机在`docker0`网络接口上的IP地址是`172.17.42.1`。
  1. 启动一个新容器并进入其shell:docker run --rm -it ubuntu:trusty bash,在容器内使用ip addr show eth0查看其主网络接口的配置:
root@e77f6a1b3740:/# ip addr show eth0
863: eth0: <BROADCAST,UP

你可能感兴趣的:(docker,容器,运维)