Docker: docker container常用命令实战(2)-数据持久化

应用服务是在容器中运行的,容器随时会被删除,如果是个mysql容器呢?数据存储在容器里,容器删除了,数据也没了,那就是个噩梦。 所以一些数据是需要存储在容器之外的,可以是宿主机,可以是网络存储位置上,目的是为了数据能保留下来,这就是数据的持久化。 

接下来,我们了解一下,如何将容器中需要持久化的数据,持久化到容器之外的位置。

Docker提供三种方式将数据从宿主机挂载到容器中:

• volumes:Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)。保存数据的最佳方式。

• bind mounts:将宿主机上的任意位置的文件或者目录挂载到容器中。

• tmpfs:挂载存储在主机系统的内存中,而不会写入主机的文件系统。如果不希望将数据持久存储在任何位置,可以使用

tmpfs,同时避免写入容器可写层提高性能。

下面的实验,我们做前2种方式:

#列出volume
[root@192 /]# docker volume ls
DRIVER              VOLUME NAME
#查看docker volume 帮助
[root@192 /]# docker volume --help

Usage:    docker volume COMMAND

Manage volumes

Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove all unused local volumes
  rm          Remove one or more volumes

Run 'docker volume COMMAND --help' for more information on a command.
# 先测试通过docker volume创建卷,并关联给容器使用。这个卷里保存容器的持久化数据
#新建一个卷,卷名=nginx-vol
[root@192 /]# docker volume create nginx-vol
nginx-vol
#列出volume,确认卷创建成功
[root@192 /]# docker volume ls
DRIVER              VOLUME NAME
local               nginx-vol
#查看卷详细信息
[root@192 /]# docker volume inspect nginx-vol
[
    {
        "CreatedAt": "2019-03-14T12:44:04+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/nginx-vol/_data",
        "Name": "nginx-vol",
        "Options": {},
        "Scope": "local"
    }
]
#进入nginx-vol卷文件存储目录
[root@192 /]# cd /var/lib/docker/volumes/nginx-vol/_data
#列出当前目录下文件
[root@192 _data]# ls
#列出当前存在的镜像文件
[root@192 _data]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              881bd08c0b08        9 days ago          109MB
busybox             latest              d8233ab899d4        3 weeks ago         1.2MB
centos              7                   1e1148e4cc2c        3 months ago        202MB
centos              latest              1e1148e4cc2c        3 months ago        202MB
java                8                   d23bdf5b1b1b        2 years ago         643MB
#列出最近的容器
[root@192 _data]# docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
5e67c2448806        nginx               "nginx -g 'daemon of…"   2 days ago          Up 3 hours          0.0.0.0:8800->80/tcp   trusting_banach
#停止指定容器
[root@192 _data]# docker container stop 5e67c2448806
5e67c2448806
[root@192 _data]# docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
#启动指定容器
[root@192 _data]# docker container start 5e67c2448806
5e67c2448806
#停止指定容器
[root@192 _data]# docker container stop 5e67c2448806
5e67c2448806
#启动一个容器,--mount src=nginx-vol,dst=/usr/share/nginx/html 将宿主机的nginx-vol卷,挂在到容器中的 /usr/share/nginx/html目录
# docker volume特点,volume和容器中数据实时同步了,不论在那端修改了数据,会实时同步,2边数据会保持一致。 删除volume时,如果有关联的容器存在(停止和运行状态),那么无法删除volume. 只有移除容器,volume才能被删除
[root@192 _data]# docker container run -d  --mount src=nginx-vol,dst=/usr/share/nginx/html -p 8800:80 nginx
6886984c9b2df1dec674abb72a659e02d6a98afbb11dccdddb926571b08085b2
[root@192 _data]# docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
6886984c9b2d        nginx               "nginx -g 'daemon of…"   31 seconds ago      Up 30 seconds       0.0.0.0:8800->80/tcp   eloquent_jackson
#进入nginx-vol卷
[root@192 _data]# cd /var/lib/docker/volumes/nginx-vol/_data
#查看是否存在文件,发现2个文件
[root@192 _data]# ls
50x.html  index.html
#进入容器
[root@192 _data]# docker container exec -it 6886984c9b2d bash
#进入dst目录
root@6886984c9b2d:/# cd /usr/share/nginx/html/
#列出文件,发现源和目标文件时一致的,测试在源和目标修改index.html,都会生效
root@6886984c9b2d:/usr/share/nginx/html# ls
50x.html  index.html
root@6886984c9b2d:/usr/share/nginx/html# cat index.html 
<h1>Welcome to volume test!</h1>
root@6886984c9b2d:/usr/share/nginx/html# echo 'This modify is in container'>index.html 
root@6886984c9b2d:/usr/share/nginx/html# cat index.html 
This modify is in container
root@6886984c9b2d:/usr/share/nginx/html# exit
exit
[root@192 _data]# cd /
#下面测试在容器运行中删除卷,删除卷失败。
[root@192 /]# docker volume rm nginx-vol
Error response from daemon: remove nginx-vol: volume is in use - [6886984c9b2df1dec674abb72a659e02d6a98afbb11dccdddb926571b08085b2]
#下面测试在容器状态时停止时删除卷,删除卷失败。
[root@192 /]# docker container stop 6886984c9b2df1dec674abb72a659e02d6a98afbb11dccdddb926571b08085b2
6886984c9b2df1dec674abb72a659e02d6a98afbb11dccdddb926571b08085b2
[root@192 /]# docker volume rm nginx-vol
Error response from daemon: remove nginx-vol: volume is in use - [6886984c9b2df1dec674abb72a659e02d6a98afbb11dccdddb926571b08085b2]
[root@192 /]# docker container ps -qa
6886984c9b2d
5e67c2448806
[root@192 /]# docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
#下面测试,删除容器后,删除卷,卷删除成功
[root@192 /]# docker container rm 6886984c9b2df1dec674abb72a659e02d6a98afbb11dccdddb926571b08085b2
6886984c9b2df1dec674abb72a659e02d6a98afbb11dccdddb926571b08085b2
[root@192 /]# docker volume rm nginx-vol
nginx-vol
[root@192 /]# docker volume ls
DRIVER              VOLUME NAME
# 下面测试数据持久化的第2种方式:bind mount ,可以将宿主机的任意文件位置挂载到容器的任意位置,容器中的路径下如果存在文件,这些文件将会被隐藏
# 新建目录 wwwroot
[root@192 /]# mkdir wwwroot
# 启动一个容器,--mount type=bind,src=$PWD/wwwroot,dst=/usr/share/nginx/html, 将宿主机src目录,挂在到容器/usr/share/nginx/html的目录
[root@192 /]# docker container run -d -p 8900:80 --mount type=bind,src=$PWD/wwwroot,dst=/usr/share/nginx/html nginx
dbc6252103716d58aa7897919e98025e51972149246b9f078304a3e26ce8d6a0
# 查看宿主机wwwroot目录下,不存在文件
[root@192 /]# ls wwwroot/
[root@192 /]# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  wwwroot
# 查看容器/usr/share/nginx/html的目录下,不存在文件; 
[root@192 /]# docker container exec -it dbc6252103716d58aa7897919e98025e51972149246b9f078304a3e26ce8d6a0 bash
root@dbc625210371:/# cd /usr/share/nginx/html/
root@dbc625210371:/usr/share/nginx/html# ls
root@dbc625210371:/usr/share/nginx/html# exit
exit
# 在宿主机wwwroot目录下,创建文件
[root@192 /]# cd wwwroot/
[root@192 wwwroot]# ls
[root@192 wwwroot]# touch index.html
[root@192 wwwroot]# vi index.html 
# 进入容器,查看是否存在文件,观察到也存在文件了
[root@192 wwwroot]# docker container exec -it dbc6252103716d58aa7897919e98025e51972149246b9f078304a3e26ce8d6a0 bash
root@dbc625210371:/# cd /usr/share/nginx/html/
root@dbc625210371:/usr/share/nginx/html# ls
index.html
# 在容器中创建文件
root@dbc625210371:/usr/share/nginx/html# touch a.out
root@dbc625210371:/usr/share/nginx/html# exit
exit
# 在宿主机观察到,在容器中创建的文件存在,说明在2边的操作,会互相同步。
[root@192 wwwroot]# ls
a.out  index.html

总结:

Volume特点:

多个运行容器之间共享数据

• 当容器停止或被移除时,该卷依然存在。

• 多个容器可以同时挂载相同的卷。

• 当明确删除卷时,卷才会被删除。

• 将容器的数据存储在远程主机或其他存储上

• 将数据从一台Docker主机迁移到另一台时,先停止容器,然后备份卷的目录(/var/lib/docker/volumes/)

Bind Mounts特点:

• 从主机共享配置文件到容器。默认情况下,挂载主机/etc/resolv.conf到每个容器,提供DNS解析。

在Docker主机上的开发环境和容器之间共享源代码。例如,可以将Maven target目录挂载到容器中,每次在Docker主机

上构建Maven项目时,容器都可以访问构建的项目包。

作者: 梅梅~

出处: https://www.cnblogs.com/keeptesting

关于作者:专注软件测试,测试运维相关工作,请多多赐教!

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接 欢迎博客园朋友加微信联系。 微信:yangguangkg20140901 暗号:博客园.

原文地址:https://www.cnblogs.com/keeptesting/p/10530102.html