本文最后更新于 392 天前,其中的信息可能已经过时,如有错误请发送邮件到 wuxianglongblog@163.com
| 存储卷就是将宿主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立绑定关系。 |
| 如下图所示,我们在容器创建测试文件,在宿主机查找时发现了2个文件路径。 |
| |
| 我们需要进入的是包含"merged"的路径哟~因为它才是真正存储容器的位置呢。 |
| 如下图所示,当我们删除容器时,那也意味着在宿主机存储的数也随之删除。 |
| [root@docker201.oldboyedu.com ~] |
| [root@docker201.oldboyedu.com ~]# docker run -it -d -p 80:80 nginx:1.20.1 |
| [root@docker201.oldboyedu.com /var/lib/docker/overlay2/c8f3eaf1cba887b7370d1dd86521989a76f5d642a76c3b790111b42b05d0212e/merged/usr/share/nginx/html] |
| [root@docker201.oldboyedu.com ~] |
| |
| 温馨提示: |
| 你知道为什么使用"docker logs"能在终端查看到日志吗? |
| 想知道原因就得进到容器内查看"/var/log/nginx"目录哟~ |
| 请思考除了使用上面的方式是否还有其它方式实现容器的代码更新呢? |
| |
| 温馨提示: |
| (1)使用"docker container cp"指令,直接将代码拷贝到指定容器的指定目录; |
| (2)使用存储卷; |
| [root@docker201.oldboyedu.com ~]# docker container run -d -p 8888:80 -v /oldboy/code:/usr/share/nginx/html nginx:1.20.1 |
| |
| [root@docker201.oldboyedu.com ~]# docker container run -d -p 9999:80 -v /oldboy/code:/usr/share/nginx/html nginx:1.20.1 |
| |
| 温馨提示: |
| 相比之前的方法,如果想要多个容器使用同一份数据,需要将同一份数据拷贝到多个不同的容器内部,而使用存储卷的方式,则无需拷贝多份数据啦。 |
| 如下图所示,根本无需重启容器,只需更改宿主机器的代码即可。 |
| 如下图所示,展示了多个容器使用同一个宿主机绝对路径的挂载原理。 |
| 如下图所示,当我们删除容器时,发现并不会一同删除挂载的存储卷。换句话说,就是不会删除宿主机的文件。 |
| [root@docker201.oldboyedu.com ~] |
| |
| 温馨提示: |
| 存储卷的默认存储路径位于"/var/lib/docker/volumes" |
| [root@docker201.oldboyedu.com ~]# docker container run -it -d -p 8888:80 -v oldboyedu:/usr/share/nginx/html nginx:1.20.1 |
| 如下图所示,当我们删除容器时,存储卷中的数据并不会丢失! |
| 数据卷的最强大的功能就是持久化数据,我们可以将多个容器挂载到同一个数据卷,从而实现了数据的共享。但有的容器并不支持挂载同一个目录,比如MySQL多实例的情况,如果指定的数据目录存在文件,则数据库会初始化失败哟。 |
| |
| 如下图所示,本篇案例演示的都是基于本地卷进行挂载,我们可以借助插件的方式帮咱们实现远程的数据挂载哟; |
| 如果存储卷下面没有数据,它会将容器指定目录下的文件持久化到存储卷的数据目录下。 |
| |
| 如果存储卷下面有数据,它会把存储卷的数据目录挂载到容器的指定目录。 |
| [root@docker201.oldboyedu.com ~]# ll /oldboy/code/ |
| 总用量 232 |
| -rw-r--r-- 1 root root 15329 8月 2 2014 2000.png |
| -rw-r--r-- 1 root root 51562 8月 2 2014 21.js |
| -rw-r--r-- 1 root root 254 8月 2 2014 icon.png |
| drwxr-xr-x 2 root root 102 8月 8 2014 img |
| -rw-r--r-- 1 root root 3059 6月 13 13:58 index.html |
| drwxr-xr-x 7 root root 171 6月 13 15:39 kod |
| -rw-r--r-- 1 root root 63008 8月 2 2014 sound1.mp3 |
| -rw-r--r-- 1 root root 91014 6月 13 13:25 xiaoniaofeifei.zip |
| [root@docker201.oldboyedu.com ~]# |
| [root@docker201.oldboyedu.com ~]# docker ps -a |
| CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
| [root@docker201.oldboyedu.com ~]# |
| [root@docker201.oldboyedu.com ~]# docker run -d -p 80:80 -v /oldboy/code:/usr/share/nginx/html nginx:1.20.1 |
| 220264c94b193fa8f4eab215d4561e0f7664fed9f4eb92ebba101c4a89be200d |
| [root@docker201.oldboyedu.com ~]# |
| [root@docker201.oldboyedu.com ~]# docker ps -a |
| CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
| 220264c94b19 nginx:1.20.1 "/docker-entrypoint.…" 4 seconds ago Up 4 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp priceless_euler |
| [root@docker201.oldboyedu.com ~]# |
| [root@docker201.oldboyedu.com ~] |
| CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
| 220264c94b19 nginx:1.20.1 "/docker-entrypoint.…" 4 seconds ago Up 4 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp priceless_euler |
| [root@docker201.oldboyedu.com ~] |
| [root@docker201.oldboyedu.com ~] |
| c4b4058ab33f7c40e04177c8b0a1872789780dd08f4d227eceda6eb7ffbc35f2 |
| [root@docker201.oldboyedu.com ~] |
| [root@docker201.oldboyedu.com ~] |
| CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
| c4b4058ab33f nginx:1.20.1 "/docker-entrypoint.…" 2 seconds ago Up 2 seconds 0.0.0.0:8888->80/tcp, :::8888->80/tcp great_grothendieck |
| 220264c94b19 nginx:1.20.1 "/docker-entrypoint.…" 16 seconds ago Up 16 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp priceless_euler |
| [root@docker201.oldboyedu.com ~] |
| 如下图所示,分别访问两个容器暴露的端口,返回的结果却是一样的。 |
| 如下图所示,我们可以直接指定nginx的日志目录分别挂载不同的存储卷上。 |
| |
| 温馨提示: |
| 静态的文件,可以共享。比如代码文件。 |
| 变化的文件,不能共享,需要单独保存。比如日志文件。 |
| 如下图所示,当我们删除容器时,数据并未丢失哟。 |
| |
| 温馨提示: |
| 下面的只是一个测试案例,不用在乎软连接,我只是为了测试一下效果。 |
| 只允许启动一个nginx容器,要求如下: |
| (1)访问8888端口,出现nginx默认的欢迎首页,要求使用存储卷使用; |
| (2)访问8889端口,出现"小鸟飞飞",要求使用存储卷使用; |
| (3)访问8890端口,出现容器主机名,IP地址; |
| |
| 温馨提示: |
| 实现效果如下图所示。 |

