docker创建自定义桥和存储卷
文章目录
- docker创建自定义桥和存储卷
- 一. docker创建自定义桥
- 1. 修改docker网络属性的配置文件,容器之前启动的ip地址不会改变,重启之后会发生改变
- 1.1 启动一个容器
- 1.2 修改配置文件
- 1.3 重启之后之前启动的容器会自动停止,启动容器之后IP地址发生改变
- 1.4 docker启动,容器随之启动,配置文件删除之后还会跟之前设置的一样
- 2. docker创建自定义桥
- 2.1 创建一个自定义桥
- 2.2 使用新建的桥创建容器
- 2.3 在创建一个容器使用默认的桥
- 2.4 在不同网段上的主机上,怎样让b1和b2通信
- 2.4.1 将b1使用的网络模式与b2连接起来或者b2的网络与b1连接起来(connect bridge b1)
- 2.4.2 次时b1的ip地址
- 2.4.3 b2的ip
- 2.4.4 可以ping通b1(ping 通b2)
- 2.5 将两个网段连接起来可以看出是永久的
- 2.6 移除连接的网络
- 二. docker存储卷
- 1. ` CoW (Copy Write ) ` 写时复制
- 2. 想要绕过隔着很多层的镜像删除文件,就需要用到存储卷
- 2.1 存储卷含义:
- 2.2 好处:
- 2.3 docker存在的问题
- 3.存储卷(data volume)管理方式
- 4. 存储卷的分类
- 4.1 绑定挂载卷:Bind mount volume
- 4.2 docker管理卷:Docker-managed volume
- 5. 容器数据管理
- 5.1 docker管理卷语法
- 5.2 挂载主机目录作为数据卷,docker挂载数据卷的默认权限是读写(rw),我们可以指定只读(ro),这样可以在主机上可以写,容器里就没有写的权限
- 5.3 挂载一个本地主机文件作为数据卷
- 5.4 数据卷容器
- 5.4.1 创建一个数据卷容器dbdata,并在其中创建一个数据卷挂载到/dbdata
- 5.4.2 在其他容器中使用--volumes-from来挂载dbdata容器中的数据卷,例如创建db1和db2两个容器,并从dbdata容器挂载数据卷
- 5.4.3 此时db1和db2都挂载同一个数据卷到相同的/dbdata目录,三个容器任何一个在该目录下的写入,其他容器都可以看到。
- 5.4.4 数据卷容器迁移数据
- 5.4.4 数据卷容器迁移数据
一. docker创建自定义桥
1. 修改docker网络属性的配置文件,容器之前启动的ip地址不会改变,重启之后会发生改变
/etc/docker/daemon.json
{
"bip": "192.168.1.5/24",//配置ip
"fixed-cidr": "192.168.1.5/25",
"fixed-cidr-v6": "2001:db8::/64",
"mtu": 1500,//最大传输单元
"default-gateway": "10.20.1.1",//容器网关
"default-gateway-v6": "2001:db8:abcd::89",
"dns": ["10.20.1.2","10.20.1.3"]
}
1.1 启动一个容器
[root@SYL4 ~]# docker run -itd --name b1 busybox
d516dfdf6e6f337e5dd2c3f81983cbc0e358164a8e74f646ff5afdfe934dd0b8
[root@SYL4 ~]# docker exec -it b1 /bin/sh
/ # ip a
8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
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
/ #
1.2 修改配置文件
[root@SYL4 ~]# cd /etc/docker/
[root@SYL4 docker]# ls
daemon.json key.json
[root@SYL4 docker]# vim daemon.json
[root@SYL4 docker]# cat daemon.json
{
"registry-mirrors": ["https://szudx43q.mirror.aliyuncs.com"],
"bip": "192.168.1.1/24" //bridge ip
}
[root@SYL4 docker]# cd
[root@SYL4 ~]# systemctl restart docker
1.3 重启之后之前启动的容器会自动停止,启动容器之后IP地址发生改变
[root@SYL4 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d516dfdf6e6f busybox "sh" About a minute ago Exited (137) 20 seconds ago b1
[root@SYL4 ~]# docker start b1
b1
[root@SYL4 ~]# docker exec -it b1 /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
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
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:c0:a8:01:02 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.2/24 brd 192.168.1.255 scope global eth0
valid_lft forever preferred_lft forever
/ #
1.4 docker启动,容器随之启动,配置文件删除之后还会跟之前设置的一样
--restart=always
[root@SYL4 ~]# docker run -d --name web --restart=always httpd
a9744c95a31c0d9c8c1305340ec621b5c2627c217941c0819f810baebfd9d923
[root@SYL4 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a9744c95a31c httpd "httpd-foreground" 2 minutes ago Up 19 seconds 80/tcp web
删除配置文件
[root@SYL4 ~]# vim /etc/docker/daemon.json
[root@SYL4 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://szudx43q.mirror.aliyuncs.com"]
}
[root@SYL4 ~]# systemctl restart docker
[root@SYL4 ~]#
[root@SYL4 ~]# ip a
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:94:75:2d:81 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.1/24 brd 192.168.1.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:94ff:fe75:2d81/64 scope link
valid_lft forever preferred_lft forever
2. docker创建自定义桥
2.1 创建一个自定义桥
创建桥的帮助文档
[root@SYL4 ~]# docker network create --help
Usage: docker network create [OPTIONS] NETWORK
Create a network
-d, --driver string Driver to manage the Network (default "bridge")
管理网络的驱动程序(默认为“桥接”)
--subnet strings Subnet in CIDR format that represents a network segment
CIDR格式的子网,代表一个网段
--gateway strings IPv4 or IPv6 Gateway for the master subnet
主子网的IPv4或IPv6网关
创建桥
[root@SYL4 ~]# docker network create -d bridge --subnet "192.168.1.0/24" --gateway "192.168.1.1" br0
7154f35a21abfd7a8c2ecaf814df35daef9fd5b04f5a9ce925a76560def0264f
[root@SYL4 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
7154f35a21ab br0 bridge local
9bccf1e5046f bridge bridge local
bd7972230eef host host local
7a7053bea0be none null local
[root@SYL4 ~]#
2.2 使用新建的桥创建容器
[root@SYL4 ~]# docker run -it --name b1 --network br0 busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
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: eth0@if20: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:c0:a8:01:02 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.2/24 brd 192.168.1.255 scope global eth0
valid_lft forever preferred_lft forever
/ #
2.3 在创建一个容器使用默认的桥
[root@SYL4 ~]# docker run -it --name b2 --network bridge busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
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
21: eth0@if22: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
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
/ #
2.4 在不同网段上的主机上,怎样让b1和b2通信
2.4.1 将b1使用的网络模式与b2连接起来或者b2的网络与b1连接起来(connect bridge b1)
[root@SYL4 ~]# docker network connect br0 b2
[root@SYL4 ~]#
b2的网络与b1连接起来
[root@SYL4 ~]# docker network connect bridge b1
2.4.2 次时b1的ip地址
[root@SYL4 ~]# docker run -it --name b1 --network br0 busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
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: eth0@if20: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:c0:a8:01:02 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.2/24 brd 192.168.1.255 scope global eth0
valid_lft forever preferred_lft forever
/ #
b2连接b1
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
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: eth0@if20: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:c0:a8:01:02 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.2/24 brd 192.168.1.255 scope global eth0
valid_lft forever preferred_lft forever
25: eth1@if26: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.3/16 brd 172.17.255.255 scope global eth1
valid_lft forever preferred_lft forever
/ #
2.4.3 b2的ip
[root@SYL4 ~]# docker run -it --name b2 --network bridge busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
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
21: eth0@if22: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
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
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
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
21: eth0@if22: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
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
23: eth1@if24: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:c0:a8:01:03 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.3/24 brd 192.168.1.255 scope global eth1
valid_lft forever preferred_lft forever
2.4.4 可以ping通b1(ping 通b2)
/ # ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2): 56 data bytes
64 bytes from 192.168.1.2: seq=0 ttl=64 time=0.167 ms
64 bytes from 192.168.1.2: seq=1 ttl=64 time=0.221 ms
64 bytes from 192.168.1.2: seq=2 ttl=64 time=0.062 ms
^C
--- 192.168.1.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.062/0.150/0.221 ms
/ #
/ # ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.197 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.190 ms
^C
--- 172.17.0.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.190/0.193/0.197 ms
/ #
2.5 将两个网段连接起来可以看出是永久的
重启容器,docker,主机都可以看出
[root@SYL4 ~]# docker restart b2
b2
[root@SYL4 ~]# docker network connect br0 b2
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
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
29: eth0@if30: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
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
31: eth1@if32: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:c0:a8:01:02 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.2/24 brd 192.168.1.255 scope global eth1
valid_lft forever preferred_lft forever
/ #
2.6 移除连接的网络
[root@SYL4 ~]# docker network disconnect br0 b2
[root@SYL4 ~]#
[root@SYL4 ~]# docker exec -it b2 /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
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
29: eth0@if30: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
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
/ #
二. docker存储卷
1. CoW (Copy Write )
写时复制
- 如果容器中修改已经存在的文件或者说删除,那么该文件是隐藏了,没有被删除
运行的容器
[root@SYL4 ~]# docker run -it --name b1 busybox /bin/sh/ # mkdir data
/ # echo 'hello world' > data/index.html
/ # cat data/index.html
hello world
/ #
制作镜像
[root@SYL4 ~]# docker commit -a 'xiaoyinguhong <3066347695@qq.com>' -c 'CMD ["/bin/sh"]' -p b1 busybox:2060.1
sha256:5fae0fd8930fefe4d6f73de77326a051908363476501fdcccf7369a0cc6853de
[root@SYL4 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox 2060.1 5fae0fd8930f 12 seconds ago 1.24MB
用制作的镜像运行容器
[root@SYL4 ~]# docker run -it --name b2 busybox:2060.1
/ # ls
bin dev home root tmp var
data etc proc sys usr
/ # cat data/index.html
hello world
/ #
删除之后
/ # rm -rf data
/ # ls
bin dev etc home proc root sys tmp usr var
/ #
退出之后删除再次运行一个容器,发现没有被删除
[root@SYL4 ~]# docker run -it --name b1 --rm busybox:2060.1
/ # ls
bin dev home root tmp var
data etc proc sys usr
/ # cat data/index.html
hello world
/ #
2. 想要绕过隔着很多层的镜像删除文件,就需要用到存储卷
2.1 存储卷含义:
- 将主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立绑定关系
- 主机上的这个与容器形成绑定关系的目录被称作存储卷。
2.2 好处:
- 容器中跑的进程的所有有效数据都保存在存储卷中,脱离容器自身文件系统
- 只要不删除与此容器绑定的在宿主机上的这个存储目录,就不用担心数据丢失了
- 容器可以脱离主机的限制,可以在任意一台部署了docker的主机上运行容器,而数据放在共享存储文件系统上
- 手动的将容器的数据挂载到一台nfs服务器上,那么只要容器在主机上停止运行或者被删除了再重建,只要关联到硬盘上的这个目录下,那么其数据还存在
2.3 docker存在的问题
- 存储于联合挂载文件系统中,不易于宿主机访问
- 容器间数据共享不便
- 删除容器其数据会丢失
3.存储卷(data volume)管理方式
- 镜像可以重复使用,卷可以共享
- 卷独立于容器的生命周期实现数据持久化,删除容器之时既不会删除卷,也不会对未被引用的卷做垃圾回收操作。
- 卷不仅和主机分离,也可以和容器分离
4. 存储卷的分类
4.1 绑定挂载卷:Bind mount volume
- 指向主机文件系统上用户指定位置的卷
4.2 docker管理卷:Docker-managed volume
- Docker守护进程在Docker所拥有的主机文件系统中创建管理卷
- 运行一个容器,可以在该容器创建文件
[root@SYL4 ~]# docker run -it --name b1 busybox:2060.1 /bin/sh
/ # ls
bin dev home root tmp var
data etc proc sys usr
/ #
/ # touch abc
- 找到运行容器目录所在的位置
[root@SYL4 ~]# docker inspect b1
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/f54ec6d735f4caf35c006983278d36d6f4b580705991d4dc6cba5dab8289c0c2-init/diff:/var/lib/docker/overlay2/354e0e5874300688605435ebdc8faf711122614113de443208f77ac4c3e37715/diff:/var/lib/docker/overlay2/d4419c92cf32b5d4facff17647e34d0aa36792605a9c60a81f6c998971a18b26/diff",
"MergedDir": "/var/lib/docker/overlay2/f54ec6d735f4caf35c006983278d36d6f4b580705991d4dc6cba5dab8289c0c2/merged",//合并后的目录
"UpperDir": "/var/lib/docker/overlay2/f54ec6d735f4caf35c006983278d36d6f4b580705991d4dc6cba5dab8289c0c2/diff",
"WorkDir": "/var/lib/docker/overlay2/f54ec6d735f4caf35c006983278d36d6f4b580705991d4dc6cba5dab8289c0c2/work"//工作目录
},
- 进行创建或删除文件,那么容器里面文件也会随之相应的操作
[root@SYL4 ~]# cd /var/lib/docker/overlay2/f54ec6d735f4caf35c006983278d36d6f4b580705991d4dc6cba5dab8289c0c2
[root@SYL4 f54ec6d735f4caf35c006983278d36d6f4b580705991d4dc6cba5dab8289c0c2]# ls
diff link lower merged work
[root@SYL4 f54ec6d735f4caf35c006983278d36d6f4b580705991d4dc6cba5dab8289c0c2]# ls
diff link lower merged work
[root@SYL4 f54ec6d735f4caf35c006983278d36d6f4b580705991d4dc6cba5dab8289c0c2]# cd merged/
[root@SYL4 merged]# ls
abc bin data dev etc home proc root sys tmp usr var
[root@SYL4 merged]# rm -f abc
[root@SYL4 merged]#
将容器删除后该目录会被删除
[root@SYL4 merged]# ls
[root@SYL4 merged]#
5. 容器数据管理
- 用户在使用Docker的过程中,往往需要能查看容器内应用产生的数据,或者需要把容器内的数据进行备份,甚至多个容器之间进行数据的共享,这必然涉及容器的数据管理操作。
- 容器中管理数据主要有两种方式:
- 数据卷(Data Volumes),将数据放在本机的目录里
- 数据卷容器(Data Volumes Containers),将一个数据放在容器里
5.1 docker管理卷语法
- docker管理卷,容器被删除,文件也没了
docker run -it --name CONTAINER_NAME -v VOLUMEDIR/容器的目录 IMAGE_NAME
[root@SYL4 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@SYL4 ~]# docker run -it --rm --name b1 -v /data busybox /bin/sh
/ # ls
bin dev home root tmp var
data etc proc sys usr
/ # ls /data
/ # ls /data
abc
/ #
[root@SYL4 ~]# cd /var/lib/docker/volumes/0ebf585a8e9d34cead93e018700358bd30bf7b2530130f80bd5178b3d51a3545/_data
[root@SYL4 _data]# ls
[root@SYL4 _data]# touch abc
[root@SYL4 _data]# ls
abc
[root@SYL4 _data]# rm -f abc
[root@SYL4 _data]# ls
[root@SYL4 _data]#
- 绑定挂载卷
docker run -it --name CONTAINER_NAME -v HOSTDIR:VOLUMEDIR IMAGE_NAME
[root@SYL4 ~]# docker run -it --rm --name b1 -v /web:/data busybox /bin/sh
/ # cd data/
/data # ls
/data # cat index.html
bloool lll
/data #
[root@SYL4 ~]# cd /web/
[root@SYL4 web]# ls
[root@SYL4 web]# echo 'bloool lll' > index.html 真机创建
[root@SYL4 web]#
退出之后
[root@SYL4 ~]# docker run -it --rm --name b1 -v /web:/data busybox /bin/sh
/ # cd data/
/data # ls
/data # cat index.html
bloool lll
/data # exit
[root@SYL4 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@SYL4 ~]#
真机上
[root@SYL4 web]# ls
index.html
[root@SYL4 web]# cat index.html
bloool lll
[root@SYL4 web]#
- 实例
终端:将下载的网站内容复制到网站内
[root@SYL4 ~]# mv 经典游戏《合金弹头》GIF和原画素材打包-合金彈頭\ GIF動_爱给网_aigei_com.gif /web/
[root@SYL4 ~]#
[root@SYL4 web]# ls
''$'\347\273\217\345\205\270\346\270\270\346\210\217\343\200\212\345\220\210\351\207\221\345\274\271\345\244\264\343\200\213''GIF'$'\345\222\214\345\216\237\347\224\273\347\264\240\346\235\220\346\211\223\345\214\205''-'$'\345\220\210\351\207\221\345\275\210\351\240\255'' GIF'$'\345\213\225''_'$'\347\210\261\347\273\231\347\275\221''_aigei_com.gif'
[root@SYL4 web]#
容器,挂载一个主机目录作为数据卷
[root@SYL4 ~]# docker run -d --name web -v /web/:/usr/local/apache2/htdocs -p 80:80 httpd
7454f71734910921834066c102be3aa28cd21e4ae5f3ef429c273af28680ff1c
[root@SYL4 ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:80 [::]:*
LISTEN 0 128 [::]:22 [::]:*
[root@SYL4 ~]#
- 访问
5.2 挂载主机目录作为数据卷,docker挂载数据卷的默认权限是读写(rw),我们可以指定只读(ro),这样可以在主机上可以写,容器里就没有写的权限
容器里
[root@SYL4 ~]# docker run -d --name web -v /web/:/usr/local/apache2/htdocs:ro -p 80:80 httpd
d50f22abb4212e601b6d55da3d766f86eb424f337e92763332418462de8df3d2
[root@SYL4 ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:80 [::]:*
LISTEN 0 128 [::]:22 [::]:*
[root@SYL4 ~]# docker exec -it web /bin/bash
root@d50f22abb421:/usr/local/apache2# cd htdocs/
root@d50f22abb421:/usr/local/apache2/htdocs# touch abc
touch: cannot touch 'abc': Read-only file system//只读权限
root@d50f22abb421:/usr/local/apache2/htdocs# ls
abc
''$'\347\273\217\345\205\270\346\270\270\346\210\217\343\200\212\345\220\210\351\207\221\345\274\271\345\244\264\343\200\213''GIF'$'\345\222\214\345\216\237\347\224\273\347\264\240\346\235\220\346\211\223\345\214\205''-'$'\345\220\210\351\207\221\345\275\210\351\240\255'' GIF'$'\345\213\225''_'$'\347\210\261\347\273\231\347\275\221''_aigei_com.gif'
root@d50f22abb421:/usr/local/apache2/htdocs#
真机
[root@SYL4 web]# touch abc
[root@SYL4 web]# ls
abc
''$'\347\273\217\345\205\270\346\270\270\346\210\217\343\200\212\345\220\210\351\207\221\345\274\271\345\244\264\343\200\213''GIF'$'\345\222\214\345\216\237\347\224\273\347\264\240\346\235\220\346\211\223\345\214\205''-'$'\345\220\210\351\207\221\345\275\210\351\240\255'' GIF'$'\345\213\225''_'$'\347\210\261\347\273\231\347\275\221''_aigei_com.gif'
[root@SYL4 web]#
5.3 挂载一个本地主机文件作为数据卷
[root@localhost ~]# docker run -it --rm -v ~/.bash_history:/.bash_history centos /bin/bash
- 可以记录在容器输入过的命令历史了
- 直接挂载一个文件到容器,使用文件编辑工具,包括vi或者sed去修改文件内容的时候,可能会造成inode的改变,这样将会导致错误
5.4 数据卷容器
- 数据卷容器就是一个专门用来放数据的容器,而这个容器可以被其他容器所挂载
5.4.1 创建一个数据卷容器dbdata,并在其中创建一个数据卷挂载到/dbdata
[root@SYL4 ~]# docker run -itd --name dbdata -v /dbdata busybox
f0593e729f5b7558dd3fcf1dcf14cbbb6e99e87ce348ea02fb7730d748712c0c
[root@SYL4 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f0593e729f5b busybox "sh" 8 seconds ago Up 7 seconds dbdata
[root@SYL4 ~]#
5.4.2 在其他容器中使用–volumes-from来挂载dbdata容器中的数据卷,例如创建db1和db2两个容器,并从dbdata容器挂载数据卷
[root@SYL4 ~]# docker run -itd --name db1 --volumes-from dbdata busybox
8ee294c77cf74b2ee3bdd84ac03ccc7a80aff78f0beb55f04f123e92dfba1f1e
[root@SYL4 ~]# docker run -itd --name db2 --volumes-from dbdata busybox
8fff538c819783b42ddd0d3b63853fc2b11f01f3360f78a68401813fff606a62
[root@SYL4 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8fff538c8197 busybox "sh" 6 seconds ago Up 4 seconds db2
8ee294c77cf7 busybox "sh" 24 seconds ago Up 23 seconds db1
f0593e729f5b busybox "sh" 2 minutes ago Up 2 minutes dbdata
[root@SYL4 ~]#
5.4.3 此时db1和db2都挂载同一个数据卷到相同的/dbdata目录,三个容器任何一个在该目录下的写入,其他容器都可以看到。
- 在db1中创建文件
[root@SYL4 ~]# docker exec -it db1 /bin/sh
/ # ls
bin dev home root tmp var
dbdata etc proc sys usr
/ # cd dbdata/
/dbdata # touch douluo
/dbdata # ls
douluo
/dbdata #
/dbdata # rm -f douluo
/dbdata # ls
/dbdata #
- 用容器db2查看
[root@SYL4 ~]# docker exec -it db2 /bin/sh
/ # ls
bin dev home root tmp var
dbdata etc proc sys usr
/ # cd dbdata/
/dbdata # ls
douluo
/dbdata #
/dbdata # ls
/dbdata #
- 可以多次使用–volumes-from参数来从多个容器挂载多个数据卷。还可以从其他已挂载了容器卷的容器来挂载数据卷
在db2生成内容
[root@SYL4 ~]# docker exec -it db2 /bin/sh
/ # ls
bin dev home root tmp var
dbdata etc proc sys usr
/ # cd dbdata/
/dbdata # ls
douluo
/dbdata # ls
/dbdata # echo '123466' > abc
/dbdata # cat abc
123466
/dbdata #
可以在db3中查看
[root@SYL4 ~]# docker run -itd --name db3 --volumes-from db1 busyboxfb270a32c0e4080fb3d02014aea9d5e5bae79e5df48c5210c8b8c1182bccc7fb
[root@SYL4 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fb270a32c0e4 busybox "sh" 5 seconds ago Up 4 seconds db3
8fff538c8197 busybox "sh" 8 minutes ago Up 8 minutes db2
8ee294c77cf7 busybox "sh" 9 minutes ago Up 9 minutes db1
f0593e729f5b busybox "sh" 11 minutes ago Up 11 minutes dbdata
[root@SYL4 ~]# docker exec -it db3 /bin/sh
/ # ls
bin dev home root tmp var
dbdata etc proc sys usr
/ # cd dbdata/
/dbdata # cat abc
123466
/dbdata #
- 使用–volumes-from参数所挂载数据卷的容器自身并不需要保持在运行状态。
- 如果删除了挂载的容器(包括dbdata、db1和db2),数据卷并不会被自动删除。如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时显式使用docker rm -v命令来指定同时删除关联的容器。
将挂载目录dbdata删除,db3目录下还遗留之前挂载的目录里
[root@SYL4 ~]# docker rm -f dbdata db2 db1
dbdata
db2
db1
[root@SYL4 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fb270a32c0e4 busybox "sh" 12 minutes ago Up 12 minutes db3
[root@SYL4 ~]# docker exec -it db3 /bin/sh
/ # ls
bin dev home root tmp var
dbdata etc proc sys usr
/ # cd dbdata/
/dbdata # mkdir aba
/dbdata # ls
aba abc
/dbdata # exit
[root@SYL4 ~]# docker run -itd --name db4 --volumes-from db3 busybox
b9832f1fd2f73c4abe38ded167cab093a54b936efb5a12b34c87b3c1a46f0003
[root@SYL4 ~]# docker exec -it db4 /bin/sh
/ # cd dbdata/
/dbdata # ls
aba abc
/dbdata #
- 将容器都删除,没加-v,所保存的数据还在真机上保存
[root@SYL4 ~]# docker rm -f db3 db4
[root@SYL4 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@SYL4 ~]#
[root@SYL4 ~]# cd /var/lib/docker/volumes/
[root@SYL4 volumes]# ls
77fafaced6ad82d5a2a524afc1d848ca11fb00092d290c53f9eadc06ac834be8
backingFsBlockDev
metadata.db
[root@SYL4 volumes]# cd 77fafaced6ad82d5a2a524afc1d848ca11fb00092d290c53f9eadc06ac834be8/_data/
[root@SYL4 _data]# ls
aba abc
[root@SYL4 _data]#
5.4.4 数据卷容器迁移数据
- 可以利用数据卷容器对其中的数据卷进行备份、恢复,以实现数据的迁移。
- 备份
[root@SYL4 ~]# docker run --name worker --volumes-from dbdata -v $(pwd):/backup centos tar -jcf /backup/backup.tar /dbdata
[root@SYL4 ~]# pwd
/root
[root@SYL4 ~]#
首先运行一个名字叫worker的容器,数据来源于dbdata,-v把当前目录跟容器里的backup做一个绑定关系,用centos镜像运行,用tar -jcf压缩/dbdata目录下的文件,放在本机的/backup/目录下,命名为/backup/backup.tar
- 恢复
- 首先创建一个带有数据卷的容器dbdata2:
[root@SYL4 ~]# docker run -it --name dbdata2 -v /dbdata centos /bin/bash
先运行一个容器名为dbdata2
- 然后创建另一个新的容器,挂载dbdata2容器,并使用untar解压备份文件到所挂载的容器卷中即可:
[root@SYL4 ~]# docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xf /backup/backup.tar
创建另外一个容器,数据来源dbdata2,解压在/backup目录下
5.4.4 数据卷容器迁移数据
- 可以利用数据卷容器对其中的数据卷进行备份、恢复,以实现数据的迁移。
- 备份
[root@SYL4 ~]# docker run --name worker --volumes-from dbdata -v $(pwd):/backup centos tar -jcf /backup/backup.tar /dbdata
[root@SYL4 ~]# pwd
/root
[root@SYL4 ~]#
首先运行一个名字叫worker的容器,数据来源于dbdata,-v把当前目录跟容器里的backup做一个绑定关系,用centos镜像运行,用tar -jcf压缩/dbdata目录下的文件,放在本机的/backup/目录下,命名为/backup/backup.tar
- 恢复
- 首先创建一个带有数据卷的容器dbdata2:
[root@SYL4 ~]# docker run -it --name dbdata2 -v /dbdata centos /bin/bash
先运行一个容器名为dbdata2
- 然后创建另一个新的容器,挂载dbdata2容器,并使用untar解压备份文件到所挂载的容器卷中即可:
[root@SYL4 ~]# docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xf /backup/backup.tar
创建另外一个容器,数据来源dbdata2,解压在/backup目录下