一、Docker的数据管理
Docker将运行中的环境打包成容器然后运行,Docker容器就会产生数据,如果Docker容器不通过docker commit生成新的镜像,使数据作为镜像的一部分保存下来,那么当容器删除后,Docker容器中的数据自然也就没有了。因此为了管理Docker容器中的数据,就需要对数据进行持久化
容器按照业务类吸纳管,总体可以分为两类
无状态的(数据不需要被持久化)
有状态的(数据需要被持久化)
管理Docker容器中的数据主要有两种方式
数据卷
数据卷容器
1.1、数据卷
数据卷是供一个或者多个容器使用的目录或文件,由docker挂载到一个容器或多个容器中。但不属于联合文件系统,因此能够绕过联合文件系统用于持续存储或共享数据
数据卷设置目的就是实现数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时刹车农户其挂载的数据卷
1.1.1、数据卷特点
数据卷可以在容器之间共享和重用,实现宿主机与容器之间传递数据
对数据卷的修改立马有效,在容器内部与本地目录均可对数据卷进行修改
对数据卷的更新,不会影响镜像,对数据与应用进行操作
一个数据卷可以被多个容器同时挂载,一个容器也可以被挂载多个数据卷
1.1.2、数据卷创建
在docker run命令中使用-v挂载数据卷,多次-v可以挂载多个数据卷
1.1.3、匿名挂载
匿名挂载就是在指定数据卷的时候,不指定容器对应的主机路径,这样对映射的主机路径就是默认在/var/lib/docker/volumes/中子哦对那个生成一个随机命名的文件夹
通过docker volume ls命令可以查看当前数据卷的目录情况
# 在web容器中创建/data1和/data2目录
# 这种属于匿名挂载,-v只写了容器内的路径,没有宿主机路径
[root@docker-01 ~]# docker run -d -v /data1 -v /data2 --name web httpd:latest
# 进入到web容器中
[root@docker-01 ~]# docker exec -it web bash
# 查看容器内创建的挂载目录
root@4bae5dfa7cee:/usr/local/apache2# ls -ld /data1
drwxr-xr-x 2 root root 6 May 30 01:59 /data1
root@4bae5dfa7cee:/usr/local/apache2# ls -ld /data2
drwxr-xr-x 2 root root 6 May 30 01:59 /data2
# 查看当前数据卷目录
[root@docker-01 ~]# docker volume ls
DRIVER VOLUME NAME
local 947bc74eec5ad38f05cc40c7a6a8c8edce3c36f56d00bea1c91a79cf4c49c17f
local 98876109bfa0ac5659043c4114d4856efc1b66261a24988d32e95cd867210364
# 检查数据卷
# 不指定宿主机挂载目录,默认会在下面这个路径下挂载
[root@docker-01 ~]# ls /var/lib/docker/volumes/
947bc74eec5ad38f05cc40c7a6a8c8edce3c36f56d00bea1c91a79cf4c49c17f
98876109bfa0ac5659043c4114d4856efc1b66261a24988d32e95cd867210364
1.1.4、具名挂载
具名挂载就是指定具体的文件名称,这里的文件夹名称是在docker指定的默认数据卷路径下
# 在宿主机创建httpd数据卷
# 这种数据具名挂载,-v数据卷名:容器内路径
[root@docker-01 ~]# docker run -d -v httpd:/data2 --name web01 httpd:latest
# 查看当前数据卷目录
[root@docker-01 ~]# docker volume ls
local httpd
# 进入容器查看目录
[root@docker-01 ~]# docker exec -it web01 bash
root@f52462bab4d9:/usr/local/apache2# ls -ld /data2/
drwxr-xr-x 2 root root 6 May 30 02:05 /data2/
# 查看数据卷
# 如果挂载的时候使用的是相对路径,那么也会在默认的docker挂载目录中,但是会自当生成挂载的名称目录
[root@docker-01 ~]# ls /var/lib/docker/volumes/httpd/
_data
1.1.5、指定路径挂载
# 宿主机创建数据
[root@docker-01 ~]# touch /mnt/a.txt
# 将宿主机中的/mnt目录挂载到容器中/data1数据卷
# 这种数据指定路径挂载。-v 宿主机绝对路径:容器内路径
[root@docker-01 ~]# docker run -d -v /mnt/:/data1 --name web02 httpd:latest
# 进入web02容器查看目录
[root@docker-01 ~]# docker exec -it web02 bash
root@94443e0d28fd:/usr/local/apache2# ls /data1/
a.txt
# 删除容器,发现数据依然存在
[root@docker-01 ~]# docker rm -f web02
# 宿主机数据仍然存在
[root@docker-01 ~]# ls /mnt/
a.txt
总之:Docker数据卷的实现原理是在宿主机的/var/lib/docker/volumes目录下,根据卷的名称创建相应的目录,然后在每个卷的目录下创建_data目录,在容器启动时如果使用”-v“参数,Docker会把主机上的目录直接映射到容器的指定目录下,实现数据持久化
1.2、数据卷容器
命名的容器挂载数据卷,其他容器通过挂载这个容器实现数据共享,挂载数据的容器,称之为数据卷容器
1.2.1、数据卷容器特点
是一个普通的容器
数据卷容器专门提供数据卷给其他容器挂载使用
数据卷容器用于在容器之间共享数据
作为数据卷容器并不要求容器中的状态是运行中的
1.2.2、Docker数据卷容器创建
# 若本地没有/data目录,docker容器会自动创建
[root@docker-01 ~]# docker run -it -v /data1 --name centos centos:7 /bin/bash
# 查看目录
[root@883cdd63bdda /]# ls -ld /data1/
drwxr-xr-x 2 root root 6 May 30 02:22 /data1/
## 其他容器创建时挂载数据卷容器
# --volumes-from 指定要从哪个数据卷容器来挂载数据
[root@docker-01 ~]# docker run -it --volumes-from centos --name centos01 centos:7 /bin/bash
# 查看目录
[root@0faf44dec9b5 /]# ls -ld /data1/
drwxr-xr-x 2 root root 6 May 30 02:22 /data1/
# 在centos01容器中创建数据
[root@0faf44dec9b5 /]# touch /data1/123
# 到centos容器中查看数据
[root@docker-01 ~]# docker exec -it centos bash
[root@883cdd63bdda /]# ls -lh /data1/
total 0
-rw-r--r-- 1 root root 0 May 30 02:26 123
注意:删除centos容器,centos01容器中的数据依然存在。数据卷容器的生命周期持续到没有容器使用为止
1.3、扩展
# 创建自定义容器数据卷
docker volume create myvolume
# 查看所有容器数据卷
docker volume ls
# 查看容器数据卷详细信息
docker volume inspect myvolume
# 删除容器数据卷
docker volume rm myvolume
# 删除所有未被挂载的卷
docker volume prune
二、Docker的网络管理
Docker未容器提供网络的方法主要有两种:
端口映射
容器互联
2.1、端口映射
端口映射就是将宿主机的指定端口或随机端口映射到容器中,外部网络访问宿主机的端口便可以访问容器内的服务
可随机映射端口(49000-49900)
# 指定宿主机12345端口映射成容器的80端口
[root@docker-01 ~]# docker run -itd -p 12345:80 --name nginx01 nginx:latest
# 指定随机端口
[root@docker-01 ~]# docker run -itd -P --name nginx02 nginx:latest
2.2、容器互联
容器互联是在源容器和接收容器间建立一条网络通信隧道,实现容器间的互联通信
--link name:[alias]实现容器间互联通信
网络通信是单向的
# 使用Dockerfile构建httpd:centos镜像
[root@docker-01 ~]# mkdir -p /opt/apache
[root@docker-01 ~]# cd /opt/apache/
[root@docker-01 apache]# cat Dockerfile
FROM centos:7
MAINTAINER this is apache image
RUN yum -y update
RUN yum -y install httpd
ADD run.sh /run.sh
RUN chmod 775 /run.sh
RUN systemctl enable httpd
EXPOSE 80
CMD ["/run.sh"]
# 创建启动脚本
[root@docker-01 apache]# cat run.sh
#!/bin/bash
#清理httpd的缓存文件,包括进程文件
rm -rf /run/httpd/*
#指定httpd前台启动
/usr/sbin/apachectl -D FOREGROUND
# 构建镜像
[root@docker-01 apache]# docker build -t httpd:centos .
# 创建容器web02
[root@docker-01 ~]# docker run -d --name web02 httpd:centos
# 创建容器web03链接到web02
[root@docker-01 ~]# docker run -d --name web03 --link web02 httpd:centos
# 测试网络
[root@docker-01 ~]# docker exec -it web03 bash
[root@8e60e7b4d3a2 /]# ping web02
PING web02 (172.17.0.7) 56(84) bytes of data.
64 bytes from web02 (172.17.0.7): icmp_seq=1 ttl=64 time=0.073 ms
64 bytes from web02 (172.17.0.7): icmp_seq=2 ttl=64 time=0.059 ms
三、Docker网络模式
介绍
当项目大规模使用Docker时,容器通信的问题也就产生了,要解决容器通信问题,必须先了解很多关于网络的知识。Docker一共有四种网络模式分别是host模式,container模式,none模式,bridge模式
3.1、Bridge模式
bridge模式是docker的默认网络模式,不写--net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看
如果你之前有Docker使用经验,你可能已经习惯了使用--link参数来使容器互联
随着Docker网络的完善,强烈建议大家将容器加入自定义的Docker网络来连接多个容器,而不是使用--link参数
# 创建一个叫my-net的bridge类型的网络
[root@docker-01 ~]# docker network create -d bridge my-net
# 查看你都有哪些网络
[root@docker-01 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
d0b9c2202d16 bridge bridge local
b4eed7f2cf29 host host local
dcddd408905e my-net bridge local
d63d40e49b96 none null local
# 运行一个容器并连接到新建的my-net网络
[root@docker-01 ~]# docker run -itd --rm --name busybox1 --network my-net busybox sh -c "while true;do echo hello;done"
# 再运行一个容器并加入my-net网络
[root@docker-01 ~]# docker run -it --rm --name busybox2 --network my-net busybox sh -c "ping busybox1"
PING busybox1 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.064 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.060 ms
# 这样,busybox1容器和busybox2容器建立了互联关系
# 如果你有多个容器之间需要互相连接,推荐使用Docker compose
3.2、Host模式
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机公有一个Network Namespace,容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的
[root@docker-01 ~]# docker run -itd --net=host --name docker_host1 busybox
# 使用ifconfig命令可以看到容器的网络和宿主机的是一致的
[root@docker-01 ~]# docker exec -it docker_host1 sh
/ # ifconfig
br-dcddd408905e Link encap:Ethernet HWaddr 02:42:24:E1:C0:A0
inet addr:172.18.0.1 Bcast:172.18.255.255 Mask:255.255.0.0
inet6 addr: fe80::42:24ff:fee1:c0a0/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:3 errors:0 dropped:0 overruns:0 frame:0
TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:84 (84.0 B) TX bytes:266 (266.0 B)
docker0 Link encap:Ethernet HWaddr 02:42:28:07:FA:71
inet addr:172.17.0.1 Bcast:172.17.255.255 Mask:255.255.0.0
inet6 addr: fe80::42:28ff:fe07:fa71/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:12484 errors:0 dropped:0 overruns:0 frame:0
TX packets:20357 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:513092 (501.0 KiB) TX bytes:117156044 (111.7 MiB)
ens33 Link encap:Ethernet HWaddr 00:0C:29:DA:3D:05
inet addr:192.168.93.165 Bcast:192.168.93.255 Mask:255.255.255.0
inet6 addr: fe80::5a88:87b5:1066:6bc5/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:215603 errors:0 dropped:0 overruns:0 frame:0
TX packets:24704 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:307872309 (293.6 MiB) TX bytes:3281773 (3.1 MiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:32 errors:0 dropped:0 overruns:0 frame:0
TX packets:32 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2592 (2.5 KiB) TX bytes:2592 (2.5 KiB)
veth392f914 Link encap:Ethernet HWaddr 0A:B1:45:62:A2:79
inet6 addr: fe80::8b1:45ff:fe62:a279/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:6 errors:0 dropped:0 overruns:0 frame:0
TX packets:11 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:364 (364.0 B) TX bytes:894 (894.0 B)
3.3、Container模式
这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡、配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器处理网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过io网卡设备通信
[root@docker-01 ~]# docker run -idt --name host1 busybox
# 创建host2容器共享host1容器的网络
[root@docker-01 ~]# docker run -itd --net=container:host1 --name host2 busybox
# 查询host1容器的网络
e953cd89eab2c1a34d98481978e3b226b1aa99171febf64569b75995e901a0ee
[root@docker-01 ~]# docker exec -it host1 ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:656 (656.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
# 查看host2容器的网络,确认和host1容器的网络一致
[root@docker-01 ~]# docker exec -it host2 ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:656 (656.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
3.4、None模式
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP
[root@docker-01 ~]# docker run -itd --net=none --name none01 busybox sh
[root@docker-01 ~]# docker exec -it none01 sh
/ # ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
评论区