docker和docker compose中使用host.docker.internal访问其他服务

在使用docker过程中,如果我们要访问宿主机,最直接的办法是查到docker0ip然后在docker中直接访问即可。

使用host.docker.internal

无host.docker.internal的情况

比如我们有一个nginx的容器,需要反向代理主机上的8081端口的一个服务。

linux下使用ip addr命令查到的docker0大概是这样的:

...
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:c2:6b:7b:52 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:c2ff:fe6b:7b52/64 scope link 
       valid_lft forever preferred_lft forever
...

可以看到,docker0网关的地址是172.17.0.1那么我们的nginx配置可以这么写:

upstream some_service {
    server 172.17.0.1:8081;
}

server {
    listen 9091 ssl;

    location / {
        proxy_pass http://some_service;
        proxy_set_header Host              http_host;
        proxy_set_header X-Real-IPremote_addr;
        proxy_set_header X-Forwarded-For   proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Protoscheme;
        proxy_redirect off;
    }
}

这么做大部分情况下是行得通的,但是如果刚好你的某个配置使用了172.17网段,或者你的服务器不是那么常见的发行版,docker网关就不一定是这个了,就需要再去确定它的地址,再去修改一遍所有使用主机服务的地方,这样显然不够环保。

在docker中使用host.docker.internal

还好,在docker 20.10 版本就开始支持在Linux上使用host.docker.internal

以下示例使用版本:

Docker version 24.0.7, build afdd53b
Docker Compose version v2.23.3

运行一个容器验证一下:

docker run -it --add-host=host.docker.internal:host-gateway nginx cat /etc/hosts

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.17.0.1  host.docker.internal
172.21.0.2  a348e1bfb96f

可以看到host.docker.internal正确的解析到了172.17.0.1上,那么上面的nginx配置就可以改成:

upstream some_service {
    server host.docker.internal:8081;
}

重启nginx容器后发现是一切正常。

在docker compose中使用host.docker.internal

docker compose中使用host.docker.internal是通过extra_hosts来指定的,比如刚才的nginx使用的docker-compose.yml

version: '3.8'

services:
    nginx:
        image: nginx:latest
        container_name: nginx
        ports:
            - {NGINX_PORTS}:{NGINX_PORTS}
        volumes:
            - {NGINX_DIR}/conf/nginx.conf:/etc/nginx/nginx.conf
            -{NGINX_DIR}/conf/conf.d:/etc/nginx/conf.d
            - {NGINX_DIR}/logs:/var/log/nginx
            -{NGINX_DIR}/ca:/etc/nginx/ca
            - ${NGINX_WWWROOT}:/usr/share/nginx/html
        extra_hosts:
            - "host.docker.internal:host-gateway"
            - "router:192.168.0.1"
        restart: always

这样的效果和上面的--add-host方式是一样的效果。

小彩蛋

上面的docker-compose.ymlextra_hosts下有一行router:192.168.0.1这个是干嘛的呢?恩,这个其实是使用nginx代理路由器web管理的,是的,除了可以添加宿主机上的服务,也可以添加网络可达的其他主机上的服务,加上内网穿透后,就可以愉快的使用https在外网的访问内网的路由器了。

docker和docker compose中使用host.docker.internal访问其他服务

原文链接:https://beltxman.com/4257.html,若无特殊说明本站内容为 行星带 原创,未经同意禁止转载。

发表评论

您的电子邮箱地址不会被公开。

Scroll to top