Docker网络之单host网络及使用案例

前言

前面总结了Docker基础以及Docker存储相关知识,今天来总结一下Docker单主机网络的相关知识。毋庸置疑,网络绝对是任何系统的核心,他在Docker中也占有重要的作用。

一、Docker默认网络

在新安装docker的主机上执行

docker network ls

便能看到docker默认安装的所有网络,分别是none网络、host网络和bridge网络。

1.1 none 网络

none网络就是什么都没有的网络。挂在这个网络下的容器除了lo,没有其他任何网卡。容器run时,可以通过添加--network=none参数来指定该容器使用none网络。那么这样一个只有lo的网络有什么用呢?此处CloudMan指出:

none网络应用与隔离场景,一些对安全性要求高并且不需要联网的应用可以使用none网络。

比如某个容器的唯一用途是生成随机密码,就可以放到none网络中避免密码被窃取。

我可以理解none网络肯定是用于隔离的,然而我好奇的是生成的随机密码如何发送到外部呢?如何被外部调用呢?这是我没有想明白的问题。有知道的希望不吝赐教!谢谢!

1.2 host 网络

连接到host网络的容器共享Docker宿主机的网络栈,即容器的网络配置与host宿主机完全一样。可以通过添加--network=host参数来指定该容器使用host网络。

在容器中可以看到host的所有网卡,并且连hostname也是host的。host网络的使用场景又是什么呢?

直接使用Docker host的网络最大的好处就是性能,如果容器对网络传输效率有较高要求,则可以选择host网络。当然不便之处就是牺牲一些灵活性,比如要考虑端口冲突问题,Docker host上已经使用的端口就不能再用了。

Docker host的另一个用途是让容器可以直接配置 host 网路。比如某些跨host的网络解决方案,其本身也是以容器方式运行的,这些方案需要对网络进行配置。

相当于该容器拥有了host主机的网络,那么其ip等配置也相同,相当于主机中套了一个与外部一模一样的容器,可以直接通过host的ip地址来访问该容器。

1.3 bridge 网络

在不指定--network参数或者--network=bridge的情况下创建的容器其网络类型都是bridge。

Docker在安装时会在宿主机上创建名为docker0的网桥,所谓网桥相当于一个虚拟交换机,如果使用上述两种方式run的容器都会挂到docker0上。

容器和docker0之间通过veth进行连接,veth相当于一根虚拟网线,连接容器和虚拟交换机,这样就使得docker0与容器连通了。

二、自定义容器网络

理论上有了上述三种网络已经足够满足普通用户的需求,但是有时候可能用户需要指定自己的网络,以此来适应某些配置,如ip地址规划等等。

2.1 创建自定义网络

Docker提供三种user-defined网络驱动:bridge,overlay和macvlan。overlay和macvlan用于创建跨主机的网络,会在下一篇文章介绍。所以本文介绍创建bridge自定义网络。命令如下:

docker network create -d bridge --subnet 172.10.0.0/24 --gateway 172.10.0.1 my_net

-d bridge表示自定义网络的驱动为bridge,--subnet 172.10.0.0/24 --gateway 172.10.0.1分别指定网段和网关。

这样就创建好了一个自动一网络,可以通过以下命令查看此网络的信息:

docker network inspect my_net

会得到此网络的配置信息,my_net是刚刚创建的网络名称,如果为bridge就是查看docker创建的默认bridge网络信息。

每创建一个自定义网络便会在宿主机中创建一个网桥(docker0是创建的默认网桥,其实原理是一致的,而且也是对等的。)。名字为br-<网络短ID>,可以通过brctl show命令查看全部网桥信息。

docker的自定义网络与OpenStack中的网络信息倒是基本一致。所以一通百通,只要docker的明白了,所有虚拟化甚至实体的网络也就基本都搞清楚了。

2.2 使用自定义网络

通过以下命令为容器指定自定义网络:

docker run -it --network my_net --ip 172.10.0.3 busybox

其实这与使用docker默认网络是一致的,都是添加--network参数参数,此处也添加了--ip参数来指定容器的ip地址。

三、不同容器之间的连通性

同一个网络(默认网络或者自定义网络)下的容器之间是能ping通的,但是不同网络之间的容器由于网络独立性的要求是无法ping通的。原因是iptables-save DROP掉了docker之间的网络,大概如下:

-A DOCKER-ISOLATION -i docker0 -o br-ac4fe2d72b18 -j DROP
-A DOCKER-ISOLATION -i br-ac4fe2d72b18 -o docker0 -j DROP
-A DOCKER-ISOLATION -i br-62f17c363f02 -o br-ac4fe2d72b18 -j DROP
-A DOCKER-ISOLATION -i br-ac4fe2d72b18 -o br-62f17c363f02 -j DROP
-A DOCKER-ISOLATION -i br-62f17c363f02 -o docker0 -j DROP
-A DOCKER-ISOLATION -i docker0 -o br-62f17c363f02 -j DROP

