首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Docker入门——网络相关

Docker入门——网络相关

原创
作者头像
cocoon_yh
发布于 2019-09-09 13:04:40
发布于 2019-09-09 13:04:40
1.4K0
举报

背景

某次在试图从容器内访问到本地的数据库时,发现在本机上并没有 docker0 这个网桥。学习了一波 Docker 网络相关的知识后作出了以下总结。

相信下面这张图大家没少看过,Docker 相较于 VM 更加轻量,不需要虚拟出自己的操作系统层,具有更多的优点。

docker.png
docker.png

上图来源于网络,后文中也将对来源于网络的图做出说明

然而笔者想当然的就以为 Docker 在所有系统下都是这种架构。查阅相关资料后发现,Dockerlinux 环境下确实是这样运行的,但是在 WindowsmacOS 系统下,Docker 会先启一个 VM ,然后在该 VM 上运行 Docker 环境。新版的 Docker for Mac 已经不再使用 VirtualBox 提供虚拟机环境,而是使用更轻量的 HyperKit ,设计上更为巧妙,本文就不展开讲这个点了。下图是 Docker for Mac 的架构图。

-1.png
-1.png

因此 docker0 网桥是在虚拟机内,而不是在宿主机内。可想而知,运行在虚拟机中与运行在本机上肯定是有区别的,因此 Docker for Mac 实际上自带了 k8s 环境,并且通过端口转发到宿主机,以屏蔽用户对 VM 的感知。然而要实现容器到宿主机的通信,还需要进行另一番调研。

下面先介绍一下 Docker 支持的几种网络模式。

Docker 支持的网络模式

Network

Description

none

no networking in the container

bridge

Connect the container to the bridge via veth interfaces

host

Use the host's network stack inside the container

Container:<name\id>

Use the network stack of another container, specified via its name or id

Network

Connects the container to a user created network(using docker network create command)

NETWORK: NONE

这种网络模式下无法联网,仅有一个 loopback 回环网络,没有其他网卡。这种类型的网络无法联网,但可以通过 link 容器来实现容器间通信,这种网络模式可以很好的保证容器的安全性。同时,这种网络模式下用户自己自行创建网络,可以实现更为灵活复杂的网络。

0.png
0.png

NETWORK: BRIDGE

这是容器默认的网络模式。桥接模式会为 Docker Container 创建独立的网络堆栈,保证容器内的进程组使用独立的网络环境,从而实现容器间、容器与宿主机之间的网络栈隔离。同时,桥接模式可以通过宿主机上的 docker0 网桥来实现宿主机与容器之间的网络通信。

桥接模式会在主机上创建两个虚拟网络接口设备,一个附加在宿主机上的 docker0 网桥内,并命名为 veth0 ,另一个附加在 Docker Container 所属的 namespace 的下,并命名为 eth0

1.png
1.png

通过 veth pair 技术,其特性可以保证无论哪一个 veth 接收到网络报文,都会将报文传输给另一方,这就实现了从容器到宿主机的网络连通性。然而上面也提到了 Docker 需要运行在 linux 环境下,所以我们无法在主机上看到 docker0 网桥,这个网桥位于虚拟机中。

NETWORK: HOST

这种网络模式下容器将跟主机共享网络堆栈,因此容器可以直接使用宿主机的 eh0 实现与外界的通信,并且主机所有的接口都可以被容器访问及使用。

host.png
host.png

在这种模式下,容器将获取更高的网络性能,因为它使用主机的网络栈,不需要通过 Docker 守护进程进行一层虚拟化。但是,这种模式也会导致容器网络环境隔离性弱化,即容器不再拥有隔离的、独立的网络栈。容器会与宿主机竞争网络栈的使用,同时容器也不再拥有所有的端口资源,因为部分端口已经被宿主机本身的服务占用,还有部分端口用于桥接模式容器的端口映射。

NETWORK: CONTAINER

