文章目录
一、docker网络
1.docker原生网络
yum install bridge-utils.x86_64 -y ##安装网桥查看管理命令
docker的镜像是令人称道的地方,但网络功能还是相对薄弱的部分
docker安装后会自动创建3种网络:bridge、host、none
(1)bridge网络
docker安装时会创建一个名为docker0的linux bridge,新建的容器会自动桥接到这个接口,并且容器的ip都会默认在这个网段种分配一个ip,且默认是以单调递增的方式获取的ip
我们创建一个容器测试一下,看分到的ip是不是172.17.0.2,并且容器的虚拟网卡会自动桥接到docker0上
bridge模式下容器没有一个公有ip,只有宿主机可以直接访问,外部主机是不可见的,但是容器可以通过宿主机的NAT规则后可以访问外网,即打开路由转发net.ipv4.ip_forward=1
(2)host网络
host网络模式需要在容器创建时指定,可以看到容器中的ip和网桥都与宿主机相同
host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性
(3)none网络模式
none模式是指金庸网络功能,让容器只有lo接口可用,在容器创建时使用–network=none指定
主要是可以实现网络的隔离,让这个容器中的数据变的安全
2.docker自定义网络
自定义网络模式,docker提供了三种自定义网络驱动:bridge、overlay和macvlan
bridge驱动类似默认的bridge网络模式,但增加了一些新功能,overlay和macvlan是用于创建跨主机网络
建议使用自定义的网络来控制哪些容器可以相互通信,还可以自动DNS解析容器名称到IP地址
创建自定义网桥
使用自定义的网桥创建一个容器
docker run -it --name vm1 --network my_net1 ubuntu
ip aadr ##在容器中查看ip,然后ctrl+p+q将容器打入后台运行,注意不是ctrl+d,那样会直接关闭容器
docker network inspect my_net1 ##查看桥接的具体信息
创建一个自定义网段的桥接,并指定网段和网关
docker network create -d bridge --subnet 172.26.0.0/24 --gateway 172.26.0.1 my_net2
##注意不能与宿主机冲突
使用--ip参数指定容器ip地址,但必须是在自定义网桥上,默认的bridge模式不支持,且同一网桥上的容器时可以互通的
docker run -it --name vm3 --network my_net2 --ip 172.26.0.10 ubuntu ##指定容器的ip
桥接到不同网桥上的容器,默认情况下彼此是不能通信的,因为docker在设计上就是要隔离不同网络的
iptables -S ##可以看到防火墙中的策略,即使我们的火墙是关闭的
让不同桥接上的容器进行通信,给容器加上另一个网段的网卡即可
docker network connect my_net2 vm1 ##vm1原本是my_net1网段的,现在给它加一个my_net2网段的网卡
3.docker容器通信
容器之间除了使用ip通信外,还可以使用容器名称通信:
docker1.10开始,内嵌了一个DNS server
dns解析功能必须在自定义网络中使用
启动容器时使用 --name参数指定容器名称
先清理掉之前建立的容器,网桥不删除
(1)
Jion容器时一种较为特别的网络模式,实际上就是共享两个容器的网络栈
在容器创建时使用--network=container:vm1指定(vm1指定的是运行的容器名)
原理类似如下,这两个容器可以使用localhost高速通信
(2)
--link可以用来链接两个容器。而且还可以传递变量
先把原来的容器删除掉
docker run -it --name vm1 --link youthful_almeida:web ubuntu
通过env可以查看到nginx的变量也传递过来了
容器的ip变化后依然可以通信
(3)
容器访问外网是通过iptables的SNAT实现的
创建的网桥都桥接在docker0上
进入容器测试能否连通外网
(4)
外网如何访问容器
通过端口映射,-p选项指定映射端口
端口映射后直接访问宿主机的ip和相应的端口就可以访问,docker-proxy来处理端口转发的数据包
外网访问容器用到了docker-proxy和iptables DNAT
宿主机访问本机使用的是iptables DNAT
外部主机访问容器或容器之间的访问是docker-proxy实现的
iptables -t nat -nL ##查看dnat策略
4.跨主机容器网络
跨主机网络解决方案:
docker原生的overlay和macvlan
第三方的flannel、weave、calico
(1)macvlan网络方案的实现
这是linux Kernel提供的一中网卡虚拟化技术,无需linux bridge,直接使用物理接口,性能极好
环境准备:
在两台docker主机上各添加一块网卡,打开网卡混杂模式:
ip link set eth1 up ##首先启用网卡eth1
ip link set eth1 promisc on ##开启混杂模式
docker network prune ##删除掉所有之前建立的网桥
在两台主机上各自创建macvlan网络:
docker network create -d macvlan --subnet 172.20.0.0/24 --gateway 172.20.0.1 -o parent=eth1 mac1
因为macvlan步走桥接,所以要指定它数据走的是哪个物理接口,用parent指定eth1网卡,并给它一个名字mac1
创建容器,要给容器指定ip,因为这都是我们手动给定的网段和网关,让它自己分配的话可能会出现冲突
给梁台主机分配不同的ip,尝试能否通信
可以发现容器的接口与主机网卡直接连接,无需NAT或端口映射
(2)macvlan会独占主机网卡,但可以使用vlan子接口实现多macvlan网络
vlan可以将物理二层网络划分为4094个逻辑网络,彼此隔离,vlan id取值为1~4094
如果要连通的话可以给其中一个加入网关或者双网卡
docker network create -d macvlan --subnet 172.21.0.0/24 --gateway 172.21.0.1 -o parent=eth1.1 mac2
以eth1.1创建一个mac2,两台主机操作相同
ip addr ##可以查看到新生成了eth1.1网卡
macvlan网络间的隔离和连通:
macvlan网络在二层上是隔离的,所以不同macvlan网络的容器是不能通信的
可以在三层上通过网关将macvlan网络连通起来
docker本身不做任何限制,像传统vlan网络那样管理即可
二、Docker数据卷管理
1.bind mount
是将主机上的目录或文件mount到容器里。
使用直观高效,易于理解。
使用-v选项指定路径<host path>:<container path> :之前的是宿主机的路径,:之后是容器的路径
bind mount 默认权限是读写rw,可以在挂载时指定只读ro
-v选项指定的路径,如果不存在,会自动创建,并且会覆盖原来目录中的内容
docker exec web1 mount ##在容器中执行mount命令
在本机挂载过去的目录里写一个默认发布文件,再次查询,即可看到信息
docker history rhel7:nginx ##可以看到最后一条命令是开启了一个容器,所以这是一个应用容器,
不能使用docker container attach web1 这种方式进入容器
但是可以用docker exec -it web1 bash 进入容器并且获得一个能交互的shell,这样在容器里面修改文件也是可以的
2.docker managed volume
bind mount 必须指定host文件系统路径,限制了移植性,不便于多节点使用。
docker managed volume 不需要指定mount源,docker自动为容器创建数据卷目录。
默认创建的数据卷目录都在/var/lib/docker/volumes中。
如果挂载时指向容器内已有的目录,原有数据会被复制到volume中。
可以发现自动生成的目录名称特别长,这样是很不方便的,我们可以指定生成的目录的名称
docker inspect web2 ##查看容器的详细信息
数据卷的删除:
docker rm -f web1 ##这样虽然删除了容器但是数据卷被保留了下来,需要我们手动删除
docker volume prune ##删除所有,但是不会删除正在被容器使用的卷
docker volume rm id/卷名 ##或者通过这种方式单个删除
手动创建一个数据卷挂载到容器中:
docker volume create webdata ##创建一个数据卷
并且这个目录可以被多个容器使用,但是端口不能,80端口被映射后,其他的容器不能再使用这个端口
可以通过docker inspect 来查看容器的详细信息获取容器的ip来完成测试
bind mount 与docker managed volume 的区别:
3.卷插件的简介
docker卷默认使用的是local类型的驱动,只能存在宿主机,跨主机的volume就需要使用第三方的驱动,可以查看以下链接:
https://docs.docker.com/engine/extend/legacy_plugins/#volume-plugins
docker官方只提供了卷插件的api,开发者可以根据实际需求定制卷插件驱动。
https://docs.docker.com/engine/extend/plugins_volume/#volume-plugin-protocol
4.通过convoy卷插件实现共享卷
(1)本次实验是通过nfs共享来实现的,卷插件可以在https://github.com/rancher/convoy上获取到下载,而且在所有节点上要提前挂载nfs存储
在server1上的操作:
yum install nfs-utils.x86_64 -y ##先配置好nfs服务
systemctl start rpcbind ##先启动这个服务,不然看不到数据,默认监听的是111端口
mkdir /etc/exports ##建立一个共享目录,同时它也是卷数据的写入点
vim /etc/exports ##修改配置文件
systemctl start nfs ##启动服务
exportfs -v ##查看一下信息
在server2上的操作:
systemctl start rpcbind
mkdir /mnt/nfs ##建立与server1相同的共享目录
showmount -e 172.25.21.1
mount 172.25.21.1:/mnt/nfs/ /mnt/nfs/ ##将共享目录挂载到本地
测试是否同步
(2)convoy插件的部署
两台主机都需要安装
两台主机操作相同:
tar zxf convoy.tar.gz ##解压文件
convoy --help ##可以查看到sock文件路径等信息
convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs & ##让程序后台运行,debug默认是开启的
cd /var/run/convoy/ ##可以看到启动的sock文件
然后把sock文件的路径告知docker
(3)创建一个卷来共享
(4)测试共享
此时这个容器已经不会影响到它创建的数据了,因为它的数据已经被宿主机保存下来
我们删掉server1上的vm1再次进行测试
[root@server1 vol1]# docker rm -f vm1
在server2上再次挂载vol1
退出卷后查看,发现只有test这个文件了,因为容器对挂载目录默认有读写权限
(5)卷的删除
删除前要确认没有容器正在使用
convoy卷插件的子命令:
convoy list ##列出卷
convoy delete ##删除卷
convoy snapshot create ##创建快照
convoy snapshot delete ##删除快照
convoy backup create ##创建备份
convoy create res1 --backup <url> ##还原备份