容器学习Day14-Docker容器存储

系列文章目录

容器学习Day01-初识容器

容器学习Day02-VMware Workstation安装Ubuntu

容器学习Day03-Ubuntu常用命令(一)

容器学习Day04-Ubuntu常用命令(二)

容器学习Day05-Ubuntu常用命令(三)

容器学习Day06-Ubuntu常用命令(四)

容器学习Day07-Docker基础(一)

容器学习Day08-Docker基础(二)

容器学习Day09-理解容器镜像

容器学习Day10-搭建私有镜像仓库

容器学习Day11-docker commit构建容器镜像

容器学习Day12-使用Dockerfile构建容器镜像

容器学习Day13-Docker容器网络

容器学习Day14-Docker容器存储

容器学习Day15-Docker容器底层实现技术

容器学习Day16-Docker Compose容器编排


文章目录

前言

一、Docker数据持久化存储

1、volumes

2、bind mounts

二、数据卷容器

总结

前言

        默认情况下,写入到容器中的数据会随着容器的删除而消失,但有的情况下,数据需要被保存下来,今天主要来了解一下 Docker 中的数据如何持久化存储。


一、Docker数据持久化存储

      默认情况下,在容器内创建的所有文件都存储在可写容器层上,这意味着:

  • 当该容器不再存在时,数据不会持久存在,并且如果另一个进程需要数据,很难从容器中取出数据。
  • 容器的可写层与运行容器的主机紧密耦合,不能轻易的将数据移动到其他地方。
  • 写入容器的可写层需要存储驱动程序来管理文件系统,存储驱动程序使用 Linux 内核提供联合文件系统,与使用直接写入主机文件系统的数据卷相比,性能比较低。

       Docker 有两个选项供容器将文件存储在主机上,以便在容器停止后文件仍然存在,volumes和 bind mounts。

1、volumes

       volumes 的数据存储在宿主机中,Linux 系统中默认存储位置是 /var/lib/docker/volumes/,数据由 Docker 管理,其他软件是不能修改的。

###创建一个volume。
root@docker:~# docker volume create mydata
mydata

###查看创建的volume。
root@docker:~# docker volume ls
DRIVER    VOLUME NAME
local     mydata

###查看创建的volume信息。
root@docker:~# docker inspect mydata 
[
    {
        "CreatedAt": "2023-05-13T04:11:12Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/docker/data/volumes/mydata/_data",
        "Name": "mydata",
        "Options": null,
        "Scope": "local"
    }
]

###启动一个httpd容器,并使用创建的数据卷mydata,将mydata卷挂载到httpd主目录。
root@docker:/# docker run -d -p 80:80 -v mydata:/usr/local/apache2/htdocs httpd
fda6770f9795265afbd4f63b00c356bda7d71fa9e44aa8e4dbb410613dc74acd
root@docker:/# docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED          STATUS          PORTS                               NAMES
fda6770f9795   httpd     "httpd-foreground"   11 minutes ago   Up 11 minutes   0.0.0.0:80->80/tcp, :::80->80/tcp   compassionate_khayyam