这种网络模式下,容器将和另一个容器共享网络堆栈,因此,同样需要注意端口冲突等问题。该模式下,两个容器与其他容器以及宿主机之间存在网络隔离。

container.png
container.png

USER-DEFINED NETWORK

开发者可以使用 Docker 网络驱动程序或者外部的网络驱动程序来创建网络,也可以把多个容器连接到同一个网络下。在这里不展开介绍。

解决方法

方案一(仅在 macOS/Windows 下可用)

Docker 本身针对这种场景已经提出了一些解决方案。从版本 18.03 开始,Docker for Mac 提供一个特殊的 DNS name 以便用户从容器内访问到本机, 这个 DNS name 被解析至主机在 docker 内使用的内部 IP 。同时其他版本的 Docker Desktop for Mac 也有对应的 host ,如下所示:

  • Docker for Mac v 18.03 and above
  • host.docker.internal
  • Docker for Mac v 17.12 to v 18.02
  • docker.for.mac.host.internal
  • Docker for Mac v 17.06 to v 17.11
  • docker.for.mac.localhost
  • Docker for Mac 17.05 and below
  • Docker 不提供,需要自己进行配置,具体配置方法可以参考 Janne Annala 的回答
代码语言:txt
AI代码解释
复制
https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach
1的副本.png
1的副本.png

如上图所示,可以通过 host.docker.internal 直接访问到宿主机内的服务

方案二(仅在 Linux 下可用)

使用桥接模式。

可以看到宿主机下已经有了 docker0 网桥,且地址为 172.17.0.1

2.png
2.png

进入容器并查看容器内的网络接口信息和路由表可以发现 eth0 和宿主机中 docker0 的网段相同,且已经将 docker0 的接口地址设置为了默认网关,即匹配到的请求将通过 172.17.0.1 转发到目标地址。

3.png
3.png

那么通过该地址即可实现从容器到宿主机的访问。

4.png
4.png

方案三(仅在 Linux 下可用)

使用 host 模式启动服务就可以直接访问本机上的服务。利弊如上所述,若在生产环境使用该模式还需要自己再多做相关调研。

5.png
5.png

延展阅读

读到这的读者可能就会想,那容器内部需要访问外界,或者外界需要访问服务内部该咋办?好像刚刚提到的知识点不足以支撑这一流程呀?docker0 网段和宿主机的网段不同,外界无法得知容器 IP 更无法直接访问到容器内部。

6.png
6.png

这里就要引入另一个概念 NAT(Network Address Translation) ,是一种用于重写源IP地址或目的IP地址的技术。

外界访问容器内部

前提条件:容器运行时通过 -P 或 -p 指令主动暴露端口并将端口映射至主机上

to_docker.png
to_docker.png
  1. 外界直接请求 host_ip:port_0
  2. 通过 DNAT 将请求的目的地址修改为 container_ip:port_1
  3. 宿主机将请求转发给 veth pair
  4. veth pair 将请求通过 veth 转发至容器内部的 eth0
  5. 回包时也通过 docker0 转发至宿主机的 eth0 发送回包

通过检测数据包可以看到请求的目的 IP 被修改为了对应的容器 IP ,以完成外界对容器内部的访问

7.png
7.png
8.png
8.png

容器内部访问外界

from_docker.png
from_docker.png
  1. 容器内发出请求,此时会随机选取一个未被占用的端口 port0 作为源端口
  2. 请求通过 eth0 转发至 docker0 网桥处的 veth
  3. docker0 网球将请求转发至宿主机的 eth0
  4. 宿主机处理请求时通过 SNAT 将请求源地址修改为 host_ip:port_1 并转发出去
  5. 外界回包时发送至宿主机的 eth0
  6. 按照 iptables 规则,宿主机将请求转发至容器内部

