五.Docker容器数据卷
环境&工具:
阿里云轻量级服务器、CentOS 7系统、FinalShell(其他连接客户端也可以)
是什么
docker的理念将运行的环境打包形成容器运行,运行可以伴随容器,但是我们对数据的要求是希望持久化,容器之间可以共享数据,Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据作为容器的一部分保存下来,那么当容器被删除之后,数据也就没了,为了能够保存数据,在docker容器中使用卷。卷就是目录或者文件,存在于一个或者多个容器中,但是不属于联合文件系统,因此能够绕过Union File System提供一些用于持久化数据或共享数据的特点
能干嘛?
卷的设计目的就是数据的持久化,完全独立与容器的生命周期,因此Docker不会在容器删除时删除其挂载的数据卷。
特点:
- 数据卷可以在容器之间共享和重用数据。
- 卷的更改可以直接生效。
- 数据卷的更改不会包含在镜像的更新中。
- 数据卷的生命周期一直持续到没有容器使用它为止。
- 容器的持久化
- 容器间继承+共享数据
数据卷
容器内添加
1. 直接命令添加
docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
以nginx为例:在宿主机上创建一个文件夹 docker/nginx 并编辑一个html文件 内容输入:“Hello Docker!”
docker run -itd --name nginx -v /docker/nginx/:/usr/share/nginx/html/ -p 80:80 nginx
查看数据卷是否挂载成功:使用
docker inspect 容器ID
[root@iZbp13dilgxismwsd349o7Z ~]# docker inspect b8ee8ac896cb
[{"Id": "b8ee8ac896cb84945b9c52586032d392f4730ffa8850e58aa04e91de761ae5d8","Created": "2020-02-09T08:54:30.244932263Z","Path": "nginx","Args": ["-g","daemon off;"],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 7125,"ExitCode": 0,"Error": "","StartedAt": "2020-02-09T08:54:30.619136578Z","FinishedAt": "0001-01-01T00:00:00Z"},"Name": "/nginx","RestartCount": 0,"Driver": "overlay2","Platform": "linux","MountLabel": "","ProcessLabel": "","AppArmorProfile": "","ExecIDs": null,"HostConfig": {"Binds": ["/docker/nginx/:/usr/share/nginx/html/"],"ContainerIDFile": "","LogConfig": {"Type": "json-file","Config": {}},"NetworkMode": "default","PortBindings": {"80/tcp": [{"HostIp": "","HostPort": "80"}]},"RestartPolicy": {"Name": "no","MaximumRetryCount": 0},"AutoRemove": false,"VolumeDriver": "","VolumesFrom": null,"CapAdd": null,"CapDrop": null,"Capabilities": null,"Dns": [],"DnsOptions": [],"DnsSearch": [],"ExtraHosts": null,"GroupAdd": null,"IpcMode": "private","Cgroup": "","Links": null,"OomScoreAdj": 0,"PidMode": "","Privileged": false,"PublishAllPorts": false,"ReadonlyRootfs": false,"SecurityOpt": null,"UTSMode": "","UsernsMode": "","ShmSize": 67108864,"Runtime": "runc","ConsoleSize": [0,0],"Isolation": "","CpuShares": 0,"Memory": 0,"NanoCpus": 0,"CgroupParent": "","BlkioWeight": 0,"BlkioWeightDevice": [],"BlkioDeviceReadBps": null,"BlkioDeviceWriteBps": null,"BlkioDeviceReadIOps": null,"BlkioDeviceWriteIOps": null,"CpuPeriod": 0,"CpuQuota": 0,"CpuRealtimePeriod": 0,"CpuRealtimeRuntime": 0,"CpusetCpus": "","CpusetMems": "","Devices": [],"DeviceCgroupRules": null,"DeviceRequests": null,"KernelMemory": 0,"KernelMemoryTCP": 0,"MemoryReservation": 0,"MemorySwap": 0,"MemorySwappiness": null,"OomKillDisable": false,"PidsLimit": null,"Ulimits": null,"CpuCount": 0,"CpuPercent": 0,"IOMaximumIOps": 0,"IOMaximumBandwidth": 0,"MaskedPaths": ["/proc/asound","/proc/acpi","/proc/kcore","/proc/keys","/proc/latency_stats","/proc/timer_list","/proc/timer_stats","/proc/sched_debug","/proc/scsi","/sys/firmware"],"ReadonlyPaths": ["/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]}...此处忽略好多信息哦...}}
]
返回的json串有这么一串数据说明挂载成功。
- 容器和宿主机之间通信,容器关闭后在宿主机更改文件,容器再次启动数据仍然同步(左侧为容器,右侧为宿主机)
命令(带权限)
docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名(read only)
此时主机能对数据卷进行更改,但是容器不能对其更改,只允许读。
2.DockerFile添加
- 根目录下新建mydocker文件夹并进入。
- 在DockerFile中使用VOLUME指令给镜像添加一个或者多个数据卷
VOLUME["/dataVolumeContainer","dataVolumeContainer2","dataVolumeContainer3"]
- 出于可移植和分享的考虑,用-v命令这种方法不能够直在DockerFile中实现,由于宿主机目录是依赖于特定宿主机的,并不能保证所有的宿主机都存在这样的特定目录。
File构建
- 编写DockerFile文件
# 基础镜像使用centos
FROM java:8
MAINTAINER honghh <honghh1217@163.com>
VOLUME["/dataVolumeContainer","dataVolumeContainer2","dataVolumeContainer3"]
CMD /bin/bash
运行容器 可以看到已经创建两个数据卷,对应主机路径
- 主机对应的数据卷
Docker 挂载主机目录Docker出项cannot open directory.:Permission denied解决办法:在挂载目录后面多加一个–privileged=true参数即可
docker run -it -v /mydatavolume:/datavolumecontainer --privileged=true 镜像名
数据卷容器
命名的容器挂载数据卷,其他的容器通过挂载这个容器(父容器)实现数据共享,挂载数据卷的容器,称为数据卷容器.
容器间传递共享(–volumes-from)
- 子容器新建的会影响父容器
- 删除父容器子容器数据保留
容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止