一、数据卷管理
1、宿主机映射到容器
(1)创建数据卷
映射内容默认存放在(挂载点):/var/lib/docker/volumes/卷名/_data
语法:docker volume create 卷名
[root@docker ~]# docker volume create nginx //创建了一个名为nginx的数据卷
nginx
[root@docker ~]# cd /var/lib/docker/volumes/
[root@docker volumes]# ls
metadata.db nginx
[root@docker volumes]# cd nginx/
[root@docker nginx]# ls
_data
[root@docker nginx]# ls _data/
[root@docker nginx]#
(2)查看数据卷
语法:docker volume inspect 卷名
可以查看创建的时间,挂载点等信息
[root@docker nginx]# docker volume inspect nginx
[
{
"CreatedAt": "2020-09-23T18:35:42+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/nginx/_data",
"Name": "nginx",
"Options": {},
"Scope": "local"
}
]
(3)查看全部数据卷
[root@docker nginx]# docker volume ls
DRIVER VOLUME NAME
local nginx
(4)应用数据卷
语法:docker run -v 数据卷名称:容器内部的路径 镜像ID
1、如果数据卷不存在,docker会自己创建
这里启动了一个nginx容器,名为volume_nginx的数据卷映射到nginx容器的主页目录/usr/share/nginx/html
[root@docker _data]# docker run -d -p 80:80 --name nginx -v volume_nginx:/usr/share/nginx/html 7e4d58f0e5f3
901158bccbdc7aa0d2f35a701b2dcef3d4582549085d99fd56dc9f1f3e56f484
[root@docker _data]#
[root@docker _data]#
[root@docker _data]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
901158bccbdc 7e4d58f0e5f3 "/docker-entrypoint.…" 2 seconds ago Up 1 second 0.0.0.0:80->80/tcp nginx
访问nginx主页
查看挂载点下面,多了2个网页文件,是从容器那里同步过来的
[root@docker _data]# pwd
/var/lib/docker/volumes/volume_nginx/_data
[root@docker _data]# ls
50x.html index.html
修改主页测试
再次访问nginx主页,主页内容已经显示为修改过的内容,说明两边进行了同步
这时也可以进入nginx容器,查看主页内容,也可以看到内容被修改了
2、先创建数据卷,再启动容器
因为之前创建了一个名为nginx的数据卷,这时启动nginx容器,端口映射为81端口
[root@docker _data]# docker run -d -p 81:80 --name nginx1 -v nginx:/usr/share/nginx/html 7e4d58f0e5f3
c8e21b3c7feaba3921c36d5488c4c184ba2245c35d3362af09017038d8b88c07
[root@docker _data]#
[root@docker _data]#
[root@docker _data]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c8e21b3c7fea 7e4d58f0e5f3 "/docker-entrypoint.…" 2 seconds ago Up 1 second 0.0.0.0:81->80/tcp nginx1
901158bccbdc 7e4d58f0e5f3 "/docker-entrypoint.…" 9 minutes ago Up 9 minutes 0.0.0.0:80->80/tcp nginx
[root@docker _data]#
[root@docker _data]# cd /var/lib/docker/volumes/
[root@docker volumes]# ls
metadata.db nginx volume_nginx
[root@docker volumes]# cd nginx/_data/
[root@docker _data]# ls
50x.html index.html
访问nginx主页
3、指定一个路径作为存放位置
语法:docker run -v 路径:容器内部的路径 镜像ID
[root@docker _data]# docker run -d -p 82:80 --name nginx2 -v /opt/volume_nginx:/usr/share/nginx/html 7e4d58f0e5f3
82c1489c992743c54d28a80952f7f529e9942c66a677da52148bd36e0d1a9aa6
[root@docker _data]#
[root@docker _data]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
82c1489c9927 7e4d58f0e5f3 "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 0.0.0.0:82->80/tcp nginx2
c8e21b3c7fea 7e4d58f0e5f3 "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 0.0.0.0:81->80/tcp nginx1
901158bccbdc 7e4d58f0e5f3 "/docker-entrypoint.…" 13 minutes ago Up 13 minutes 0.0.0.0:80->80/tcp nginx
[root@docker _data]# cd /opt/volume_nginx/
[root@docker volume_nginx]# ls
[root@docker volume_nginx]#
这时访问主页
主页显示无法访问
进入nginx容器,发现主页目录下并没有任何网页文件
[root@docker ~]# docker exec -it 82c1489c9927 /bin/bash
root@82c1489c9927:/#
root@82c1489c9927:/# cd /usr/share/nginx/html/
root@82c1489c9927:/usr/share/nginx/html# ls
root@82c1489c9927:/usr/share/nginx/html#
这时到挂载目录下创建一个网页
[root@docker _data]# cd /opt/volume_nginx/
[root@docker volume_nginx]# ls
[root@docker volume_nginx]#
[root@docker volume_nginx]# vim index.html
<h1>this is nginx!!!</h1>
再次访问网页
再次进入nginx容器,查看网页已经同步过来了
[root@docker ~]# docker exec -it 82c1489c9927 /bin/bash
root@82c1489c9927:/#
root@82c1489c9927:/# cd /usr/share/nginx/html/
root@82c1489c9927:/usr/share/nginx/html# ls
index.html
root@82c1489c9927:/usr/share/nginx/html# cat index.html
<h1>this is nginx!!!</h1>
容器内目录设定为只读
[root@docker ~]# docker run -d -p 84:80 --name nginx4 -v nginx:/usr/share/nginx/html:ro 7e4d58f0e5f3
8946ad7a59972366c02ede1f87fce9655c36b07ecb649f74a96f280f61939a46
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8946ad7a5997 7e4d58f0e5f3 "/docker-entrypoint.…" 5 seconds ago Up 4 seconds 0.0.0.0:84->80/tcp nginx4
进入容器的主页目录,尝试拷贝文件报错
[root@docker ~]# docker exec -it 8946ad7a5997 /bin/bash
root@8946ad7a5997:/#
root@8946ad7a5997:/# cd /usr/share/nginx/html/
root@8946ad7a5997:/usr/share/nginx/html# ls
50x.html index.html
root@8946ad7a5997:/usr/share/nginx/html# cp index.html index2.html
cp: cannot create regular file 'index2.html': Read-only file system
总结:如果是指定名称,会将容器里自带的文件映射过来,如果是指定路径的话默认不会把自带的文件映射过来,一般这种情况用的比较多,可以自己把想要的东西放进去
2、容器间的数据卷映射
如果你有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器。数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。
将容器centos的两个目录/data1 和 /data2当做容器centos7的挂载点
[root@docker ~]# docker run --name centos -v /data1 -v /data2 -it centos:7 /bin/bash
[root@033859a7258c /]#
[root@033859a7258c /]# ls
anaconda-post.log bin data1 data2 dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@033859a7258c /]# cd data1/
[root@033859a7258c data1]# echo 111 > 111.txt
[root@033859a7258c data1]# ls
111.txt
[root@033859a7258c data1]# cd ../data2/
[root@033859a7258c data2]# echo 222 > 222.txt
[root@033859a7258c data2]#
[root@033859a7258c data2]# ls
222.txt
被挂载的容器需要–volumes-from指定另一个容器的挂载,然后就可以在这个容器看到2个挂载目录了
[root@docker ~]# docker run --name centos7 --volumes-from centos -it centos:7 /bin/bash
[root@d98568536b76 /]#
[root@d98568536b76 /]# ls
anaconda-post.log bin data1 data2 dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@d98568536b76 /]# ls data1/
111.txt
[root@d98568536b76 /]# ls data2/
222.txt
[root@d98568536b76 /]#
查看容器运行状态
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d98568536b76 centos:7 "/bin/bash" 34 seconds ago Exited (0) 4 seconds ago centos7
033859a7258c centos:7 "/bin/bash" 3 minutes ago Exited (127) 2 minutes ago centos
现在到centos7的/data2下面写入一个新的文件2222.txt
[root@d98568536b76 /]# cd data2
[root@d98568536b76 data2]# ls
222.txt
[root@d98568536b76 data2]# echo 2222 > 2222.txt
[root@d98568536b76 data2]#
[root@d98568536b76 data2]# ls
222.txt 2222.txt
进入容器centos查看,新建的文件也已经同步过来了
[root@docker ~]# docker exec -it 033859a7258c /bin/bash
[root@033859a7258c /]# ls
anaconda-post.log bin data1 data2 dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@033859a7258c /]# cd data2
[root@033859a7258c data2]# ls
222.txt 2222.txt
如果一个容器挂载了volume,即使容器停止了运行,该volume仍然存在,其他容器仍然可以继续–volumes-from它
[root@docker ~]# docker run --volumes-from centos --name centos7-1 -it centos:7 /bin/bash
[root@073b0c54e62b /]#
[root@073b0c54e62b /]# ls
anaconda-post.log bin data1 data2 dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@073b0c54e62b /]# ls data1/
111.txt
但这个时候在容器的挂载点中写入内容,会把数据卷容器的挂载点里的内容覆盖掉
[root@073b0c54e62b /]# cd data1/
[root@073b0c54e62b data1]# echo 1111 > 1111.txt
[root@073b0c54e62b data1]# ls
1111.txt
(1)删除数据卷
查看所有数据卷
[root@docker ~]# docker volume ls
DRIVER VOLUME NAME
local 24c8b7c3f24f6a2f832d1653e5e96f1a5f47fb55e17e6273d1289148e583ec96
local 992137d1bae13151b538b451a270b5f71399a7e7543932ebde08609e15c93ea3
local nginx
local volume_nginx
直接删除数据卷失败,因为数据卷被挂载到2个容器中
[root@docker ~]# docker volume rm nginx
Error response from daemon: remove nginx: volume is in use - [c8e21b3c7feaba3921c36d5488c4c184ba2245c35d3362af09017038d8b88c07, 8946ad7a59972366c02ede1f87fce9655c36b07ecb649f74a96f280f61939a46]
必须要删除容器才能够删除挂载的数据卷
[root@docker ~]# docker stop c8e21b3c7fea
c8e21b3c7fea
[root@docker ~]# docker stop 89
89
[root@docker ~]# docker volume rm nginx
Error response from daemon: remove nginx: volume is in use - [c8e21b3c7feaba3921c36d5488c4c184ba2245c35d3362af09017038d8b88c07, 8946ad7a59972366c02ede1f87fce9655c36b07ecb649f74a96f280f61939a46]
[root@docker ~]# docker rm c8
c8
[root@docker ~]# docker rm 89
89
[root@docker ~]# docker volume rm nginx
nginx
[root@docker ~]# docker volume ls
DRIVER VOLUME NAME
local 24c8b7c3f24f6a2f832d1653e5e96f1a5f47fb55e17e6273d1289148e583ec96
local 992137d1bae13151b538b451a270b5f71399a7e7543932ebde08609e15c93ea3
local volume_nginx
宿主机上默认的映射目录也被删除了
[root@docker ~]# cd /var/lib/docker/volumes
[root@docker volumes]# ls
24c8b7c3f24f6a2f832d1653e5e96f1a5f47fb55e17e6273d1289148e583ec96 metadata.db
992137d1bae13151b538b451a270b5f71399a7e7543932ebde08609e15c93ea3 volume_nginx
当删除容器时,宿主机上的挂载目录是不会删除的,使用docker rm -v可以删除容器的同时删除宿主机上的挂载目录
删除centos数据卷容器之后,挂载目录/data1和/data2也一并删除了
[root@docker _data]# docker rm -f -v 033859a7258c
033859a7258c
[root@docker /]# ls
bin boot cloud cp.txt dev etc home KY03 lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
使用docker run --rm也可以当容器运行停止时会自动删除容器以及容器所挂载的volume
二、端口映射
在启动容器时,如果不配置宿主机器与虚拟机的端口映射,外部程序是无法访问虚拟机的,因为没有端口。
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx new c7fa9b81a516 40 hours ago 480MB
sshd new fedd607e01f1 42 hours ago 481MB
centos 7-1 7a6937221a35 2 days ago 203MB
tomcat latest f796d3d2c195 7 days ago 647MB
nginx latest 7e4d58f0e5f3 12 days ago 133MB
busybox latest 6858809bf669 2 weeks ago 1.23MB
centos 7 7e6257c9f8d8 6 weeks ago 203MB
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
一般使用 docker run -p进行端口映射
-P:后面不指定端口默认会随机分配一个端口,这里是32768
[root@docker ~]# docker run -d -P nginx:latest
20626ad5528d17644de60eef6ddcb73fbb201d6a1e2c7e48902bd532ae06b997
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
20626ad5528d nginx:latest "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 0.0.0.0:32768->80/tcp festive_ritchie
将宿主机的32000端口映射到虚拟机里的80端口,nginx服务是80端口
[root@docker ~]# docker run -d -p 32000:80 nginx:latest
d4d357df69b82426f3f6db9e9e52a0a1170d98ce3f9c5b285deeafdcee35489e
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d4d357df69b8 nginx:latest "/docker-entrypoint.…" 2 seconds ago Up 1 second 0.0.0.0:32000->80/tcp kind_grothendieck
20626ad5528d nginx:latest "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:32768->80/tcp festive_ritchie
使用docker port查看端口映射情况,后面可以跟容器ID或者名字
[root@docker /]# docker port nginx
80/tcp -> 0.0.0.0:80
[root@docker /]# docker port nginx3
80/tcp -> 0.0.0.0:83
默认映射的是tcp端口,如果要映射udp端口的话可以这样写:
docker run -d -p 53000:53/udp 镜像名