| (1)本地创建测试代码 |
| [root@docker201.oldboyedu.com ~] |
| 总用量 232 |
| -rw-r--r-- 1 root root 15329 8月 2 2014 2000.png |
| -rw-r--r-- 1 root root 51562 8月 2 2014 21.js |
| -rw-r--r-- 1 root root 254 8月 2 2014 icon.png |
| drwxr-xr-x 2 root root 102 8月 8 2014 img |
| -rw-r--r-- 1 root root 3059 6月 13 13:58 index.html |
| drwxr-xr-x 7 root root 171 6月 13 15:39 kod |
| -rw-r--r-- 1 root root 63008 8月 2 2014 sound1.mp3 |
| -rw-r--r-- 1 root root 91014 6月 13 13:25 xiaoniaofeifei.zip |
| [root@docker201.oldboyedu.com ~] |
| |
| (2)挂载本地目录到容器(但请不要覆盖nginx容器默认的代码文件,因为我们是要访问2个站点目录) |
| [root@docker201.oldboyedu.com ~] |
| |
| (3)进入容器生成配置文件(由于没有vi命令,因此我们可以借助echo或者cat生成nginx的配置文件) |
| [root@docker201.oldboyedu.com ~] |
| root@e634dfcc6248:/ |
| 2000.png 21.js icon.png img index.html kod sound1.mp3 xiaoniaofeifei.zip |
| root@e634dfcc6248:/ |
| root@e634dfcc6248:/etc/nginx/conf.d |
| server { |
| listen 9999; |
| server_name localhost; |
| location / { |
| root /oldboyedu/code; |
| index index.html index.htm; |
| } |
| } |
| root@e634dfcc6248:/etc/nginx/conf.d |
| |
| (4)对nginx的配置文件进行测试 |
| root@e634dfcc6248:/etc/nginx/conf.d |
| nginx: the configuration file /etc/nginx/nginx.conf syntax is ok |
| nginx: configuration file /etc/nginx/nginx.conf test is successful |
| root@e634dfcc6248:/etc/nginx/conf.d |
| |
| (5)重启nginx的配置文件 |
| [root@docker201.oldboyedu.com ~] |
| |
| 温馨提示: |
| 有小伙伴可能会质疑,为啥我不用nginx的reload指令呢?的确进入到容器进行reload是是一个可行的方案哟,但不是所有的服务都得reload,比如tomcat就不支持reload指令哟。 |
| 综上所诉,我们上面演示的方法更加通用。 |