###查看容器卷挂载的信息。
root@docker:/# docker inspect fda6770f9795 |grep -A 8 Mounts 
        "Mounts": [
            {
                "Type": "volume",
                "Name": "mydata",
                "Source": "/docker/data/volumes/mydata/_data",
                "Destination": "/usr/local/apache2/htdocs",
                "Driver": "local",
                "Mode": "z",
                "RW": true,

###查看数据卷目录和容器中挂载目录中的文件内容一样,容器中的数据被拷贝到了数据卷中。
root@docker:/# ls -l /docker/data/volumes/mydata/_data
total 4
-rw-r--r-- 1 504 staff 45 Jun 11  2007 index.html
root@docker:/# cat /docker/data/volumes/mydata/_data/index.html 
<html><body><h1>It works!</h1></body></html>

root@docker:/# docker exec -it fda6770f9795 bash
root@fda6770f9795:/usr/local/apache2# ls -l /usr/local/apache2/htdocs
total 4
-rw-r--r-- 1 504 staff 45 Jun 11  2007 index.html
root@fda6770f9795:/usr/local/apache2# cat /usr/local/apache2/htdocs/index.html 
<html><body><h1>It works!</h1></body></html>

###修改宿主机数据卷中的内容,容器中的内容也会更新。
root@docker:/# echo "HelloWord!" > /docker/data/volumes/mydata/_data/index.html

root@fda6770f9795:/usr/local/apache2# cat /usr/local/apache2/htdocs/index.html 
HelloWord!

###宿主机上测试访问httpd的服务。
root@docker:/# curl http://192.168.1.128:80
HelloWord!

###停止并删除容器后,去数据卷查看文件依然存储。
root@docker:/# docker stop fda6770f9795
fda6770f9795
root@docker:/# docker rm fda6770f9795
fda6770f9795
root@docker:/# cat /docker/data/volumes/mydata/_data/index.html
HelloWord!

       数据卷可以像上边这样,先创建,然后挂载给容器使用,也可以启动容器时使用 -v 参数,只指定容器中的挂载目录,会自动创建一个数据卷。

###运行一个容器,并指定容器中的挂载目录。
root@docker:/# docker run -d -p 80:80 -v /usr/local/apache2/htdocs httpd
f14bc01e3fd08f1f69eeb6c04ab78b5424dc14d20f854aefe185de9b7857b4b8
root@docker:/# docker ps 
CONTAINER ID   IMAGE     COMMAND              CREATED          STATUS          PORTS                               NAMES
f14bc01e3fd0   httpd     "httpd-foreground"   11 seconds ago   Up 10 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   mystifying_goldwasser

###查看数据卷,发现自动创建了一个数据卷。
root@docker:/# docker volume ls
DRIVER    VOLUME NAME
local     a98edacc177ef49c81e72c60fbef13c81b55ebedd2d1cc52ab57ff1d0fcb6126
local     mydata

###查看数据卷信息。
root@docker:/# docker inspect a98edacc177ef49c81e72c60fbef13c81b55ebedd2d1cc52ab57ff1d0fcb6126
[
    {
        "CreatedAt": "2023-05-13T16:05:15Z",
        "Driver": "local",
        "Labels": {
            "com.docker.volume.anonymous": ""
        },
        "Mountpoint": "/docker/data/volumes/a98edacc177ef49c81e72c60fbef13c81b55ebedd2d1cc52ab57ff1d0fcb6126/_data",
        "Name": "a98edacc177ef49c81e72c60fbef13c81b55ebedd2d1cc52ab57ff1d0fcb6126",
        "Options": null,
        "Scope": "local"
    }
]

###查看容器挂载信息。
root@docker:/# docker inspect f14bc01e3fd0 |grep -A 8 Mounts
        "Mounts": [
            {
                "Type": "volume",
                "Name": "a98edacc177ef49c81e72c60fbef13c81b55ebedd2d1cc52ab57ff1d0fcb6126",
                "Source": "/docker/data/volumes/a98edacc177ef49c81e72c60fbef13c81b55ebedd2d1cc52ab57ff1d0fcb6126/_data",
                "Destination": "/usr/local/apache2/htdocs",
                "Driver": "local",
                "Mode": "",
                "RW": true,

       数据卷不再使用了可以将其删除。

###删除之前创建的mydata数据卷。
root@docker:/# docker volume ls
DRIVER    VOLUME NAME
local     a98edacc177ef49c81e72c60fbef13c81b55ebedd2d1cc52ab57ff1d0fcb6126
local     mydata
root@docker:/# docker volume rm mydata
mydata
root@docker:/# docker volume ls
DRIVER    VOLUME NAME
local     a98edacc177ef49c81e72c60fbef13c81b55ebedd2d1cc52ab57ff1d0fcb6126

2、bind mounts

       bind mounts 是将宿主机上已有的目录或文件 mount 到容器中,文件或目录由其在宿主机上的绝对路径引用。bind mounts 性能非常好,但是它依赖于主机的文件系统具有特定的目录结构。

  • 挂载目录
###停止并删除前面创建的容器。
root@docker:/# docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED        STATUS        PORTS                               NAMES
f14bc01e3fd0   httpd     "httpd-foreground"   10 hours ago   Up 10 hours   0.0.0.0:80->80/tcp, :::80->80/tcp   mystifying_goldwasser
root@docker:/# docker stop f14b
f14b
root@docker:/# docker rm f14b
f14b

###创建一个目录,启动容器,将目录挂载到容器中。
root@docker:/# mkdir /docker/htdocs
root@docker:/# docker run -d -p 80:80 -v /docker/htdocs:/usr/local/apache2/htdocs httpd
02d708764fe163e885e3c8985862f9bfbda7d9265e0d0dcb7a1146ac805af822
root@docker:/# docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED         STATUS         PORTS                               NAMES
02d708764fe1   httpd     "httpd-foreground"   6 seconds ago   Up 2 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   wizardly_bhaskara

###访问测试页发现返回的是空的内容,因为新建的目录里没有文件,创建文件后,可以访问。
root@docker:/# curl http://localhost:80
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
 <head>
  <title>Index of /</title>
 </head>
 <body>
<h1>Index of /</h1>
<ul></ul>
</body></html>
root@docker:/# ls -l /docker/htdocs/
total 0
root@docker:/# echo hello > /docker/htdocs/index.html
root@docker:/# curl http://localhost:80
hello

###停止删除容器后,不会影响宿主机上的文件。
root@docker:/# docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED          STATUS          PORTS                               NAMES
02d708764fe1   httpd     "httpd-foreground"   24 minutes ago   Up 24 minutes   0.0.0.0:80->80/tcp, :::80->80/tcp   wizardly_bhaskara
root@docker:/# docker stop 02d7
02d7
root@docker:/# docker rm 02d7
02d7
root@docker:/# ls -l /docker/htdocs/index.html 
-rw-r--r-- 1 root root 6 May 14 10:47 /docker/htdocs/index.html
  • 挂载文件

       官方的 Docker 镜像往往使用的是 UTC 时区,为了和宿主机保持时区上的一致,比较常用的是把宿主机上的 /etc/localtime 挂载到容器中。

###查看宿主机时区时间。
root@docker:/# date
Sun May 14 11:33:41 CST 2023

###先运行一个httpd容器,查看默认时区时间,与宿主机相差8个小时。
root@docker:/# docker run --rm -d -p 80:80 httpd
68a5119ee10fb4a30f6e7df8d9e5e5279717ae5f6631bc2e4cdebf60afe68b84
root@docker:/# docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED          STATUS          PORTS                               NAMES
68a5119ee10f   httpd     "httpd-foreground"   32 seconds ago   Up 29 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   angry_carson
root@docker:/# docker exec -it 68a5 bash 
root@68a5119ee10f:/usr/local/apache2# date
Sun May 14 03:35:59 UTC 2023

###将容器停止,因为运行时带了--rm参数,停止后,会自动删除容器。
root@docker:/# docker stop 68a5
68a5

###再次运行一个容器,将宿主机的localtime挂载到容器中,再查看时区时间,已于宿主机一致。
###我们不希望容器对这个文件进行修改,ro参数代表容器对挂载的文件只有只读权限。

root@docker:/# docker run --rm -d -p 80:80 -v /etc/localtime:/etc/localtime:ro httpd
bfdb7ad054c4322e5c908dfc212fc59233d794723a2bdcf10c47e492aad5b932

root@docker:/# date
Sun May 14 11:44:06 CST 2023
root@docker:/# docker exec -it bfdb bash 
root@bfdb7ad054c4:/usr/local/apache2# date
Sun May 14 11:44:14 CST 2023

二、数据卷容器

       数据卷容器也是一个容器,专门用来提供数据卷供其他容器挂载。如果用户需要在多个容器之间共享一些持续更新的数据,则最简单的方式是使用数据卷容器。

###创建一个数据卷容器myapp。
root@docker:/# docker run -d -v /docker/data/htdocs:/usr/local/apache2/htdocs -p 80:80 --name myapp httpd
634a325af9bf3e07be4e33fdba16b687fccad5e519a2da78dacc63b5e739dca8
root@docker:/# docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED         STATUS         PORTS                               NAMES
634a325af9bf   httpd     "httpd-foreground"   4 seconds ago   Up 2 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   myapp

###查看容器myapp挂载信息。
root@docker:/# docker inspect myapp |grep -A 8 Mounts
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/docker/data/htdocs",
                "Destination": "/usr/local/apache2/htdocs",
                "Mode": "",
                "RW": true,
                "Propagation": "rslave"
            }

###再创建一个容器myapp1,使用--volumes-from引用myapp中的卷。
root@docker:/# docker run -d -p 81:80 --name myapp1 --volumes-from myapp httpd
6882ff39c92be837dfce55414332ff7c5cdc1d278977641a24cdfd486391843e
root@docker:/# docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED              STATUS              PORTS                               NAMES
6882ff39c92b   httpd     "httpd-foreground"   4 seconds ago        Up 2 seconds        0.0.0.0:81->80/tcp, :::81->80/tcp   myapp1
634a325af9bf   httpd     "httpd-foreground"   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp, :::80->80/tcp   myapp

###查看myapp1挂载信息,和myapp一模一样。
root@docker:/# docker inspect myapp1 |grep -A 8 Mounts
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/docker/data/htdocs",
                "Destination": "/usr/local/apache2/htdocs",
                "Mode": "",
                "RW": true,
                "Propagation": "rslave"
            }

###修改/docker/data/hodocs中的index.html文件,访问myapp和myapp1测试。
root@docker:/# echo HelloWord > /docker/data/htdocs/index.html
root@docker:/# curl http://localhost:80
HelloWord
root@docker:/# curl http://localhost:81
HelloWord

###将myapp删除后,myapp1仍然可以使用。
root@docker:/# docker stop myapp
myapp
root@docker:/# docker rm myapp
myapp
root@docker:/# curl http://localhost:81
HelloWord

总结

       以上就是今天学习了解的内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AtobeKegio

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值