繁体   English   中英

Docker卷不保留数据

[英]Docker volume does not persist data

这是我的docker文件:

FROM ubuntu:14.04

RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8
RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list

RUN apt-get update && apt-get -y -q install python-software-properties software-properties-common \
    && apt-get -y -q install postgresql-9.3 postgresql-client-9.3 postgresql-contrib-9.3

USER postgres
RUN /etc/init.d/postgresql start \
    && psql --command "CREATE USER pguser WITH SUPERUSER PASSWORD 'pguser';" \
    && createdb -O pguser pgdb
USER root
RUN echo "host all  all    0.0.0.0/0  md5" >> /etc/postgresql/9.3/main/pg_hba.conf
RUN echo "listen_addresses='*'" >> /etc/postgresql/9.3/main/postgresql.conf
EXPOSE 5432

RUN mkdir -p /var/run/postgresql && chown -R postgres /var/run/postgresql
VOLUME  ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]
USER postgres

CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]

这是我做的...

  1. 我构建了docker镜像:

     docker build --rm=true -t my_image/postgresql:9.3 
  2. 然后,我在当前目录中创建一个名为data的新目录,并运行以下命令:

     docker run -i -t -v="data:/data" -p 5432:5432 my_image/postgresql:9.3 
  3. 我打开另一个终端并通过运行进入postgres shell:

     psql -h my_docker_ip -p 5432 -U pguser -W pgdb 

    然后创建一个表:

     pgdb=# create table test (test_id bigserial primary key); 
  4. 我使用\\dt验证表是否存在并退出postgres shell

  5. 我终止docker进程并重新运行以下命令:

     docker run -i -t -v="data:/data" -p 5432:5432 my_image/postgresql:9.3 
  6. 我再次进入posgrest shell并运行\\dt

  7. 我注意到
    • 没有桌子。
    • data目录中没有文件。

我肯定做错了,因为我假设我创建的表将持久存在。 有人可以指出我的错误吗?

根据您的评论:

数据已持久,但是我仍然无法在主机./data目录中找到持久数据

并运行以下命令:

docker run -i -t -v="data:/data" -p 5432:5432 my_image/postgresql:9.3

您似乎混淆了命名卷和主机卷。 当您给卷命名时没有路径,例如data ,则使用命名卷。 命名卷使用泊坞窗驱动程序(通常是本地驱动器)以可重用的给定名称存储数据。 它具有在docker volume ls列出并在安装位置初始化为映像内容的优点。

如果包括完整路径,例如/home/username/data ,它将从Docker主机而不是使用命名卷挂载目录。 最大的缺点是您没有使用映像中的内容初始化目录,并且可能会遇到权限问题,其中容器进程的uid与您在主机上使用的uid不匹配。

有关更多详细信息,请参阅https://docs.docker.com/engine/tutorials/dockervolumes/

有一些让我感到困惑的事情,对我而言,官方文档中并不清楚。

据我所知,可以通过三种方式创建持久卷。

  • 在包含完整路径( -v ~/database:/data )的容器调用时 :使主机的外部文件夹在docker容器内可用。 两者都可以修改它。
  • 在容器调用时,使用卷名( -v datamysql:/data ):在容器内部使持久卷可用。 如果它不存在,则会创建它。 您可以使用docker volume ls按名称列出它们。 在内部,它将存储在/var/lib/docker/volumes/ae4445f7c9317a22fe84726fb894c47754f38a7fd150c00fd877024889968750/_data
  • 在容器构建时 (Dockerfile中的VOLUME ["/database/data"] )。 每次docker run调用都会创建一个新卷,即使您删除容器,该卷也将保留。 这可能会造成混乱,因为后续的调用将导致创建不同的卷,而这些卷将无法重用。

您可以使用以下命令列出已命名(第二种情况)卷和未命名(第三种情况)卷

$ docker volume ls                                                             
DRIVER              VOLUME NAME                                                             
local               064593b3e65977097d4d0c8402a6c633f1af69be2937bf118678ab8f97ee9a7e               
local               4753ad0437d13e54c76d9c34a30a1843396a1866a0cf9237d500fdcca0d78c5f           
local               8d7a35354f666b2e8a26866a35bbae36bb9601701d4c6b505ab8ce6629f69415               
local               db48eefe8f189b36107ca9c4eebb792690590ab0ba055e7e4e2c9adfd1765b7e                    
local               datamysql

您可以使用docker inspect mycontainer容器的确切位置

{
                "Type": "volume",
                "Name": "8d7a35354f666b2e8a26866a35bbae36bb9601701d4c6b505ab8ce6629f69415",
                "Source": "/media/USBdrive/docker/volumes/8d7a35354f666b2e8a26866a35bbae36bb9601701d4c6b505ab8ce6629f69415/_data",
                "Destination": "/var/lib/mysql",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },

删除未使用的卷可能很方便(特别是对于第三种情况)。

$ docker volume prune
WARNING! This will remove all volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
4753ad0437d13e54c76d9c34a30a1843396a1866a0cf9237d500fdcca0d78c5f

Total reclaimed space: 205MB

因为您在Dockerfile中使用了VOLUME指令,所以处于第三种情况。 检查您的容器以查找文件,如果要重复的会话来保留数据,请从命令行指定卷。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM