2019-08-18 Docker管理应用程序数据

1. 将数据从宿主机挂载到容器中的三种方式

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

  • volumes:Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)。保存数据的最佳方式。
  • bind mounts:将宿主机上的任意位置的文件或者目录挂载到容器中。
  • tmpfs:挂载存储在主机系统的内存中,而不会写入主机的文件系统。如果不希望将数据持久存储在任何位置,可以使用 tmpfs,同时避免写入容器可写层提高性能。
Docker将数据从宿主机挂载到容器中的三种方式

2. Volume

管理卷:

docker volume create nginx-vol
docker volume ls
docker volume inspect nginx-vol
用卷创建一个容器:
docker run -d --name=nginx-test --mount src=nginx-vol,dst=/usr/share/nginx/html nginx
docker run -d --name=nginx-test -v nginx-vol:/usr/share/nginx/html nginx
清理:
docker stop nginx-test
docker rm nginx-test
docker volume rm nginx-vol

注意

  1. 如果没有指定卷,自动创建
  2. 建议使用--mount,更通用
[root@localhost ~]# docker volume create nginx_vol
nginx_vol
[root@localhost ~]# docker volume ls
DRIVER              VOLUME NAME
local               nginx_vol
[root@localhost ~]# docker volume inspect nginx_vol
[
    {
        "CreatedAt": "2019-08-18T17:22:46+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/nginx_vol/_data",
        "Name": "nginx_vol",
        "Options": {},
        "Scope": "local"
    }
]
[root@localhost ~]# ls /var/lib/docker/volumes/nginx_vol/_data/    ---数据卷数据存放位置

安装nginx,与容器共享网页文件目录:
[root@localhost ~]# rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm    ---设置nginx的yum源
[root@localhost ~]# yum install -y nginx    ---安装nginx
[root@localhost ~]# systemctl start nginx    ---启动nginx
[root@localhost html]# docker rm -f $(docker ps -a | awk '{print $1}')    ---先删除前面创建的容器
b75a5892d442
2645100be04d
0dab09030fd2
23688554bc1f
d7123e29b0be
2dd1300152d5
c8633362cbe4
4dc7b59c8eef
44fddd40d047
4404f627f050
1feb5ca6ca6c
Error: No such container: CONTAINER
[root@localhost html]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@localhost html]# vi /usr/lib/sysctl.d/00-system.conf
net.ipv4.ip_forward=1    ---添加如下行
:wq
[root@localhost html]# docker run -d --name nginx01 -p 88:80 --mount src=nginx_vol,dst=/usr/share/nginx/html nginx    
---创建容器nginx01,src指定卷名,dst指定挂载的html文件路径
2397a403199a0046102f63f4a07ecf9c821f1a12d71c5fbd00780b119bb151f5
[root@localhost ~]# ls /var/lib/docker/volumes/nginx_vol/_data/    ---挂载成功
50x.html  index.html
测试访问新创建的容器的网页
[root@localhost ~]# cd /var/lib/docker/volumes/nginx_vol/_data/
[root@localhost _data]# ls
50x.html  index.html
[root@localhost _data]# vi index.html    ---修改默认页面内容
<h1>Hello world!</h1>
:wq

[root@localhost _data]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
2397a403199a        nginx               "nginx -g 'daemon of…"   3 hours ago         Up 3 hours          0.0.0.0:88->80/tcp   nginx01
[root@localhost _data]# docker inspect 2397a403199a
---省略若干---
                    "IPAddress": "172.17.0.2",    ---找到容器对应的IP
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]
[root@localhost ~]# curl 172.17.0.2
<h1>Hello world!</h1>
修改后的内容

说明可以直接在外面修改容器中的数据,但是不建议这么做。

[root@localhost ~]# docker stop nginx01    ---把nginx01停止掉
nginx01
[root@localhost ~]# docker run -d --name nginx02 -p 88:80 --mount src=nginx_vol,dst=/usr/share/nginx/html nginx    ---重新创建一个新的容器,指定的目录跟nginx01一样
9902f8e84ec761ea7c98b734998c3072ea49afd96ed03e869f8bbd7b5fab052b
访问网页

nginx01停止掉了还是能正常访问网页,因为数据还是使用的原来的数据,端口还是原来的端口,就算原来的容器损坏了,只要再重新创建一个容器指定相同的内容即可。这就是volume的好处。

[root@localhost ~]# docker rm -f $(docker ps -a | awk '{print $1}')    ---删除所有容器
9902f8e84ec7
2397a403199a
Error: No such container: CONTAINER
[root@localhost ~]# ls /var/lib/docker/volumes/nginx_vol/_data/    ---数据还在
50x.html  index.html

[root@localhost ~]# docker volume rm nginx_vol    ---删除数据卷
nginx_vol
[root@localhost ~]# ls /var/lib/docker/volumes/nginx_vol/_data/    ---数据没了
ls: cannot access /var/lib/docker/volumes/nginx_vol/_data/: No such file or directory

小结:删除容器,数据卷的数据还在,只有删除数据卷,数据卷的数据才会被删除。

3. Bind Mounts

用卷创建一个容器:

docker run -d --name=nginx-test --mount type=bind,src=/app/wwwroot,dst=/usr/share/nginx/html nginx
docker run -d --namenginx-test -v /app/wwwroot:/usr/share/nginx/html nginx

