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网络,通用性好,但带来了暴露宿主网络的风险。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
- ASP.NET Core中的依赖注入(1):控制反转(IoC)
- Web-Fontmin -- 在线提取你需要的字体
- 让Kaggle比赛第二名获奖者告诉你:买下一个冰淇淋的最佳时间是什么时候?
- 3种方式提升云可扩展性
- 数字图像相关技术DIC分析介绍
- 3种提升云可扩展性的方法
- 用一个命令使用 Docker Compose 安装Mesos
- C语言/C加加新手入门学习经验资料分享,基础知识大汇总!
- 云数据服务蜂拥而至...好难选呀
- ASP.NET MVC的Razor引擎:View编译原理
- ASP.NET Core中的依赖注入(4): 构造函数的选择与服务生命周期管理
- 通过Knockout.js + ASP.NET Web API构建一个简单的CRUD应用
- 自动驾驶车辆在2017年的七大光辉历史时刻
- 简单的实现Javascript的MVC
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 如何卸载python插件
- Keras实现支持masking的Flatten层代码
- 用opencv给图片换背景色的示例代码
- 解决Keras 自定义层时遇到版本的问题
- Laravel框架运行出错提示RuntimeException No application encryption key has been specified.解决方法
- Laravel访问出错提示:`Warning: require(/vendor/autoload.php): failed to open stream: No such file or di解决方法
- python实现PDF中表格转化为Excel的方法
- php实现算术验证码功能
- 基于matplotlib中ion()和ioff()的使用详解
- Laravel5.7框架安装与使用学习笔记图文详解
- Python基于httpx模块实现发送请求
- Python Tkinter图形工具使用方法及实例解析
- PHP实现的简单留言板功能示例【基于thinkPHP框架】
- Python SMTP配置参数并发送邮件
- Python如何实现自带HTTP文件传输服务