1. Docker持久化数据的方案

  • 基于本地文件系统的Volume。可以在执行Docker create或Docker run时,通过-v参数将主机的目录作为容器的数据卷。这部分功能便是基于本地文件系系统的volume管理。
  • 基于plugin的Volume,支持第三方的存储方案,比如NAS,aws。

2. Volume的类型

  • 受管理的data Volume,由docker后台自动创建。
  • 绑定挂载的Volune,具体挂载位置可以由用户指定。

3. Data Volume

创建mysql容器

  1. [vagrant@docker-host ~]$ sudo docker run -d --name mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql

查看docker volume

  1. [vagrant@docker-host ~]$ docker volume ls
  2. DRIVER VOLUME NAME
  3. local f1c4118d0960cb957470a149af3c4f46fcb1f501ed7e675c0babb6dd364b5eee
  4. [vagrant@docker-host ~]$ docker volume inspect f1c4118d0960cb957470a149af3c4f46fcb1f501ed7e675c0babb6dd364b5eee
  5. [
  6. {
  7. "CreatedAt": "2019-11-16T02:41:04Z",
  8. "Driver": "local",
  9. "Labels": null,
  10. "Mountpoint": "/var/lib/docker/volumes/f1c4118d0960cb957470a149af3c4f46fcb1f501ed7e675c0babb6dd364b5eee/_data",
  11. "Name": "f1c4118d0960cb957470a149af3c4f46fcb1f501ed7e675c0babb6dd364b5eee",
  12. "Options": null,
  13. "Scope": "local"
  14. }
  15. ]

会发现多出一个VOLUME,这个就是mysql容器的外部数据卷。 mysql容器外部数据卷目录: /var/lib/docker/volumes/f1c4118d0960cb957470a149af3c4f46fcb1f501ed7e675c0babb6dd364b5eee/_data

删除mysql容器

  1. [vagrant@docker-host ~]$ docker stop mysql
  2. mysql
  3. [vagrant@docker-host ~]$ docker rm mysql
  4. mysql

再次查看volume

  1. [vagrant@docker-host ~]$ docker volume ls
  2. DRIVER VOLUME NAME
  3. local f1c4118d0960cb957470a149af3c4f46fcb1f501ed7e675c0babb6dd364b5eee

可以发现容器删除后,volume还是存在的。这样确保了数据丢失的问题。

删除volume

  1. [vagrant@docker-host ~]$ docker volume rm f1c4118d0960cb957470a149af3c4f46fcb1f501ed7e675c0babb6dd364b5eee
  2. f1c4118d0960cb957470a149af3c4f46fcb1f501ed7e675c0babb6dd364b5eee

创建容器并且指定volume名称与容器内部存放数据的路径

  1. [vagrant@docker-host ~]$ sudo docker run -d -v mysql:/var/lib/mysql --name mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
  2. f57c6983d307a66db5597a2720236321b95d3744455b07770784499cc11f6c8c
  3. [vagrant@docker-host ~]$ docker volume ls
  4. DRIVER VOLUME NAME
  5. local mysql
  6. [vagrant@docker-host ~]$ docker volume inspect mysql
  7. [
  8. {
  9. "CreatedAt": "2019-11-16T02:53:14Z",
  10. "Driver": "local",
  11. "Labels": null,
  12. "Mountpoint": "/var/lib/docker/volumes/mysql/_data",
  13. "Name": "mysql",
  14. "Options": null,
  15. "Scope": "local"
  16. }
  17. ]

volume的复用

  1. [vagrant@docker-host ~]$ docker stop mysql
  2. mysql
  3. [vagrant@docker-host ~]$ docker rm mysql
  4. mysql
  5. [vagrant@docker-host ~]$ sudo docker run -d -v mysql:/var/lib/mysql --name mysql2 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
  6. 9334e575f98766a56b37d84a800c2673137289d3cc49e7e74c200d9b9173b167
  7. [vagrant@docker-host ~]$ docker volume ls
  8. DRIVER VOLUME NAME
  9. local mysql

