Docker容器访问宿主机网络的方法

最近部署一套系统,使用nginx作反向代理,其中nginx是使用docker方式运行:

$ docker run -d --name nginx $PWD:/etc/nginx -p 80:80 -p 443:443 nginx:1.15

需要代理的API服务运行在宿主机的 1234 端口, nginx.conf 相关配置如下:

server {
 ...

 location /api {
  proxy_pass http://localhost:1234
 }
 ...
}

结果访问的时候发现老是报 502 Bad Gateway 错误,错误日志显示无法连接到upstream。

仔细想一想, nginx.conf 中的 localhost 似乎有问题。由于nginx是运行在docker容器中的,这个 localhost 是容器的localhost,而不是宿主机的localhost。

到这里,就出现了本文要解决的问题:如何从容器中访问到宿主机的网络?通过搜索网络,有如下几种方法:

使用宿主机IP

在安装Docker的时候,会在宿主机安装一个虚拟网关 docker0 ,我们可以使用宿主机在 docker0 上的IP地址来代替 localhost 。

首先,使用如下命令查询宿主机IP地址:

$ ip addr show docker0
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
  link/ether 02:42:d5:4c:f2:1e brd ff:ff:ff:ff:ff:ff
  inet 172.17.0.1/16 scope global docker0
    valid_lft forever preferred_lft forever
  inet6 fe80::42:d5ff:fe4c:f21e/64 scope link
    valid_lft forever preferred_lft forever

可以发现宿主机的IP是 172.17.0.1 ,那么将 proxy_pass http://localhost:1234 改为 proxy_pass http://172.17.0.1:1234 就可以解决 502 Bad Gateway 错误。

但是,不同系统下宿主机的IP是不同的,例如Linux下一般是 172.17.0.1 , macOS下一般是 192.168.65.1 ,并且这个IP还可以更改。所以使用IP配置 nginx.conf ,不能跨环境通用。

使用host网络

Docker容器运行的时候有 host 、 bridge 、 none 三种网络可供配置。默认是 bridge ,即桥接网络,以桥接模式连接到宿主机; host 是宿主网络,即与宿主机共用网络; none 则表示无网络,容器将无法联网。

当容器使用 host 网络时,容器与宿主共用网络,这样就能在容器中访问宿主机网络,那么容器的 localhost 就是宿主机的 localhost 。

在docker中使用 --network host 来为容器配置 host 网络:

$ docker run -d --name nginx --network host nginx

上面的命令中,没有必要像前面一样使用 -p 80:80 -p 443:443 来映射端口,是因为本身与宿主机共用了网络,容器中暴露端口等同于宿主机暴露端口。

使用host网络不需要修改 nginx.conf ,仍然可以使用 localhost ,因而通用性比上一种方法好。但是,由于 host 网络没有 bridge 网络的隔离性好,使用 host 网络安全性不如 bridge 高。

总结

