docker知识6---docker存储
docker存储
容器,在镜像分层上添加可读写的分层,因此容器退出时,写入layer的数据会丢失;当数据写入外挂的volume时,容器退出,不会导致volume中的数据丢失。
docker持久化数据方案有2类:
1)基于本地文件系统的volume;可在执行docker create或docker run时,通过-v参数将主机的目录作为容器的数据卷;这部分功能便是基于本地文件系统的volume管理。
2)基于plugin的volume,支持第三方的存储方案,比如NAS,AWS;
volume类型分为:
1)受管理的data volume,由docker后台自动创建;
2)绑定挂载的volume,具体挂载位置可以由用户指定;
案例1:data volume---受docker管理的volume
指定持久化卷的路径(该路径为容器运行时所有产生数据的存储位置,在image中使用VOLUME指定)、然后将容器volume路径映射到宿主机本地磁盘,如下图;
cat Dockerfile |ls VOLUME #查看dockerfile中的volume目录为/var/lib/mysql; docker run -d -e MYSQL_ALLOW_EMPTY_PASSWORD=true --name mysql1 mysql #启动名为mysql1的mysql服务,初始化时规定无需密码即可登录mysql; docker volume ls #查看mysql1创建的volume; docker volume inspect 3ba0c4d22ea4004793d8e4d991740759287997a8d0dacff56afbac2f5c13a5da #查看挂载卷信息; docker run -d -v mysql2_volume:/var/lib/mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=true --name mysql2 mysql #启动mysq2服务,由于自动创建的volume的名称太长,故使用-v指定volume的名; docker container exec -it mysql2 mysql -u root -e 'show databases;' docker container exec -it mysql2 mysql -u root -e 'create database docker_mysql2;' docker container exec -it mysql2 mysql -u root -e 'show databases;' docker rm -f mysql1 mysql2 docker container ls -a docker volume ls #查看到mysql实例删除后,但volume仍存在,即volume可实现持久化存储; docker run -d -v mysql2_volume:/var/lib/mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=true --name mysql3 mysql #启动mysq3服务,使用指定名为mysql2_volume的volume; docker container exec -it mysql3 mysql -u root -e 'show databases;' #查看mysql3服务中存在docker_mysql2表等内容,表示mysql服务的volume在容器退出后仍然存在;
该图表示mysql镜像中指定了volume的挂载的目录;
案例2:bind mouting---绑定挂载的volume
mkdir hello_nginx_volume cd hello_nginx_volume cat <<eof> Dockerfile # this same shows how we can extend/change an existing official image from Docker Hub FROM nginx:latest # highly recommend you always pin versions for anything beyond dev/learn WORKDIR /usr/share/nginx/html # change working directory to root of nginx webhost # using WORKDIR is prefered to using 'RUN cd /some/path' COPY index.html index.html # I don't have to specify EXPOSE or CMD because they're in my FROM eof cat <<eof> index.html <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>hello</title> </head> <body> <h1>Hello Docker! </h1> </body> </html> eof docker build -t chalon/nginx ./ docker images ls docker run -d -p 1080:80 --name nginx_1 chalon/nginx curl 127.0.0.1:1080 #服务正常运行; docker exec -ti nginx_1 touch test1_nginx_1.txt #在容器工作目录创建文件; docker exec -ti nginx_1 ls #在容器工作目录新建文件; ls #查看宿主机本地文件,并未与容器工作目录同步数据; docker rm -f nginx_1 docker container ls -a docker run -d -v $(pwd):/usr/share/nginx/html -p 2080:80 --name nginx_2 chalon/nginx #将当前目录映射为容器工作目录; docker exec -ti nginx_2 touch test1_nginx_2.txt #在容器工作目录创建文件; docker exec -ti nginx_2 ls #在容器工作目录新建文件; ls #查看宿主机本地文件,与容器工作目录同步数据; docker rm -f nginx_2 ls #容器文件持续存储本地磁盘;
案例3:bind mouting应用实例
mkdir flask-skeleton cd flask-skeleton # ~~~~上传程序源代码 cd scripts/ chmod +x dev.sh deploy.sh ls #scripts/dev.sh为程序启动脚本; cat <<eof> Dockerfile FROM python:2.7 LABEL maintainer="chalon" COPY . /skeleton WORKDIR /skeleton RUN pip install -r requirements.txt EXPOSE 5000 ENTRYPOINT ["scripts/dev.sh"] eof docker build -t chalon/flask-skeleton ./ docker run -d -p 1080:5000 --name flask-skeleton chalon/flask-skeleton curl 127.0.0.1:1080 #服务运行正常,但是程序源代码变化时,容器并不能同步; docker rm -f flask-skeleton docker run -d -v $(pwd):/skeleton -p 1080:5000 --name flask-skeleton-proc chalon/flask-skeleton #将本地磁盘目录映射至容器内部,以便修改源码过程中随时查看容器运行的效果; cd /root/flask-skeleton/ && cat home.html #进入前台,查看主页内容; sed -i 's/Welcome/Welcome chalon/g' home.html #修改主页内容; curl 127.0.0.1:1080 #查看主页,已发生变化;web浏览器可安装自动刷新插件,以便观察程序修改后的效果;