一.Docker原生网络
docker网络功能是相对薄弱的部分
docker安装后会自动创建3种网络:bridge、host、none
可以使用以下命令查看
[root@server2 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
f38ea08fb71f bridge bridge local
da320f6907e9 host host local
13bf213f9c27 none null local
docker安装时会创建一个名为 docker0 的Linux bridge,新建的容器会自动桥接到这个接口
(一).bridge(桥接模式)
1.bridge模式下容器没有一个公有ip,只有宿主机可以直接访问,外部主机是不可见的
2.容器通过宿主机的NAT规则后可以访问外网
yum install bridge-utils -y
docker run -it busybox:latest
ctrl+p+q后台运行
docker run -d --name demo reg.westos.org/server/web:latest
(二).host
host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性
host网络模式需要在容器创建时指定 --network=host
docker run -d --name demo --network=host reg.westos.org/server/web #与宿主机共享网络
已经开启了80端口,再开启一个web时,会报错;但是可以让其使用默认桥接模式起来
(三).nono,只能本地访问
none模式是指禁用网络功能,只有lo接口,在容器创建时使用
–network=none指定
二.Docker自定义网络
1.自定义网络模式,docker提供了三种自定义网络驱动:bridge、overlay、macvlan
2.bridge驱动类似默认的bridge网络模式,但增加了一些新的功能,overlay和macvlan是用于创建跨主机网络
3.建议使用自定义的网络来控制哪些容器可以相互通信,还可以自动DNS解析容器名称到IP地址
(一).bridge
docker network create mynet1 #创建自定义网桥
docker network ls
docker run -d --name demo --network=mynet1 reg.westos.org/library/web
docker run -it --network=mynet1 busybox
1.还可以自己定义网段
在创建时指定参数:–subnet 、–gateway
使用–ip参数可以指定容器ip地址,但必须是在自定义网桥上,默认的bridge模式不支持,同一网桥上的容器是可以互通的
docker network create --subnet 172.20.0.0/24 --gateway 172.20.0.1 net1
docker run -it --ip 172.20.0.10 --network net1 reg.westos.org/busybox
桥接到不同网桥上的容器,彼此是不通信的
docker在设计上就是要隔离不同network的
2.那么如何使两个不同网桥的容器通信呢
再添加一块网卡
docker network connect net1 0e049fe5396e
docker inspect 0e049fe5396e
三.Docker容器通信
容器之间除了使用ip通信外,还可以使用容器名称通信.docker 1.10开始,内嵌了一个DNS server.
dns解析功能必须在自定义网络中使用.启动容器时使用 --name 参数指定容器名称
(一)Joined容器
一种较为特别的网络模式
在容器创建时使用–network=container:vm1指定。(vm1指定的是运行的容器名)
docker run -it --rm --network container:demo reg.westos.org/busybox
docker inspect demo
处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用localhost高效快速通信
(二)–link 可以用来链接2个容器
–link的格式:
–link :alias
name和id是源容器的name和id,alias是源容器在link下的别名
docker run -it --rm --link demo:web reg.westos.org/busybox
当此容器重启时,IP被别的容器占用时,它的新IP解析也会更新到busybox,但其变量ENV不会改变
(三)访问外网
容器如何访问外网是通过iptables的SNAT实现的
数据包过程
(四)外网如何访问容器
外网如何访问容器:端口映射,-p 选项指定映射端口
外网访问容器用到了docker-proxy和iptables DNAT,属于一种冗余;但是在IPV6只能用docker-proxy
1.外部主机访问容器或容器之间的访问主要是docker-proxy实现,在没有火墙策略NAT情况下,外网也可以访问到容器;
2.当docker-proxy进程杀死时,外网也可以通过NAT访问
docker run -d --name demo -p 80:80 reg.westos.org/nginx
iptables -t nat -nL
netstat -antlp
1.删除火墙策略
2.杀死docker-proxy进程
四.跨主机容器网络
1.跨主机网络解决方案
docker原生的overlay和macvlan
第三方的flannel、weave、calico
2.众多网络方案是如何与docker集成在一起的
(1)libnetwork docker容器网络库
(2)CNM (Container Network Model)这个模型对容器网络进行了抽象
CNM分三类组件
Sandbox:容器网络栈,包含容器接口、dns、路由表。(namespace)
Endpoint:作用是将sandbox接入network (veth pair)
Network:包含一组endpoint,同一network的endpoint可以通信
macvlan网络方案实现
Linux kernel提供的一种网卡虚拟化技术
无需Linux bridge,直接使用物理接口,性能极好
在两台docker主机上各添加一块网卡,打开网卡混杂模式
使实验清晰,新添加一块网卡eth1
server1 srever2
ip link set up eth1或ifconfig eth1 up
ip link set eth1 promisc on 打开混杂模式
docker network create -d macvlan --subnet 172.21.0.0/24 --gateway=172.21.0.1 -o parent=eth1 mac_net1 #在两台docker主机上各创建macvlan网络
docker run -it --rm --network mac_net1 --ip 172.21.0.11 busybox #server1 2 分别打开容器,设定ip
4.macvlan网络结构分析
(1)没有新建linux bridge
(2)容器的接口直接与主机网卡连接,无需NAT或端口映
5.macvlan会独占主机网卡,但可以使用vlan子接口实现多macvlan网络
vlan可以将物理二层网络划分为4094个逻辑网络,彼此隔离,vlan id取值为1~4094
6.macvlan网络间的隔离和连通
macvlan网络在二层上是隔离的,所以不同macvlan网络的容器是不能通信的
可以在三层上通过网关将macvlan网络连通起来
docker本身不做任何限制,像传统vlan网络那样管理即可
五.Docker数据卷管理
(一)为什么要用数据卷
1.docker分层文件系统
(1)性能差
(2)生命周期与容器相同
2.docker数据卷
(1)mount到主机中,绕开分层文件系统
(2)和主机磁盘性能相同,容器删除后依然保留
(3)仅限本地磁盘,不能随容器迁移
3.docker提供了两种卷:
(1)bind mount
(2)docker managed volume
(二)bind mount
(1)是将主机上的目录或文件mount到容器里
(2)使用直观高效,易于理解
(3)使用 -v 选项指定路径,格式 :
(4)bind mount 默认权限是读写rw,可以在挂载时指定只读ro,-v选项指定的路径,如果不存在,挂载时会自动创建
docker run -it --rm -v /data1:/data1 -v /data2:/data2:ro -v /etc/yum.repos.d/rhel7.6.repo:/mnt/rhel7.6.repo busybox
docker save reg.westos.org/nginx -o webserver.tar #镜像的打包分享
docker run -d --name demo nginx
docker inspect demo
curl 172.17.0.4
docker rm -f demo
docker run -d --name demo -v /data1:/usr/share/nginx/html nginx
curl 172.17.0.4 #对挂载点文件覆盖掉了
需要重新编写发布目录
(三)docker managed volume
(1)bind mount必须指定host文件系统路径,限制了移植性
(2)docker managed volume 不需要指定mount源,docker自动为容器创建数据卷目录
(3)默认创建的数据卷目录都在 /var/lib/docker/volumes 中
(4)如果挂载时指向容器内已有的目录,原有数据会被复制到volume中
docker volume create webserver
docker run -d --name demo -v webserver:/usr/share/nginx/html nginx
docker inspect demo #这种的不会覆盖
bind mount与docker managed volume对比
相同点:两者都是 host 文件系统中的某个路径
不同点:
六.卷插件简介
1.docker 卷默认使用的是local类型的驱动,只能存在宿主机,跨主机的volume就需要使用第三方的驱动,可以查看以下链接:官网帮助
2.docker官方只提供了卷插件的api,开发者可以根据实际需求定制卷插件驱动api
3.Docker Plugin 是以Web Service的服务运行在每一台Docker Host上的,通过HTTP协议传输RPC风格的JSON数据完成通信
4.Plugin的启动和停止,并不归Docker管理,Docker Daemon依靠在缺省路径下查找Unix Socket文件,自动发现可用的插件
5.当客户端与Daemon交互,使用插件创建数据卷时,Daemon会在后端找到插件对应的 socket 文件,建立连接并发起相应的API请求,最终结合Daemon自身的处理完成客户端的请求
docker通过数据卷插件来访问nfs共享文件
convoy卷插件
convoy卷插件实现,支持三种运行方式:devicemapper、NFS、EBS
以下实验使用nfs方式,在所有节点提前挂载NFS存储
下载软件:
convoy卷插件子命令
参数 | 含义 |
---|---|
convoy list | 列出卷 |
convoy delete | 删除卷 |
convoy snapshot create | 创建快照 |
convoy snapshot delete | 删除快照 |
convoy backup create | 创建备份 |
convoy create res1 --backup | 还原备份 |
server1 server2
yum install nfs-util -y #nfs安装
vim /etc/exports
/nfsdata *(rw,no_root_squash)
systemctl enable --now nfs
showmount -e
mkdir /nfsdata
chmod 777 /nfsdata/
mount 172.25.2.1:/nfsdata/ /nfsdata/ #server2上还要挂载server1的共享
cd
get convoy.tar.gz #convoy卷插件安装
tar zxf convoy.tar.gz
cd convoy/
mv convoy* /usr/local/bin/
convoy daemon --drivers vfs --driver-opts vfs.path=/nfsdata &
cd /var/run/convoy/ #生成的.sock文件
mkdir -p /etc/docker/plugins/
echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec
convoy create vol1 #任意一个节点创建数据卷
convoy list
自动生成目录/nfsdata/vol1
server2
docker run -d --name demo -v vol1:/usr/share/nginx/html --volume-driver convoy nginx #使用卷
cd /nfsdata/vol1/
echo www.test.org > index.html
[root@server2 vol1]# curl 172.17.0.2
www.test.org
docker rm -f demo
server1
docker run -d --name demo -v vol1:/usr/share/nginx/html --volume-driver convoy nginx
[root@server1 convoy]# curl 172.17.0.2
www.test.org
数据还在,数据卷又是共享的,因此再部署一台发布页面也相同