Docker的网络配置-小白笔记

1 docker网络模式

  • docker的镜像是令人称道的地方,但网络功能还是相对薄弱的部分。
  • docker安装后会自动创建3种网络:bridge、host、none

Docker在启动时会开启一个虚拟网桥设备docker0,默认的地址为172.17.0.1/16,容器启动后都会被桥接到docker0上,并自动分配到一个ip地址。

查看docker网络配置

docker network ls

2 容器的四种网络模式

2.1 bridge网络模式

默认的网络模式。bridge模式下容器没有一个公有ip,只有宿主机可以直接访问,外部主机是不可见的,但容器通过宿主机的NAT规则后可以访问外网。

Bridge 桥接模式的实现步骤主要如下:

  • Docker Daemon 利用 veth pair 技术,在宿主机上创建两个虚拟网络接口设备,假设为veth0 和 veth1。而veth pair 技术的特性可以保证无论哪一个 veth 接收到网络报文,都会将报文传输给另一方。

  • Docker Daemon 将 veth0 附加到 Docker Daemon 创建的 docker0网桥上。保证宿主机的网络报文可以发往 veth0;

  • Docker Daemon 将 veth1 添加到 Docker Container 所属的 namespace 下,并被改名为eth0。如此一来,保证宿主机的网络报文若发往 veth0,则立即会被 eth0 接收,实现宿主机到Docker Container网络的联通性;同时,也保证 Docker Container 单独使用 eth0,实现容器网络环境的隔离性。

Bridge桥接模式的缺陷

1.最明显的是,该模式下 Docker Container 不具有一个公有 IP,即和宿主机的 eth0 不处于同一个网段。导致的结果是宿主机以外的世界不能直接和容器进行通信。
2.虽然 NAT 模式经过中间处理实现了这一点,但是 NAT 模式仍然存在问题与不便,如:容器均需要在宿主机上竞争端口,容器内部服务的访问者需要使用服务发现获知服务的外部端口等。
3.另外 NAT 模式由于是在三层网络上的实现手段,故肯定会影响网络的传输效率。

注意:
veth设备是成双成对出现的,一端是容器内部命名为eth0,一端是加入到网桥并命名的veth(通常命名为veth),它们组成了一个数据传输通道,一端进一端出,veth设备连接了两个网络设备并实现了数据通信

2.2 host网络模式

host网络模式需要在容器创建时指定–network=host

host 模式是 bridge 桥接模式很好的补充。采用 host 模式的 Docker Container,可以直接使用宿主机的 IP地址与外界进行通信,若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公有IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换。

host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性。

Host 网络模式的缺陷:
最明显的是 Docker Container 网络环境隔离性的弱化。即容器不再拥有隔离、独立的网络栈。
另外,使用 host 模式的 Docker Container 虽然可以让容器内部的服务和传统情况无差别、无改造的使用,但是由于网络隔离性的弱化,该容器会与宿主机共享竞争网络栈的使用;
另外,容器内部将不再拥有所有的端口资源,原因是部分端口资源已经被宿主机本身的服务占用,还有部分端口已经用以 bridge 网络模式容器的端口映射。

创建命令

docker run -idt --name hostContainer --network=host ubuntu

2.3 none网络模式

none模式是指禁用网络功能,只有lo接口,在容器创建时使用–network=none指定。

网络环境为 none,即不为 Docker Container 任何的网络环境。一旦 Docker Container 采用了none网络模式,那么容器内部就只能使用 loopback 网络设备,不会再有其他的网络资源。可以说 none 模式为 Docke Container 做了极少的网络设定,但是俗话说得好“少即是多”,在没有网络配置的情况下,作为 Docker 开发者,才能在这基础做其他无限多可能的网络定制开发。这也恰巧体现了 Docker 设计理念的开放。

创建命令

docker run -it --name vm3 --network=none ubuntu

2.4 Container网络模式

Container 网络模式是 Docker 中一种较为特别的网络的模式。在容器创建时使用–network=container:vm1指定。(vm1指定的是运行的容器名)

处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用localhost高效快速通信。

缺陷:它并没有改善容器与宿主机以外世界通信的情况(和桥接模式一样,不能连接宿主机以外的其他设备)。

创建命令

docker run -it --name vm4 --network=container:vm1 ubuntu

3 使用link方式使容器间可以相互通信

docker run --link可以用来链接2个容器,使得源容器(被链接的容器)和接收容器(主动去链接的容器)之间可以互相通信,并且接收容器可以获取源容器的一些数据,如源容器的环境变量。

创建一个容器vm5,并使用link方式连接vm1

#此时的vm1的是容器名,db1是容器的别名
[root@server1 ~]# docker run -it --name vm5 --link vm1:db1 ubuntu
#查看当前环境的环境变量
root@b814d53a605c:/# env

尝试去连接vm1以及其别名,发现可以成功连接

root@b814d53a605c:/# ping vm1
root@b814d53a605c:/# ping db1

4 高级网络配置–网桥

自定义网络模式中,docker提供了三种自定义网络驱动:brdge,overlay,macvlan,bridge驱动类似默认的bridge网络模式,但增加了一些新的功能,overlay和macvlan是用于创建跨主机网络

