涉及常见命令:
docker save webserver:v5 -o webserver.tar 镜像打包;
docker network prune 回收不用的docker 资源 ;
docker rm -f `docker ps -aq` docker ps -aq 所有容器;
sysctl -a | grep ipv4.ip_forward 查询内核路由功能;
sysctl -w net.ipv4.ip_forward=1 打开内核路由功能;
docker exec -it demo bash 在demo中使用bash,不用attach上去;(需要demo中装有bash命令);
showmount -e 172.25.254.54 ; 查看72.25.254.54主机上共享的nfs;
1.同个主机的不同容器间通信:
1.1:docker network ls,查看docker网络信息;
1.2:docker network create --subnet 172.20.0.0/24 --gateway 172.20.0.1 net1 ; 创建网络,默认桥接(-d bridge);
1.3 :docker network inspect ;查看网络连接的详细信息;
1.4:docker run -it --rm --ip 172.20.0.10 --network net1 busybox ; --rm 退出后立即删除回收资源,–ip 指定具体ip(未指定默认递增),在 busybox中查看 ip信息: ip addr ;(地址为172.20.0.10) ;
注意:(ctrl+D 为立即退出容器;ctrl+PQ 为后台运行容器);
1.5:在server1中的两个容器didi和demo1为不同vlan,可以通过给demo1加一块网卡实现通信:
docker run -it --name demo1 busybox ; 在 busybox中查看 ip信息: ip addr ;使用的默认的ip(地址为172.17.0.2);
docker run -it --name didi --ip 172.20.0.10 --network net1 busybox ; ping 172.17.0.2 默认不通;
docker network connect net1 demo1 ;给demo1添加net1的ip默认递增(172.20.0.2); 此时demo1为双网卡,可以ping通didi(172.20.0.10);
2.容器的通信机制(iptables 与 docker-proxy);
在容器与外界主机建立连接时,默认会产生两种策略:iptables (DNAT)策略和docker-proxy策略:
2.1:docker run -d --name demo -p 80:80 nginx 创建nginx容器,命名为demo;端口对应本机的80端口;(iptables策略为最后的DNAT)
2.2:删除掉iptables中的策略后,依旧可以正常访问nginx:其他主机中也可以正常访问(curl 172.25.254.101:80 )
2.3:开启新的容器,对应宿主机的8080端口;并删除docker-proxy 策略,依旧可以正常访问nginx;
2.4:如果将两种策略同时删除,通信将会失败;
综上可以得出结论:容器与外界主机建立连接时,默认会产生两种策略:iptables (DNAT)策略和docker-proxy策略,其中任何一种存在都可保证通信正常,如果两种策略都失效,则会通信失败;
3.两台不同主机上实现容器通信:
两台主机(server1和server2)
3-1:在两台主机上添加一个网卡新的网卡eth1:(添加硬件):
3-2:在两台主机中将eth1开为promisc 模式:(ip link set eth1 promisc on ;) eth1的状态需要为 up ;
3-3:docker network create -d macvlan --subnet 172.21.0.0/24 --gateway=172.21.0.1 -o parent=eth1 mac_net1(在server1和server2)上创建相同的docker vlan,使用eth1 网卡 :(server2中相同)
**3-4;**在server1和server2上分别建立容器(1上为172.21.0.11 ; 2上为172.21.0.12);
创建完成后分别使用ip addr 查看ip ,此时 172.21.0.11和 172.21.0.12 可以ping同(跨主机容器通信;) 但是一个容器需要在需要独占一个网卡(parent=eth1):
3-5:由于一个容器需要在需要独占一个网卡,因此,可以使用虚拟子接口的形式创建相同vlan(可以让一块网卡创建多个子接口(4096)):
docker network create -d macvlan --subnet 172.22.0.0/24 --gateway=172.22.0.1 -o parent=eth1.1 mac_net2;(1和2)上创建相同的vlan,使用eth1.1(虚拟的)接口;
docker run -it --rm --network mac_net1 --ip 172.22.0.11 busybox ; 在1和2上分别建立容器(1上为172.22.0.11 ; 2上为172.22.0.12);同理,可以ping同;
4.docker 的数据卷volume:
docker数据卷提供了两种形式:bind mount 和 docker managed volume;
4-1:
bind mount 默认权限是读写,在挂载时可以指定只读(ro),-v 指定路径,不存时会自动创建;
例:docker run -it --name vm1 /etc/yum.repos.d/dvd.repo:/etc/yum.repos.d/dvd.repo:ro rhel7 bash;
docker run -it --rm -v /data1:/data1 -v /data2:/data2:ro -v /etc/yum.repos.d/dvd.repo:/mnt/dvd.repo:ro busybox ;
:ro只读,-v挂载(让宿主机的volume和容器保持相同;) 主机路径:容器路径 :控制权限;
演示结果如下:
4-2:
docker managed volume: docker 自动为容器创建数据卷目录;
例:docker run -d --name web1 -p 80:80 -v /usr/share/nginx/html/ nginx ;
docker volume create registry ;
docker run -d --name registry -v registry:/var/lib/registry registry ;
docker volume inspect registry ;
[
{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/registry/_data",
"Name": "registry",
"Options": {},
"Scope": "local"
}
]
docker run -d --name demo -v webdata:/usr/share/nginx/html:ro nginx ; webdata为数据卷的名字;
docker volume inspect webdata,查看数据卷的详细信息;
docker inspect demo:
docker exec -it demo bash:
**4-3:**两者比较:
5.基于nfs系统使用卷插件convoy实现不同主机上容器间的存储共享,保存容器存储内容的迁移:
docker 不能直接联合nfs使用,因此需要convoy
5-1:完成nfs的存储共享
在server1 和 server2 上 ,同时安装 yum install -y nfs-utils ;
在server1和 server2 中完成配置的设置,使两台机器完成nfs的存储共享;
此时已经完成nfs的存储共享
5-2:部署docker的卷插件:convoy
以下步骤需要在server1和server2中共同完成,以server2为例:
在server1中也完成上述步骤后,使用ps -ax命令可以查看到后台已启动的服务(4028),并将convoy的启动文件放到已经建立好的plugins目录中,并在server1中建立新卷vol1:
建立完成之后在server2中可以看见vol1:
到此,基于nfs的docker卷插件convoy已经部署完成;
5-3:用指定的方式建立容器以完成容器的存储共享:
-----------------------------------.--------------------------------------------------------------------------------------------------------------------------
容器部署完成后没有-p开启端口映射,因此应当访问容器端口:
此时,容器已经个vol1完成存储共享,因此:可以直接更改nginx的默认发布目录:
在server1中可以看见:
[root@server1 plugins]# cd /nfsdata/vol1/
[root@server1 vol1]# ls
50x.html index.html
[root@server1 vol1]# cat index.html
zzzzzyyyyyy
lllllbbbbb
**5-4:**容器的迁移:
在server2中删除:demo
在server1中使用相同的命令建立:docker run -d --name demo -v vol1:/usr/share/nginx/html --volume-driver convoy nginx
数据依旧保留;
[root@server1 vol1]# docker run -d --name demo -v vol1:/usr/share/nginx/html --volume-driver convoy nginx
[root@server1 vol1]# cat index.html
zzzzzyyyyyy
lllllbbbbb
[root@server1 vol1]# curl 172.17.0.2
zzzzzyyyyyy
lllllbbbbb
在server1中访问到原来容器中的内容,迁移完成!!!