查看 iptables 规则可知,从 172.17.0.0 网段出去访问外网的请求都会交由 MASQUERADE 处理。而 MASQUERADE 的处理就是将请求的源 ip 替换成宿主机的 ip 并发出去,也就是做了一次 NAT 处理。

9.png
9.png
通过检测数据包可知,请求的源 ip 确实被从 docker0 网段的容器 ip:172.17.0.2 修改为 eth1:10.12.91.17
10.png
10.png
11.png
11.png

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
tensorflow学习笔记(十四):tensorlfow操作gradient
在训练深度神经网络的时候,我们经常会碰到梯度消失和梯度爆炸问题,scientists提出了很多方法来解决这些问题,本篇就介绍一下如何在tensorflow中使用clip来address这些问题
ke1th
2019/05/26
7200
TensorFlow学习笔记之--[compute_gradients和apply_gradients原理浅析]
我们都知道,TensorFlow为我们提供了丰富的优化函数,例如GradientDescentOptimizer。这个方法会自动根据loss计算对应variable的导数。示例如下:
marsggbo
2018/12/21
6.2K0
Tensorflow 笔记:搭建神经网络
用张量表示数据,用计算图搭建神经网络,用会话执行计算图,优化线上的权重(参数),得到模型。
云时之间
2018/05/02
1.6K6
Tensorflow 笔记:搭建神经网络
【TensorFlow篇】--Tensorflow框架初始,实现机器学习中多元线性回归
TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统,其命名来源于本身的运行原理。Tensor(张量)意味着N维数组,Flow(流)意味着基于数据流图的计算,TensorFlow为张量从流图的一端流动到另一端计算过程。TensorFlow是将复杂的数据结构传输至人工智能神经网中进行分析和处理过程的系统。
LhWorld哥陪你聊算法
2018/09/13
6410
【TensorFlow篇】--Tensorflow框架初始,实现机器学习中多元线性回归
一看就懂的Tensorflow实战(TensorBoard高级篇)
[TensorBoard: 图表可视化]http://wiki.jikexueyuan.com/project/tensorflow-zh/how_tos/graph_viz.html
AI异构
2020/07/29
5060
一看就懂的Tensorflow实战(TensorBoard高级篇)
《Scikit-Learn与TensorFlow机器学习实用指南》 第11章 训练深度神经网络(下)
训练一个非常大的深度神经网络可能会非常缓慢。 到目前为止,我们已经看到了四种加速训练的方法(并且达到更好的解决方案):对连接权重应用良好的初始化策略,使用良好的激活函数,使用批量规范化以及重用预训练网络的部分。 另一个巨大的速度提升来自使用比普通渐变下降优化器更快的优化器。 在本节中,我们将介绍最流行的:动量优化,Nesterov 加速梯度,AdaGrad,RMSProp,最后是 Adam 优化。
SeanCheney
2020/10/27
1.1K0
《Scikit-Learn与TensorFlow机器学习实用指南》 第11章 训练深度神经网络(下)
tensorflow学习笔记(三十):tf.gradients 与 tf.stop_gradient() 与 高阶导数
本文介绍了如何使用 TensorFlow 计算高阶导数,包括 TensorFlow 的高阶导数 API 和使用 tf.gradients() 函数计算高阶导数的方法,并通过示例代码进行了演示。同时,还介绍了如何使用 tf.stop_gradient() 函数在计算高阶导数时阻止节点更新。
ke1th
2018/01/02
5.7K0
tensorflow语法【shape、tf.trainable_variables()、Optimizer.minimize()】
【一】tensorflow安装、常用python镜像源、tensorflow 深度学习强化学习教学
汀丶人工智能
2022/12/01
4940
[源码解析] 深度学习流水线并行GPipe (2) ----- 梯度累积
梯度累积是一种增大训练时 batch size的技术,在本地使用 micro-batch 多次进行正向和反向传播积累梯度后,再进行梯度规约和优化器更新,这是用来均摊通信成本的一种常用策略。本文通过几个框架/库的实现对比,让大家对这个技术有进一步的了解。
罗西的思考
2021/08/30
1.7K0
[源码解析] 深度学习流水线并行GPipe (2) ----- 梯度累积
TensorFlow2.0代码实战专栏(五):神经网络示例
原项目 | https://github.com/aymericdamien/TensorFlow-Examples/
磐创AI
2019/12/11
2.2K0
TF入门03-实现线性回归&逻辑回归
之前,我们介绍了TF的运算图、会话以及基本的ops,本文使用前面介绍的东西实现两个简单的算法,分别是线性回归和逻辑回归。本文的内容安排如下:
公众号-不为谁写的歌
2020/07/23
8090
tf42:tensorflow多GPU训练
MachineLP的Github(欢迎follow):https://github.com/MachineLP
MachineLP
2019/05/26
8080
猪年快乐之TensorFlow中实现word2vec及如何结构化TensorFlow模型
猪年快乐之TensorFlow中实现word2vec及如何结构化TensorFlow模型
公众号guangcity
2019/09/20
1.2K0
猪年快乐之TensorFlow中实现word2vec及如何结构化TensorFlow模型
如何用 TensorFlow 实现基于 LSTM 的文本分类(附源码)
引言 学习一段时间的tensor flow之后,想找个项目试试手,然后想起了之前在看Theano教程中的一个文本分类的实例,这个星期就用tensorflow实现了一下,感觉和之前使用的theano还是
AI研习社
2018/03/29
1.5K0
如何用 TensorFlow 实现基于 LSTM 的文本分类(附源码)
【干货】TensorFlow 2.0官方风格与设计模式指南(附示例代码)
【导读】TensorFlow 1.0并不友好的静态图开发体验使得众多开发者望而却步,而TensorFlow 2.0解决了这个问题。不仅仅是默认开启动态图模式,还引入了大量提升编程体验的新特性。本文通过官方2.0的风格指南来介绍新版本的开发体验。
小小詹同学
2019/11/12
1.9K0
TensorFlow-CIFAR10 CNN代码分析
想了解更多信息请参考CIFAR-10 page,以及Alex Krizhevsky写的技术报告
百川AI
2021/10/19
7050
搭建的神经网络过程
x1、x2 表示输入,w1、w2 分别是 x1 到 y 和 x2 到 y 的权重,y=x1w1+x2w2。
foochane
2019/05/23
7600
搭建的神经网络过程
TensorFlow指南(三)——深度神经网络(初级)
由于本系列博文主要专注于Tensorflow本身,所以还是老样子不会过多讲解神经网络的理论知识。 可以参阅这篇博文来先理解下神经网络:http://blog.csdn.net/u011239443/article/details/76680704
小爷毛毛_卓寿杰
2019/02/13
4360
深度学习_1_Tensorflow_1
# 深度学习 # 图像识别,自然语言处理 # 机器学习 深度学习 # 分类:神经网络(简单) 神经网络(深度) # 回归 图像:卷积神经网络 # 自然语言处理:循环神经网络 # cpu:运行操作系统,处理业务,计算能力不是特别突出 # gpu:专门为计算设计的 import tensorflow as tf a = tf.constant(5.0) b = tf.
Dean0731
2020/05/08
5810
《Scikit-Learn与TensorFlow机器学习实用指南》 第09章 启动并运行TensorFlow
TensorFlow 是一款用于数值计算的强大的开源软件库,特别适用于大规模机器学习的微调。 它的基本原理很简单:首先在 Python 中定义要执行的计算图(例如图 9-1),然后 TensorFlow 使用该图,并使用优化的 C++ 代码高效运行该图。
SeanCheney
2018/10/10
9610
《Scikit-Learn与TensorFlow机器学习实用指南》 第09章 启动并运行TensorFlow
推荐阅读
相关推荐
tensorflow学习笔记(十四):tensorlfow操作gradient
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档