社区编辑申请
注册/登录
Docker数据卷与DockerFile学习
云计算 云原生
数据卷(Data Volumes)是宿主机中的一个目录或文件,数据卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

什么是数据卷

数据卷(Data Volumes)是宿主机中的一个目录或文件,数据卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。当容器目录和数据卷目录绑定后,对方的修改会立即同步,一个数据卷可以被多个容器同时挂载,一个容器也可以被挂载多个数据卷。

数据卷可以在容器之间共享和重用,本地与容器间传递数据更高

对数据卷的修改会立马有效,在容器内部与本地目录均可对数据卷进行修改

对数据卷的更新,不会影响镜像,对数据与应用进行了解耦操作

卷会一直存在,直到没有容器使用

其实也不难理解和我们上一篇讲的端口映射很相似,因为容器与宿主机之间都是相互隔离的。而端口映射则是在两个互相隔离体之间构建通道,使其可以进行通讯共享。数据卷也是这种意思,但是数据卷不会因为容器的死亡而消失,只要还有一个容器或宿主机与其进行绑定,那么数据卷的内容就不会丢失。

数据卷

一、直接命令挂载在宿主机目录

1、测试nginx

docker run -v 主机目录:容器内目录
docker run -d -v 主机目录地址:/usr/share/nginx/html -p 8080:80 --name nginx-music-volume nginx

当我们的两个目录进行挂载之后,就相当于共用一个目录,不管哪边发送改变目录的内容都会发生改变,这样的话我们只需在宿主机这边的目录进行操作,那么容器内的该目录也会发生相应的变化。就像我上篇文章所进行的cp操作就可以省去,并且当我需要更新版本时也只需在宿主机这边进行操作即可。下面我以nginx进行测试,挂载上自己自定义的网页。

这里我自己网页是放在/var/www/html里,接下来我需要挂载到nginx容器里的html文件夹下。

可以看到已经运行起来了访问也通了,让我们看看网页行不行。

ok也是没问题了。这里我们还能通过docker inspect 容器id 查看详细信息。

这里可以看到确实是挂载成功了。可以看到当我们使用-v时很容易就将自己的本地目录网页放在了容器里,到这里其实就已经可以说明现在这两个目录实际上已经共用同一个目录了,并且就算我将这个容器删除,里面的内容也依旧是保留的。

以后修改或者发布新的版本就只需在服务器进行修改就行容器会自动同步,并且只有容器没删不管是停止状态还是运行状态都会自动同步。

2、 测试mysql

我这用mysql:5.7版本演示,首先docker pull mysql:5.7 ,当然这里我先去官网看了一下。我这里还是建议大家直接先去官方进行查询学习。

但是为了挂载目录方便管理,这里我们需要对该命令进行修改。

docker run -d -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -p 3310:3306 --name mysql01 mysql:5.7 相信看完上一篇文章的你对于这个命令应该不难理解了。
-d 后台
-p 端口映射
-v 卷挂载
-e 环境配置
--name 命名

接下来我们去测试一下是否联通了。

可以看到已经成功了!我们在navicat加一个表看看服务器上是否会有。

这样我们就完成了MySQL容器的数据持久化。就算我们将容器进行删除,数据库中的数据也将获得保存。

二、 匿名挂载和具名挂载

匿名挂载和具名挂载也很好理解,匿名就是没有给名字,具名就是给了具体的名字
docker run -d -v /usr/share/nginx/html -p 8080:80 --name nginx01 nginx (未指定名称,只写了容器内路径的为匿名挂载)
docker run -d -v Aasee:/usr/share/nginx/html -p 8080:80 --name nginx02 nginx(指定名称和容器内路径的为具名挂载)
docker run -d -v 主机路径:容器内路径 -p 8080:80 --name nginx-volume nginx(直接挂载在宿主机指定目录)

下面我来给大家逐一展示,这里我就用-P随机指定端口了因为我8080端口跑着。

匿名

我们可以用docker volume ls 来查看数据卷列表,docker inspect [volumename] 来查看卷信息。

更多使用参数可以 --help查看。