删除mysql容器 创建mysql2容器指定使用mysql容器的volume 实践步骤:

  1. 进入mysql容器的mysql数据库中添加一个数据库
  2. 退出mysql容器并删除mysql容器
  3. 创建mysql2容器并指定volume为mysql的volume
  4. 进入mysql2容器的mysql数据库中查看 1 操作的数据库是否存在

4. Bind Mouting

将本地文件目录与容器文件目录进行绑定/映射,本地文件目录下文件修改 容器文件目录下文件也会修改,容器文件目录下文件修改 本地文件目录下文件也会修改。

Dockerfile创建镜像

dockerfile文件
  1. # this same shows how we can extend/change an existing official image from Docker Hub
  2. FROM nginx:latest
  3. # highly recommend you always pin versions for anything beyond dev/learn
  4. WORKDIR /usr/share/nginx/html
  5. # change working directory to root of nginx webhost
  6. # using WORKDIR is prefered to using 'RUN cd /some/path'
  7. COPY index.html index.html
  8. # I don't have to specify EXPOSE or CMD because they're in my FROM

index.html文件
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <title>hello</title>
  6. </head>
  7. <body>
  8. <h1>Hello Docker! </h1>
  9. </body>
  10. </html>

创建镜像
  1. [vagrant@docker-host docker-nginx]$ docker build -t wenxudong/nginx .
  2. Sending build context to Docker daemon 3.072kB
  3. Step 1/3 : FROM nginx:latest
  4. latest: Pulling from library/nginx
  5. 8d691f585fa8: Pull complete
  6. 5b07f4e08ad0: Pull complete
  7. abc291867bca: Pull complete
  8. Digest: sha256:922c815aa4df050d4df476e92daed4231f466acc8ee90e0e774951b0fd7195a4
  9. Status: Downloaded newer image for nginx:latest
  10. ---> 540a289bab6c
  11. Step 2/3 : WORKDIR /usr/share/nginx/html
  12. ---> Running in 602a1a4c4dec
  13. Removing intermediate container 602a1a4c4dec
  14. ---> 745743e7e234
  15. Step 3/3 : COPY index.html index.html
  16. ---> c8191f8fedba
  17. Successfully built c8191f8fedba
  18. Successfully tagged wenxudong/nginx:latest
  19. [vagrant@docker-host docker-nginx]$ docker images
  20. REPOSITORY TAG IMAGE ID CREATED SIZE
  21. wenxudong/nginx latest c8191f8fedba About a minute ago 126MB
  22. nginx latest 540a289bab6c 3 weeks ago 126MB

创建容器并且映射文件

  1. # 查看当前目录下的文件
  2. [vagrant@docker-host docker-nginx]$ ls
  3. Dockerfile index.html
  4. # 创建目录
  5. [vagrant@docker-host docker-nginx]$ docker run -d -p 80:80 -v $(pwd):/usr/share/nginx/html --name web wenxudong/nginx
  6. 35eb4452adcea5e6932838a69d840efe7ed0fe065535f4d18e98ed47074821e5

-v $(pwd):/usr/share/nginx/html将当前目录映射到web容器的/usr/share/nginx/html目录

验证Bind Mouting

  1. # 进入容器
  2. [vagrant@docker-host docker-nginx]$ docker exec -it web /bin/bash
  3. root@35eb4452adce:/usr/share/nginx/html# cd /usr/share/nginx/html
  4. root@35eb4452adce:/usr/share/nginx/html# ls
  5. Dockerfile index.html
  6. root@35eb4452adce:/usr/share/nginx/html# touch test.txt
  7. root@35eb4452adce:/usr/share/nginx/html# ls
  8. Dockerfile index.html test.txt
  9. # 退出容器
  10. root@35eb4452adce:/usr/share/nginx/html# exit
  11. exit
  12. # 再次查看当前目录下的文件
  13. [vagrant@docker-host docker-nginx]$ ls
  14. Dockerfile index.html test.txt
  15. [vagrant@docker-host docker-nginx]$ touch test2.txt
  16. # 进入容器
  17. [vagrant@docker-host docker-nginx]$ docker exec -it web /bin/bash
  18. root@35eb4452adce:/usr/share/nginx/html# ls
  19. Dockerfile index.html test.txt test2.txt