| (1)本地创建测试代码 |
| [root@docker201.oldboyedu.com ~] |
| 总用量 232 |
| -rw-r--r-- 1 root root 15329 8月 2 2014 2000.png |
| -rw-r--r-- 1 root root 51562 8月 2 2014 21.js |
| -rw-r--r-- 1 root root 254 8月 2 2014 icon.png |
| drwxr-xr-x 2 root root 102 8月 8 2014 img |
| -rw-r--r-- 1 root root 3059 6月 13 13:58 index.html |
| drwxr-xr-x 7 root root 171 6月 13 15:39 kod |
| -rw-r--r-- 1 root root 63008 8月 2 2014 sound1.mp3 |
| -rw-r--r-- 1 root root 91014 6月 13 13:25 xiaoniaofeifei.zip |
| [root@docker201.oldboyedu.com ~] |
| |
| (2)挂载本地目录到容器(但请不要覆盖nginx容器默认的代码文件,因为我们是要访问2个站点目录) |
| [root@docker201.oldboyedu.com ~] |
| |
| (3)在宿主机上生成配置文件 |
| [root@docker201.oldboyedu.com ~] |
| [root@docker201.oldboyedu.com ~] |
| [root@docker201.oldboyedu.com ~] |
| server { |
| listen 9999; |
| server_name localhost; |
| location / { |
| root /oldboyedu/code; |
| index index.html index.htm; |
| } |
| } |
| [root@docker201.oldboyedu.com ~] |
| |
| (3)将宿主机的配置文件拷贝到其他电脑上 |
| [root@docker201.oldboyedu.com ~] |
| |
| (4)重启容器 |
| 如下图所示,重启容器后,可以使用浏览器访问到相应的数据哟~ |

| [root@docker201.oldboyedu.com ~]# docker run -d -p 8888:80 -p 9999:9999 -v /root/xiaoniao.conf:/etc/nginx/conf.d/xiaoniao.conf -v /oldboy/code:/oldboyedu/code nginx:1.20.1 |
| |
| 温馨提示: |
| 理解了前面的两种解法后,第三种解法自然就明白了。 |
| 数据卷挂在还支持权限配置,比如说rw代表读写,ro代表只读. |
| |
| 案例1: |
| docker container run -it -v /oldboyedu/data/:/oldboyedu-linux:ro -it -w /oldboyedu-linux --rm alpine |
| |
| 案例2: |
| docker container run -it -v /oldboyedu/data/:/oldboyedu-linux:rw -it -w /oldboyedu-linux --rm alpine |
| |
| 案例3:(挂在磁盘) |
| docker container run -it --device=/dev/sdc:/dev/oldboyedu-sdc --rm alpine |
| |
| 推荐阅读: |
| https://docs.docker.com/engine/reference/commandline/run/ |
| https://docs.docker.com/engine/reference/commandline/run/ |
| for i in `seq 0 2` ; do echo "- - -" > /sys/class/scsi_host/host$i/scan;done |
| |
| 温馨提示: |
| 使用"lsblk"命令查看磁盘即可. |