本文提出了使用宿主机IP和使用host网络两种方法,来实现从容器中访问宿主机的网络。两种方法各有优劣,使用宿主机IP隔离性更好,但通用性不好;使用host网络,通用性好,但带来了暴露宿主网络的风险。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解如何解决docker容器无法通过IP访问宿主机问题

    问题起源 在使用 docker 的过程中我不幸需要在 docker 容器中访问宿主机的 80 端口, 而这个 80 端口是另外一个容器 8080 端口映射出去的. 当我在容器里通过 docker 的网桥 172.17.0.1 访问宿主机时, 居然发现: curl: (7) Failed to connect to 172.17.0.1 port 80: No route to host 查找问题原因 可以确定的是容器与宿主机是有网络连接的, 因为可以在容器内部通过 172.17.0.1 Ping

  • 详解docker 容器不自动退出结束运行的方法

    本文主要简单介绍 docker 容器与前置进程的关系,以及如何编写 Dockerfile/docker-compose.yml 优雅的让容器可以常驻运行. docker 容器的生命周期是同容器中的前置进程相关在一起的,这也是我们平时可能会遇到一些容器只是运行几秒便自动结束的原因:因为容器中没有一个常驻的前置进程,前置进程运行结束后,容器便自动退出了. 比如 docker hello-world # 一闪而过 输出一堆东西 docker run --name hello-world hello-w

  • 基于spring-boot和docker-java实现对docker容器的动态管理和监控功能[附完整源码下载]

    docker简介 Docker 是一个开源的应用容器引擎,和传统的虚拟机技术相比,Docker 容器性能开销极低,因此也广受开发者喜爱.随着基于docker的开发者越来越多,docker的镜像也原来越丰富,未来各种企业级的完整解决方案都可以直接通过下载镜像拿来即用.因此docker变得越来越重要. 本文目的 本文通过一个项目实例来介绍如果通过docker对外接口来实现对docker容器的管理和监控. 应用场景: 对服务器资源池通过docker进行统一管理,按需分配资源和创建容器,达到资源最大化利

  • 详解Docker容器的日志处理

    Docker有很多的日志插件,默认使用 json-file,只有使用json-file时,sudo docker logs -f 才可以显示,输入以下命令查看docker日志插件: $ sudo docker info | grep Logging 这里先说明一下,当容器运行时,docker会在宿主机上创建一个该容器相关的文件,然后将容器产生的日志转存到该文件下.docker logs -f 命令就会找到该文件内容并显示在终端上. 我们都知道docker logs -f会将所有对应的服务日志输出

  • Linux上创建、列出、删除Docker容器方法总结

    1.启动Docker容器 使用下面的命令启动新的Docker容器.这将启动一个新的容器,并为你提供使用/bin/bash shell访问该容器的权限. # docker run [OPTIONS] <IMAGE NAME> [COMMAND] [ARG...] 例如,下面的命令将使用名为"ubuntu"的图像创建新的docker容器.要列出所有可用图像,请使用docker images命令. # docker run -i -t ubuntu /bin/bash 要退出Do

  • Docker 容器操作指令汇总详解

    1. 创建并运行 一个容器 docker run -it --rm centos:latest bash run 运行容器 -it 以交互方式运行容器 --rm 退出容器后删除容器 centos:latest 基于 镜像启动容器 bash 命令 交互式shell 2. 退出容器 exit 3. 查看容器 docker ps 查看正在运行的容器 docker ps -a 查看所有容器 4.删除容器 docker rm [容器id ] 5 . 查看 镜像 容器 数据卷 占用空间 docker sys

  • Docker容器应用日志查看方法

    docker attach命令 docker attach [options] 容器会连接到正在运行的容器,然后将容器的标准输入.输出和错误流信息附在本地打印出来.命令中options的取值有三种:--detach-keys,--no-stdin,--sig-proxy. 该命令只是进入容器终端,不会启动新的进程.所以当你同时使用多个窗口进入该容器,所有的窗口都会同步显示.如果一个窗口阻塞,那么其他窗口也就无法再进行操作. 使用ctrl+c可以直接断开连接,但是这样会导致容器退出,而且还stop

  • Docker容器修改配置文件的实现

    一.进入容器 docker run [option] 镜像名 [向启动容器中传入的命令] 常用可选参数说明: -i 表示以"交互模式"运行容器 -t 表示容器启动后会进入其命令行.加入这两个参数后,容器创建就能登录进去.即 分配一个伪终端. --name 为创建的容器命名 -v 表示目录映射关系(前者是宿主机目录,后者是映射到宿主机上的目录,即 宿主机目录:容器中目录),可以使 用多个-v 做多个目录或文件映射.注意:最好做目录映射,在宿主机上做修改,然后 共享到容器上. -d 在ru

  • Docker容器访问宿主机网络的方法

    最近部署一套系统,使用nginx作反向代理,其中nginx是使用docker方式运行: $ docker run -d --name nginx $PWD:/etc/nginx -p 80:80 -p 443:443 nginx:1.15 需要代理的API服务运行在宿主机的 1234 端口, nginx.conf 相关配置如下: server { ... location /api { proxy_pass http://localhost:1234 } ... } 结果访问的时候发现老是报 5

  • docker容器与宿主机的数据交互方式总结

    前言 在生产环境中使用 Docker ,往往需要对数据进行持久化,或者需要在多个容器之间进行数据共享,这必然涉及容器的数据管理操作. 方式一.Docker cp命令 docker cp :用于容器与主机之间的数据拷贝. 语法 # 容器内文件 copy to 宿主机 docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|- # 宿主机文件 copy to 容器内 docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_

  • 解决docker容器与宿主机相差8小时的问题

    使用docker-compose部署时,在输出的日志以及相关事件校验及输出时,导致事件与现实相差8小时. 排查问题: 1.查看宿主机时间: # 查看时间 date Wed Sep 29 11:12:44 CST 2021 # 查看时区 date -R Wed, 29 Sep 2021 11:13:34 +0800 2.进入容器查看时间 # 查看所有容器 docker ps -a # 进入容器 docker eec -it [容器ID] /bin/bash # 查看时间 date 此时看到的宿主机

  • Docker容器的网络管理和网络隔离的实现

    一.Docker网络的管理 1.Docker容器的方式 1)Docker访问外网 Docker容器连接到宿主机的Docker0网桥访问外网:默认自动将docker0网桥添加到docker容器中. 2)容器和容器之间通信 需要管理员创建网桥:将不同的容器连接到网桥上实现容器和容器之间相互访问. 3)外部网络访问容器 通过端口映射或者同步docker宿主机网络配置实现通信. 2.Docker容器网络通信的模式 1)bridge 默认容器访问外网通信使用:依赖docker0网桥. 2)none 需要给

  • docker内服务访问宿主机服务的实现

    目录 1. 场景 2. 解决 3. 总结 4. 参考 1. 场景 使用windows, wsl2 进行日常开发测试工作. 但是wsl2经常会遇到网络问题.比如今天在测试一个项目,核心功能是将postgres 的数据使用开源组件synch 同步到clickhouse 这个工作. 测试所需组件 postgres kafka zookeeper redis synch容器 最开始测试时,选择的方案是, 将上述五个服务使用 docker-compose 进行编排, network_modules使用ho

  • Docker容器互相连接三种实现方法详解

    docker容器间的互连通信有三种方法: docker内部网络:不够灵活强大,不推荐 docker networking:1.9或更新版本,推荐使用 docker链接:1.9之前版本适用. 1.docker内部网络 涉及docker自己的网络栈. 安装docker后,系统会创建一个新的网络接口,名字是docker0,用于连接容器和宿主机,IP范围是172.16-172.30, 每个docker容器都会在这个接口上分配一个IP地址. docker每创建一个容器就会创建一组互联的网络接口,一端是容器

  • Docker容器使用宿主机上的mongod/redis等服务详解

    我们在本地的开发中为了保证大家都开发环境一直,PHP 的扩展,版本保持一致, 我们使用了 docker .但是由于redis/mongodb 在宿主机上, 所以通过 127.0.0.1 是连接不上的 前提说明 这个是在 docker 运行容器时使用的桥接模式(默认) 时才会发生以上问题.如果使用 host 模式就没有. 所以,我们就是要把是 docker 的网络模式设置为 host 模式. 具体实现 ~ docker run --network host php56 补充说明 使用了 host

  • docker部署访问postgres数据库的实现方法

    目录 部署与访问 启用日志 如果需要修改pg配置 重启pg 代码&外部连接时注意(温馨提示) 部署与访问 宿主机创建postgres用户: adduser postgres 拉取镜像,此处以12.1版本为例: docker pull postgres:12.1 创建所用的卷 docker volume create pgdata_test_env 启动(密码为123456): docker run --user=0 -p 45565:5432 -d --name pg_test --restar

  • docker容器挂载宿主主机目录的操作方法

    有一项重要的参数 -v 目录挂载,就是让容器内部目录和宿主主机目录关联起来,这样就可以直接操作宿主主机目录而不用再操作具体容器了 比如在2中,我们要发布一个war包,是通过 sudo docker cp demo.war tomcat_xiao:/usr/local/tomcat/webapps 来发布的,有没有更快捷的方式呢? 肯定有, 没有 我就不会在这里写这些玩意儿了 sudo docker run -p 8822:8080 --name tomcat_xiao_volume -v /ho

随机推荐