建议使用自定义的网络来控制哪些容器可以相互通信,还可以自动DNS解析容器名称到IP地址


4.1 bridge自定义网络

  • 自定义网桥中会自己分配ip地址和网关地址)

1.创建自定义网桥并查看

#以下命令也可以写成以下格式:
[root@server1 ~]# docker network create --driver bridge my_net1
[root@server1 ~]# docker network create my_net1
[root@server1 ~]# docker network ls

在这里插入图片描述
2.为了不影响之后的实验,将所有的容器都进行关闭
#查看正在运行的容器

[root@server1 ~]# docker ps

在这里插入图片描述

#将正在运行的容器强制删除

[root@server1 ~]# docker rm -f vm1
[root@server1 ~]# docker rm -f vm3
[root@server1 ~]# docker rm -f vm4
[root@server1 ~]# docker rm -f vm5

 

在这里插入图片描述
#查看没有运行的容器

[root@server1 ~]# docker ps -a

在这里插入图片描述
#将其也依次删除,使其环境纯净

[root@server1 ~]# docker rm -f vm2
[root@server1 ~]# docker rm -f registry

在这里插入图片描述

3.查看自定义网络的ip地址和网关地址

[root@server1 ~]# ip a
[root@server1 ~]# docker network inspect my_net1

在这里插入图片描述在这里插入图片描述

4.创建容器vm1并使用自定义网桥,并尝试与vm1通信,发现可以通信

[root@server1 ~]# docker run -it --name vm1 --network=my_net1 ubuntu
#在通信时
root@ea41dabc161f:/# ping vm1

在这里插入图片描述
5.创建容器vm2并使用自定义网桥,并尝试与vm1通信,发现可以通信

[root@server1 ~]# docker run -it --name vm2 --network=my_net1 ubuntu
#在通信时可以发现vm1自动进行了域名解析
root@010fe2d13a0b:/# ping vm1

在这里插入图片描述
总结:
在创建容器时,如果使用的网络模式时自定义的网桥,那么在此网桥中创建的容器都可以互相进行通信。

4.2 bridge自定义网络–网段

  • 还可以自己定义网段:在创建时指定参数:–subnet 、–gateway

  • 创建两个容器,并桥接到不同的网桥上(vm1连接的网桥是my_net1),彼此是不通信的。

  • 使用–ip参数可以指定容器ip地址,但必须是在自定义网桥上,默认的bridge模式不支持,同一网桥上的容器是可以互通的。


1.添加一个docker的自定义网段并查看

[root@server1 ~]# docker network create --subnet=172.21.0.0/24 --gateway=172.21.0.1 my_net2
[root@server1 ~]# docker network ls

在这里插入图片描述
2.创建一个容器vm3,并设置其ip(ip必须在自定义桥内)

[root@server1 ~]# docker run -it --name vm3 --network=my_net2 --ip=172.21.0.100  ubuntu
root@0f6d07ab74f1:/# ip a

在这里插入图片描述

3.尝试通信vm1,发现无法通信;尝试通信vmm3,发现可以通信。说明如果使用不同网桥间的容器时不可以通讯的

root@0f6d07ab74f1:/# ping vm1
root@0f6d07ab74f1:/# ping vm3

在这里插入图片描述

4.3 不同网桥间的容器进行通信

  • docker在设计上就是要隔离不同的network的
  • dokcer作为一个超级厉害的容器,怎么能容忍不同网桥间无法进行通信,它当然有其自己的方法。

前提:
现在使用的容器vm1使用的网桥时my_net1,容器vm3使用的网桥是my_net2,默认是无法进行通讯的

实验:
1.使用 docker network connect命令为vm1添加一块my_net2 的网卡。

#给容器添加网卡后可以连接不同网络
[root@server1 ~]# docker network connect my_net2 vm1

在这里插入图片描述

2.进入容器vm1(因为vm1此时正在运行,所以可以使用attach直接进入vm1容器),并查看ip,发现此时多了一块网卡,且自动分配了ip,然后尝试与vm3进行通信,发现可以成功通讯

[root@server1 ~]# docker attach vm1
root@ea41dabc161f:/# 
root@ea41dabc161f:/# ip a
root@ea41dabc161f:/# ping vm3

在这里插入图片描述

3.容器之间除了使用ip通信外,还可以使用容器名称通信

#docker 1.10开始,内嵌了一个DNS server,但是dns解析功能必须在自定义网络中使用
root@ea41dabc161f:/# ping -c1 vm1
root@ea41dabc161f:/# ping -c1 vm3

在这里插入图片描述

总结:
1.docker的bridge自定义网络(自定义网络中的网桥)间可以随便添加对方的网卡
2.docker的bridge自定义网络与系统自带的网桥自己间:只能是系统自带的网桥对应的容器添加给自定义的网桥间,而反过来会报错
3.docker的系统自带的网桥之间时可以互相通信的,因为在同一个网络桥接上

5 网络解决方案(跨主机)

猜你喜欢

转载自blog.csdn.net/h4241778/article/details/108909140