docker inspect 容器id

具名

docker inspect 容器id查看

顺便补充一下。

看到这这幅图就很好理解了。一般建议用具名挂载。

设置只读:docker run -d -v 主机目录地址:/usr/share/nginx/html:ro -p 8080:80 --name 
nginx-music-volume nginx

三、数据卷容器

正如容器与主机之间能够进行通讯,容器与容器之间也可以进行通信,而这个父容器就为数据卷容器,因为我们已经知道了容器与宿主机可以通过数据卷进行文件共享,所以自然容器与容器之间也是同样可以通过数据卷共享。

--volumes-from容器间数据共享命令。
docker run -it --name 子容器名 --volumes-from 父容器名 镜像名 /bin/bash

这里我以nginx进行演示,先启动一个带有数据卷的容器作为父容器,我这把它命令为docker01

docker run -d --name docker01 -P -v volume01:/home/volume01 nginx

好的第一个容器已经做好了,接下来做第二个。

docker run -it --name docker02 --volumes-from docker01 nginx /bin/bash

我们可以去home目录验证一下是不是已经存在volume01文件夹。

我们在这新建一个文件,touch helloDocker.py 然后去docker01看看是不是已经共享了。

可以看到成功了。

DockerFile

  • DockerFile:构建文件,定义了镜像如何生成已经所需的文件等等配置。
  • DockerImages: 通过DockerFile层层生成的最终镜像。最终发布和运行的产品
  • DockerContainer: 容器是镜像运行起来的服务,也是一个可写层。

下面是我找的两幅docker常用命令的简介图。大家可以好好看看有对命令的详细介绍。

可以看到ENTRYPOINT和CMD的功能描述几乎是一样的,但是他们还是有区别的,CMD的命令是执行最后一个,ENTRYPOINT命令则是追加。

所以这里我就通过编写DockerFile来演示他们的区别。

[root@VM-0-3-centos ~]# cd dockerFile/
[root@VM-0-3-centos dockerFile]# vim docker-test-cmd
[root@VM-0-3-centos dockerFile]# cat docker-test-cmd
FROM centos
CMD ["ls","-a"]

这样我们就创建好了一个dockerfile,很简单的一个dockerfile,这个的意思就是当我们运行这个镜像的时候自动ls -a。我们接下来用build命令来创建镜像。

docker build -f docker-test-cmd -t test01-cmd .

现在我们就创建好了。run一下试试。

现在我们在run命令后面加上一个 -l,理论上来说的话如果我们加上了一个-l那么这个镜像在run的时候执行的命令应该是ls -a -l 对吧,我们试试看。

可以看到报错了,这是为什么呢,因为前面说了CMD命令是只执行最后一项,所以当我们在run的时候加上命令-l的话实际镜像运行时执行的命令-l替换了ls -a,那么这时centos就无法识别-l是什么意思了。而ENTRYPOINT则是可以进行追加的,像这种情况entrypoint就可以运行命令为ls -a -l。这里就不对其再进行演示。

制作一个tomcat镜像

我们需要先去准备几个安装包,大家可以去官网上搜索,​​jdk下载​​,​​tomcat下载​​。

下载完用xftp上传上去就行。

接下来就可以编写Dockerfile文件了。

FROM centos:centos7
MAINTAINER Aasee<xxx@qq.com>
COPY readme.txt /usr/local/readme.txt
#导入压缩包会自动解压
ADD apache-tomcat-9.0.63.tar.gz /usr/local/
ADD jdk-8u333-linux-x64.tar.gz /usr/local/
#安装vim
RUN yum -y install vim
#设置工作目录
ENV MYPATH /usr/local
WORKDIR $MYPATH
#jdk环境配置
ENV JAVA_HOME /usr/local/jdk1.8.0_333
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
#tomcat环境配置
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.63
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.63
#配置path环境
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#暴露端口
EXPOSE 8080
# 启动tomcat和打印日志
CMD /usr/local/apache-tomcat-9.0.63/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.63/logs/catalina.out