验证绑定:

docker inspect nginx-test

清理:

docker stop nginx-test
docker rm nginx-test

注意

  1. 如果源文件/目录不存在,不会自动创建,会抛出一个错误。
  2. 如果挂载目标在容器中非空目录,则该目录现有内容将被隐藏,所以最好确保挂载目标目录为空目录。但是后续在容器中新增的数据会同步到宿主机对应的目录下。
[root@localhost ~]# docker run -d --name nginx01 -p 88:80 --mount type=bind,src=/mnt/,dst=/usr/share/nginx/html nginx
8e3ddc68630d8e1acf6382baf061a3e3c208b62a9b2570ba8ffaebd4dfeeff6d
[root@localhost ~]# docker ps -l
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
8e3ddc68630d        nginx               "nginx -g 'daemon of…"   11 seconds ago      Up 10 seconds       0.0.0.0:88->80/tcp   nginx01
[root@localhost ~]# ls /mnt/    ---目前没有数据
[root@localhost app]# docker exec -it nginx01 bash
root@8e3ddc68630d:/# cd /usr/share/nginx/html/
root@8e3ddc68630d:/usr/share/nginx/html# ls
root@8e3ddc68630d:/usr/share/nginx/html# echo "Hello world!" > index.html
root@8e3ddc68630d:/usr/share/nginx/html# exit
exit
[root@localhost app]# ls /mnt    ---同步到src目录下了
index.html

[root@localhost app]# docker run -d --name nginx02 -p 89:80 --mount type=bind,src=/etc,dst=/opt nginx
---把/etc目录挂载到/opt目录下
434e38fa613a33e6cbc9a4607edb25bb61d5c7abb75d22bf80bb9d59190caaa1
[root@localhost app]# docker exec -it nginx02 bash
root@434e38fa613a:/# ls /opt/
DIR_COLORS       centos-release-upstream  e2fsck.conf  hostname       locale.conf       nsswitch.conf.bak  python      security    sysctl.d
DIR_COLORS.256color  chkconfig.d          environment  hosts          localtime         openldap       rc.d        selinux     system-release
DIR_COLORS.lightbgcolor  containerd       ethertypes   hosts.allow    login.defs        opt        rc.local    services    system-release-cpe
GREP_COLORS      cron.d           exports      hosts.deny     logrotate.conf        os-release     rc0.d       sestatus.conf   systemd
GeoIP.conf       cron.daily       favicon.png  init.d         logrotate.d       pam.d          rc1.d       shadow      terminfo
GeoIP.conf.default   cron.deny        filesystems  inittab        lvm           passwd         rc2.d       shadow-     tmpfiles.d
NetworkManager       cron.hourly          firewalld    inputrc        machine-id        passwd-        rc3.d       shells      tuned
X11          cron.monthly         fstab        iproute2       magic         pkcs11         rc4.d       skel        udev
adjtime          cron.weekly          fuse.conf    issue          makedumpfile.conf.sample  pki        rc5.d       ssh         vconsole.conf
aliases          crontab          gcrypt       issue.net      man_db.conf       plymouth       rc6.d       ssl         virc
aliases.db       crypttab         gnupg        kdump.conf     mke2fs.conf       pm         redhat-release  statetab    vmware-tools
alternatives         csh.cshrc        groff        kernel         modprobe.d        polkit-1       resolv.conf     statetab.d      wpa_supplicant
anacrontab       csh.login        group        krb5.conf      modules-load.d        popt.d         rpc         subgid      xdg
asound.conf      dbus-1           group-       krb5.conf.d    motd          postfix        rpm         subuid      xinetd.d
audisp           default          grub.d       ld.so.cache    mtab          ppp        rsyslog.conf    sudo-ldap.conf  yum
audit            depmod.d         grub2.cfg    ld.so.conf     my.cnf            prelink.conf.d     rsyslog.d       sudo.conf       yum.conf
bash_completion.d    dhcp             gshadow      ld.so.conf.d   my.cnf.d          printcap       rwtab       sudoers     yum.repos.d
bashrc           docker           gshadow-     libaudit.conf  networks          profile        rwtab.d     sudoers.d
binfmt.d         dracut.conf          gss          libnl          nginx         profile.d      sasl2       sysconfig
centos-release       dracut.conf.d        host.conf    libuser.conf   nsswitch.conf     protocols      securetty       sysctl.conf

总结

Volume特点:
  • 多个运行容器之间共享数据
  • 当容器停止或被移除时,该卷仍然存在
  • 多个容器可以同时挂载相同的卷
  • 当明确删除卷时,卷才会被删除
  • 将容器的数据存储在远程主机或其他存储上
  • 将数据从一台Docker主机迁移到另一台时,先停止容器,然后备份卷的目录(/var/lib/docker/volumes/)
Bind Mounts特点:
  • 从主机共享配置文件到容器。默认情况下,挂载主机/etc/resolv.conf到每个容器,提供DNS解析
  • 在Docker主机上的开发环境和容器之间共享源代码。例如,可以将Maven target目录挂载到容器中,每次在Docker主机上构建Maven项目时,容器都可以访问构建的项目包
  • 当Docker主机的文件或目录结构保证与容器所需的绑定挂载一致时
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容