那么如何让不同网络之间的docker通信呢?接下来介绍容器间通信的三种方式。

3.1 IP 通信

IP通信就是直接用IP地址来进行通信,根据上面的分析需要保证两个容器处于同一个网络,那么如果不在同一个网络如何处理呢?

如果是实体机我们很容易理解,只需要为其中一台服务器添加一块网卡连接到另一个网络就可以了。容器同理,只需要为其中一个容器添加另外一个容器的网络就可以了。使用如下命令:

docker network connect my_net httpd

connect命令能够为httpd容器再添加一个my_net网络(假设httpd原来只有默认的bridge网络)。这样上面创建的busybox容器就能与此次connect的httpd容器进行通信。

3.2 Docker DNS Server

通过 IP 访问容器虽然满足了通信的需求,但还是不够灵活。因为我们在部署应用之前可能无法确定IP,部署之后再指定要访问的IP会比较麻烦。对于这个问题,可以通过docker自带的DNS服务解决。

从Docker 1.10 版本开始,docker daemon 实现了一个内嵌的DNS server,使容器可以直接通过“容器名”通信。

方法很简单,只要在启动时用--name为容器命名就可以了。

下面的命令启动两个容器bbox1和bbox2:

docker run -it --network=my_net --name=bbox1 busybox
docker run -it --network=my_net --name=bbox2 busybox

然后,bbox2就可以直接ping到bbox1了,但是使用docker DNS有个限制,只能在user-defined网络中使用。默认的bridge网络是无法使用的。

3.3 joined 容器

joined 容器是另一种实现容器间通信的方式。joined 容器非常特别,它可以使两个或多个容器共享一个网络栈,共享网卡和配置信息,joined容器之间可以通过127.0.0.1直接通信。host网络使得容器与宿主机共用同一个网络,而jointed是使得两个容器共用同一个网络。

请看下面的例子:

先创建一个httpd容器,名字为web1。

docker run -d -it --name=web1 httpd

然后创建busybox容器并通过--network=container:web1指定jointed容器为web1:

docker run -it --network=container:web1 busybox

这样busybox和web1的网卡mac地址与IP完全一样,它们共享了相同的网络栈。busybox 可以直接用127.0.0.1访问web1的http服务。

其实也很容易理解,之前的--network参数指定了默认网络或者自定义网络,而此处是指定了一个容器,那么当然意思就是使用这个容器的网络。这也有点类似上一篇文章讲到的共享存储。

joined 容器非常适合以下场景:

不同容器中的程序希望通过loopback高效快速地通信,比如web server与app server。

希望监控其他容器的网络流量,比如运行在独立容器中的网络监控程序。

其实就是应用于即需要独立而又需要两个容器网络高度一致的场景。

3.4 容器与外部网络的连通性

3.4.1 容器访问外部网络

容器默认是能访问外部网络的。通过NAT,docker实现了容器对外网(此处外网不一定是互联网)的访问。

3.4.2 外部网络访问容器

通过端口映射的方式实现外部网络访问容器,即通过-p参数实现将容器的端口映射到外部端口。

总结