我这的命名为官方推荐名Dockerfile。所以不需要再用-f来指定文件。直接可以用docker build来创建

docker build -t 命名 .

接下来就可以run起来了

docker run -d -p 9090:8080 --name aaseetomcat -v /root/dockerFile/tomcat/test:/usr/local/apache-tomcat-9.0.63/webapps/test -v /root/dockerFile/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.63/logs aasee-tomcat01

这是我的命令你们也可以按自己需要改,相信看到这里,大部分命令大家都是能看懂的了。

可以看到运行成功并且也挂载成功了。访问页面看看。

日志也能查看了。

再用docker inspect 容器id 来看看卷数据是否绑定成功。

让我们看看tomcatlogs里的目录是否挂载成功。

可以看到已经成功了。

接下来我们就给他新建一个自定义网页试试看。由于我们已经通过卷挂载了webapps/test,所以我们可以直接在宿主机的test目录下进行更改。同时也能反推看看两个目录是否卷挂载成功。

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
</web-app>

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello world</title>
</head>
<body bgcolor="F6F3D6">
<!--用HTML语言向世界打声招呼吧!-->
<h1 align="center">Hello World</h1>
<p align="center">Aasee-Docker</p>
</body>
</html>

接着我们去看看页面的效果吧。

欧克了。

push到仓库保存

当我们做好镜像之后要怎么给别人使用呢,有两种方法一种是打包到本地然后发给别人,另一种是上传到docker官方仓库或者是阿里云,腾讯云等这些大厂的官方仓库。但是由于docker官方仓库节点在国外,速度时好时坏的,而且操作都差不多,这里就以阿里云为例子(腾讯云相同操作)。

首先先登录阿里云。

直接搜索容器镜像服务,我们个人测试使用就直接用个人版就行,然后根据提示创建命令空间再创建镜像仓库选择本地仓库之后就可以看到push的教程了。

这些内容就大家自己去看了。官方的命令很详细了。根据官方的命令我们就能很容易得将镜像推送到官方仓库。

补充

这里补充一下其他命令,例如docker history 镜像id这样就能看到这个镜像怎么生成的了。

像这样👇

总结

到这里我们就基本能独立构建镜像并且使用镜像用来搭建发布项目了!

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2022-06-28 12:35:21

DockerPython

2022-06-05 21:09:47

Python办公自动化

2022-05-26 15:02:35

Docker容器云原生

2022-06-03 09:41:03

DockerKubernetes容器

2022-06-28 12:14:02

DockerLinux

2022-03-10 08:24:17

Docker容器SaaS

2022-06-27 17:46:53

PythonFlask

2022-06-24 10:16:59

Python精选库

2022-07-01 14:25:27

机器学习人工智能工业4.0

2022-04-24 14:11:26

病毒僵尸网络网络攻击

2022-06-15 08:25:07

Python天气数据可视化分析

2022-06-15 08:21:49

Linux运维工程师

2022-06-30 18:17:00

数据集云数据建模计数据仓库

2022-06-16 17:02:49

微软智能云混合云Azure

2022-06-24 11:14:00

美团开源

2022-06-28 11:16:36

机器学习数据科学

2022-05-24 12:34:32

Docker容器Linux容器进程

2022-06-30 14:23:56

机器学习工具算法

2022-06-27 19:01:04

Python应用程序数据

2022-06-17 09:47:04

Linux命令

同话题下的热门内容

七个用于云原生世界的Java框架实现Kubernetes可观测性的三种优秀工具无服务器计算正在成为云原生的下一个发展方向一文读懂云网络迁移云计算工作负载的四个基本策略专有云你想知道的,这一篇就够了云存储架构框架设计如何实现以应用为基础的服务模式?使用 Traefik Hub 轻松暴露本地 Kubernetes 集群服务

编辑推荐

Service Mesh真的是云原生应用的绝配吗云原生桌面:虚拟桌面的解构与重新定义解密云原生---看企业云的未来云原生技术及其未来发展趋势展望如何评估云原生NFV中的容器化VNF部署
我收藏的内容
点赞
收藏

51CTO技术栈公众号