美文网首页
2019-08-18 Docker管理应用程序数据

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

作者: 阿丧小威 | 来源:发表于2019-08-19 23:14 被阅读0次

    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主机的文件或目录结构保证与容器所需的绑定挂载一致时

    相关文章

      网友评论

          本文标题:2019-08-18 Docker管理应用程序数据

          本文链接:https://www.haomeiwen.com/subject/tkdqfctx.html