以上所述是小编给大家介绍的Docker网络之单host网络及使用案例,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • Docker探索namespace详解

    Docker通过namespace实现了资源隔离,通过cgroups实现了资源限制,通过写时复制(copy-on-write)实现了高效的文件操作. 1.namespace资源隔离 namepsace的6项隔离: namespace 系统调用参数 隔离内容 UTS CLONE_NEWUTS 主机名与域名 IPC CLONE_NEWIPC 信号量,消息队列和共享内存 PID CLONE_NEWPID 进程编号 Network CLONE_NEWNET 网络设备,网络栈,端口等 Mount CLON

  • Docker端口映射实现网络访问的方法

    Docker运行容器之后却发现没IP,没端口,那要如何访问容器呢? 下面我来介绍下docker通过端口映射来实现网络访问 一.从外部访问容器应用 在启动容器的时候,如果不指定对应参数,在容器外部是无法通过网络来访问容器内的网络应用和服务的. 当容器中运行一些网络应用,要让外部访问这些应用时,可以通过-P或-p参数指定端口映射. 先来说说p和P吧 -p 可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器 -P 它会随机映射一个端口至容器内部开放的网络端口(范围不详,似乎都上万) 先申明

  • docker中修改镜像容器的存放目录的方法

    最近在学习docker的路上,今天遇到了个问题,在网上查找了一下资料,顺便留个笔记 在默认情况下,Docker镜像和容器的默认存放位置为: /var/lib/docker 一般根下分区我们不会给太大.镜像和容器越存越多一般我们有两种解决方法: 1. 挂载大分区到/var/lib/docker 一般选择建立逻辑分区lvm,方便后期扩展集体. 建立新分区,并格式化 [root@localhost lib]# lvcreate -L 300G lv_docker vg_home [root@local

  • Docker网络之单host网络及使用案例

    前言 前面总结了Docker基础以及Docker存储相关知识,今天来总结一下Docker单主机网络的相关知识.毋庸置疑,网络绝对是任何系统的核心,他在Docker中也占有重要的作用. 一.Docker默认网络 在新安装docker的主机上执行 docker network ls 便能看到docker默认安装的所有网络,分别是none网络.host网络和bridge网络. 1.1 none 网络 none网络就是什么都没有的网络.挂在这个网络下的容器除了lo,没有其他任何网卡.容器run时,可以通

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

  • Docker网络原理及自定义网络详细解析

    Docker在宿主机上虚拟了一个网桥,当创建并启动容器的时候,每一个容器默认都会被分配一个跟网桥网段一致的ip,网桥作为容器的网关,网桥与每一个容器联通,容器间通过网桥可以通信.由于网桥是虚拟出来的,外网无法进行寻址,也就是默认外网无法访问容器,需要在创建启动容器时把宿主机的端口与容器端口进行映射,通过宿主机IP端口访问容器.这是Docker默认的网络,它有一个弊端是只能通过IP让容器互相访问,如果想使用容器名称或容器ID互相访问需要在创建启动容器时候用link的方式修改hosts文件实现.一般

  • 对docker中的overlay式网络详解

    翻译自docker官方文档,原文:https://docs.docker.com/network/overlay/ overlay(覆盖)式网络会在多个docker守护进程所在的主机之间创建一个分布式的网络.这个网络会覆盖宿主机特有的网络,并允许容器连接它(包括集群服务中的容器)来安全通信.显然,docker会处理docker守护进程源容器和目标容器之间的数据报的路由. 当你初始化一个集群(swarm)或把一个docker宿主机加入一个已经存在的集群时,宿主机上会新建两个网络: 一个叫ingre

  • docker搭建mongodb单节点副本集的实现

    目录 背景 启动步骤 可能遇到的问题 解决办法 背景 在开发中,我们很容易通过docker启动一个普通的mongodb数据库服务.但是有时候为了保持与线上环境一致,或者为了利用mongodb副本集的某些特性,我们需要在本地部署mongodb副本集.副本集往往需要启动多个mongodb服务作为副本集成员,而通常用于开发的笔记本资源比较有限.鉴于此,官方文档给了解决办法,可以直接将一个单节点mongodb服务转换为单节点副本集(standlone replica set)(https://www.m

  • 非对称网络不通 子网掩码导致网络不通是“祸首”

    网络不通,这是最多的网络问题表像,但如果你能访问我,但我不能访问你,这个问题就比较麻烦了.本文是作者在实战中的一起由子网掩码造成的故障总结. 网络不通是经常发生的一种现象,遇到这种现象,相信许多人都会将精力集中在网络线缆.网卡驱动.网卡参数方面;而在检查网卡参数时,他们或许又将眼光聚焦在IP地址.网关地址.DNS服务器或DHCP服务器等重点参数上.事实上,还有一个网络参数--子网掩码,同样也是非常重要的,要是我们忽略了对它的设置或将它设置错误,同样也会带来网络不通的故障.由于子网掩码参数平时不被

  • vue网络请求方案原生网络请求和js网络请求库

    一. 原生网络请求 1. XMLHttpRequest(w3c标准)    // 没有promise时的产物 当时的万物皆回调,太麻烦 2. Fetch    // html5提供的对象,基于promise 因为promise的存在,为了简化网络请求. 使用 Fetch - Web API 接口参考 | MDN Fetch是新的ajax解决方案 Fetch会返回Promise对象.fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象. 参数: 1.第一个参数

  • Android网络监听和网络判断示例介绍

    目录 一.在AndroidMainfest.xml中添加权限 二.NetUtilSS 网络判断工具类 三.IntentReceiver网络监听工具类 四.BaseActivity 五.MainActivity    一.在AndroidMainfest.xml中添加权限 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:

  • pytorch单维筛选 相乘的案例

    m需要和筛选的结果维度相同 >0.5运行的结果与原来维度相同,结果是 0 1,0代不符合,1代表符合. import torch m=torch.Tensor([0.1,0.2,0.3]).cuda() iou=torch.Tensor([0.5,0.6,0.7]) x= m * ((iou > 0.5).type(torch.cuda.FloatTensor)) print(x) 下面是把第一条与第二条变成了2: import torch m=torch.Tensor([0.1,0.2,0.

随机推荐