docker存储与网络
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了docker存储与网络相关的知识,希望对你有一定的参考价值。
-
场景:启动一个nginx web 对外提供服务。
[[email protected] ~]# docker run -d -p 80:80 --name web nginx:latest [[email protected] ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7b8d4119a9c1 nginx:latest "nginx -g ‘daemon of…" 13 hours ago Up 3 minutes 0.0.0.0:80->80/tcp web
这时可以访问到web界面:
当对访问页面修改后,对容器删除操作#docker exec -it web /bin/sh # cd /usr/share/nginx # echo "im changing container web" >> html/index.html #对默认界面添加内容
重新访问服务:
当执行docker rm -f web 后,重新执行 docker run -d -p 80:80 --name web nginx:latest。
访问到的内容与图1一致,说明修改的内容丢失掉。
镜像是只读,无法修改,修改的只是容器。在容器修改的内容,只对当前有效,容器一旦退出,所有内容也丢失。如何解决? -
Docker的数据卷存储技术:
挂载主机目录(Bind mounts)
数据卷容器(Data Volumes)-
数据卷是供一个或多个容器使用的文件或目录,有多种特性:
可以共享于多个容器之间;
对数据卷的修改会立即生效;
对数据卷的更新与镜像无关;
数据卷会一直存在; -
使用数据挂载的方式:
(1) -v /container-MOUNT_POINT #docker上挂载点,
不给宿主机目录,默认映射的宿主机路径:/var/lib/docker/volumes/
(2) -v /HOST/DIR:/CONTAINER/DIR[:ro|rw]
/HOST/DIR: 宿主机挂载路径
/CONTAINER/DIR :容器上的挂载路径
(3) 在Dockerfile中使用VOLUME指令定义; -
在容器之间共享卷:使用其他容器卷:实际上卷容器也将容器路径映射到本地:/var/lib/docker/volumes/
--volumes-from=[后跟容器名] Mount volumes from the specified container(s) 删除卷: docker rm -v CONTAINER_NAME 注:删除容器的同时删除其卷; docker run --rm选项,表示容器关闭会被自动删除,同时删除其卷(此容器为最后一个使用此卷的容器时); 备份和恢复: 备份: docker run --rm --volumes-from vol_container -v $(pwd):/backup busybox:latest tar cvf /backup/data.tar /data
此时使用重新运行容器。对容器执行删除在启动服务访问到的内容始终一致。
[[email protected] ~]# docker run -d -p 80:80 -v /root/web:/usr/share/nginx/html --name web nginx:latest df9123226d0e3125d8b042a175e147fa5512be3c9bde314a7d078f0be3a0f543 [[email protected] ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES df9123226d0e nginx:latest "nginx -g ‘daemon of…" 5 seconds ago Up 3 seconds 0.0.0.0:80->80/tcp web
-
-
容器的网络:
当dockerd启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机启动的容器会连接至docker0.虚拟网桥工作方式与物理交换机类似,这样主机上的所有容器就通过交换机连接在一个二层网络中。从docker0子网中分配一个IP给容器使用,并将docker0的IP设置为默认网关。在主机上创建一对虚拟网卡veth pair设备,docker将虚拟网卡对的一端放在新创建的容器中命名为eth0,另一端放在宿主机中,以vethxxxxxx这类命名,并将这个虚拟网卡加入docker0中,默认为bridge模式。[[email protected] ~]# ifconfig docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 inet6 fe80::42:8aff:fe57:bc1b prefixlen 64 scopeid 0x20<link> ether 02:42:8a:57:bc:1b txqueuelen 0 (Ethernet) RX packets 92 bytes 11197 (10.9 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 126 bytes 9833 (9.6 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 vethfa86d5d: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 #容器创建的虚拟网卡 inet6 fe80::88cf:4fff:fe51:c391 prefixlen 64 scopeid 0x20<link> ether 8a:cf:4f:51:c3:91 txqueuelen 0 (Ethernet) RX packets 44 bytes 5233 (5.1 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 58 bytes 4623 (4.5 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [[email protected] ~]# docker network ls NETWORK ID NAME DRIVER SCOPE fe7e1e9b398c bridge bridge local 1aa16ea22bd0 host host local fffd9b29f13d none null local
bridge模型
-
基于bridge网络的容器访问外部网络
默认情况下,基于bridge网络容器即可访问外部网络,这是因为默认情况下,docker使用了iptables的snat转发来实现容器对外部的访问(需要内核开启net.ipv4.ip_forward=1)[[email protected] ~]# !s sysctl net.ipv4.ip_forward net.ipv4.ip_forward = 1
如果为 0,说明没有开启转发,则需要手动打开。
sysctl -w net.ipv4.ip_forward=1
/echo 1 > /proc/sys/net/ipv4/ip_forward 此法对当前shell有效,永久有效写配置文件即可。 -
容器的网络模型
1、closed container:封闭式网络
仅有一个接口:loopback
不参与网络通信,仅适用于无须网络通信的应用场景,例如备份、程序调试等;
--net none
eg:docker run --rm -it --net none busybox:lastest /bin/sh --name busybox2、bridged container:(直接桥接(不安全)、nat桥-默认,host only)
此类容器都有两个接口:一半在虚拟机,一半在虚拟网桥上
loopback
以太网接口:桥接至docker daemon设定使用的桥,默认为docker0;
跨主机通信:都直接桥接模式、VLAN--net bridge --network bridge -h, --hostname= HOSTNAME #UTL: --dns DNS_SERVER_IP 指定dns服务器 --add-host "HOSTNAME:IP" 可有多个域名解析 docker0 NAT桥模型上的容器发布给外部网络访问-->映射:相当于添加dnat规则 -p <containerPort> 仅给出了容器端口,表示将指定的容器端口映射至主机上的某随机端口;
eg:docker run --rm -it --net bridge -p 80 busybox:lastest /bin/sh
-p <hostPort>:<containerPort> 将主机的<hostPort>映射为容器的<containerPort> -p <hostIP>::<containerPort> 将主机的<hostIP>上的某随机端口映射为容器的<containerPort> -p <hostIP>:<hostPort>:<containerPort>若主机上有多个IP地址 将主机的<hostIP>上的端口<hostPort>映射为容器的<containerPort> -P-大写, --publish-all 发布所有的端口,跟--expose选项一起指明要暴露出外部的端口; — P --expose 80 --expose 443 --expose 8080 如果不想启动容器时使用默认的docker0桥接口,需要在运行docker daemon命令时使用 -b选项:指明要使用桥; 1.16废弃--> dockerd -b string Attach containers to a network bridge
如何查看端口映射:docker help port
docker port container_name
docker inspect :查看容器某个属性详细信息
docker ps :查看进程3、联盟式容器:监控
启动一个容器时,让其使用某个已经存在的容器的网络名称空间; --net container:CONTAINER_NAME
4、开放式容器:性能比较好(缺点:无法使用端口映射、启动多个容器、建立路由表)
容器使用物理Host的网络名称空间;物理与虚拟容器没有隔离, --net host 直接可以使用物理现有网络
-
- 自定义网络:bridge、overlap、macvlan
[[email protected] ~]# docker network create -d bridge --subnet 10.0.0.0/24 my_bridge #-d --driver指定驱动模式,默认为bridge [[email protected] ~]# docker network ls NETWORK ID NAME DRIVER SCOPE fe7e1e9b398c bridge bridge local 1aa16ea22bd0 host host local 089e7664a35d mynet bridge local fffd9b29f13d none null local [[email protected] ~]# docker run -it --name ab --net my_bridge alpine:latest /bin/sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 11: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:0a:00:00:02 brd ff:ff:ff:ff:ff:ff inet 10.0.0.2/24 brd 10.0.0.255 scope global eth0 valid_lft forever preferred_lft forever / # ping www.baidu.com PING www.baidu.com (163.177.151.110): 56 data bytes 64 bytes from 163.177.151.110: seq=0 ttl=54 time=25.080 ms 64 bytes from 163.177.151.110: seq=1 ttl=54 time=25.241 ms
此时的网络模型结构:
- 如果想让默认bridge网络的c1与my_bridge中的容器通信,可以给c1容器添加一块自定义网络的网卡
[[email protected] ~]# docker network connect my_bridge c1 #此时在c1添加一块my_bridge子网的网卡 / # ip a #c1容器web界面 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 19: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever 21: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:0a:00:00:03 brd ff:ff:ff:ff:ff:ff inet 10.0.0.3/24 brd 10.0.0.255 scope global eth1 valid_lft forever preferred_lft forever
- 如果反过来再自定网络中添加一块默认网卡,但不能指定IP;
[[email protected] ~]# docker network connect bridge ab #此时能自动分配IP [[email protected] ~]# docker network connect --ip 172.17.0.100 bridge ab Error response from daemon: user specified IP address is supported on user defined networks only
至此,可以解决同一宿主机内不同网络名称空间的容器通信,但不同宿主机间是不能通信的。
- 如果想让默认bridge网络的c1与my_bridge中的容器通信,可以给c1容器添加一块自定义网络的网卡
注:同一个网络名称空间内容器间网络互通,c1不能与c2/c3容器通信。
参考文档:
https://success.docker.com/article/networking
以上是关于docker存储与网络的主要内容,如果未能解决你的问题,请参考以下文章
Docker删除报错:Error response from daemon: conflict: unable to delete 08b152afcfae (must be forced)(代码片段