docker(2)

1、数据卷

为什么要用数据卷?

容器是隔离环境,容器内程序的文件、配置、运行时产生的容器都在容器内部,我们要读写容器内的文件非常不方便。大家思考几个问题:

1、容器中的文件在宿主机上存在形式复杂,不能在宿主机上很方便地对容器中的文件进行访问。

2、多个容器之间的数据无法共享

3、当删除容器时,容器产生的数据将丢失。

因此,容器提供程序的运行环境,但是程序运行产生的数据、程序运行依赖的配置都应该与容器解耦。

 什么是数据卷

数据卷是一个虚拟的目录,他将宿主主机的目录映射到容器的目录,方便我们操作容器内文件,或者方便迁移容器产生的数据

在上图中:

  • 我们创建了两个数据卷:confhtml

  • Nginx容器内部的conf目录和html目录分别与两个数据卷关联。

  • 而数据卷conf和html分别指向了宿主机的/var/lib/docker/volumes/conf/_data目录和/var/lib/docker/volumes/html/_data目录

这样以来,容器内的confhtml目录就 与宿主机的confhtml目录关联起来,这称为挂载。此时,我们操作宿主机的/var/lib/docker/volumes/html/_data就是在操作容器内的/usr/share/nginx/html/_data目录。只要我们将静态资源放入宿主机对应目录,就可以被Nginx代理。

而且容器与数据卷的挂载要在创建容器时配置,对于创建好的容器,是不能设置数据卷的。而且创建容器的过程中,数据卷会自动创建

如何挂载数据卷

  • 在执行docker run命令创建容器时,利用  -v 数据卷名: 容器内目录   完成挂载

-v参数的前半部分是数据卷名字,自己起名,不与别人冲突即可,后半部分是容器内要挂载的目录

  • 当容器创建时,如果发现挂载的数据卷不存在,则会自动创建数据卷

数据卷的常见命令

命令

说明

docker volume create

创建数据卷

docker volume ls

查看所有数据卷

docker volume rm

删除指定数据卷

docker volume inspect

查看某个数据卷的详情

docker volume prune

清除数据卷

当数据卷的目录结构较深时,我们去操作数据卷目录会不太方便。在很多情况下,我们会直接将容器目录与宿主机指定目录挂载。挂载语法与数据卷类似:

挂载本地目录:-v 本地目录:容器目录

挂载本地文件:-v 本地文件:容器文件

本地目录或文件必须以 /./开头,如果直接以名字开头,会被识别为数据卷名而非本地目录名。

-v mysql:/var/lib/mysql  会被识别为一个数据卷叫mysql,运行时会自动创建这个数据卷

-v ./mysql:/var/lib/mysql  会被识别为当前目录下的mysql目录,运行时如果不存在会创建目录

2、镜像

之前我们一直在使用别人准备好的镜像,那如果我要部署一个Java项目,把它打包为一个镜像该怎么做呢?

镜像打包

当要部署一个java项目的时候,需要把它打包成一个镜像,而要想自己构建镜像就必须先了解镜像的结构。

而镜像之所以能让我们快速跨操作系统部署应用而忽略其运行环境、配置,就是因为镜像中包含了程序运行需要的系统函数库、环境、配置、依赖。

因此,自定义镜像本质就是依次准备好程序运行的基础环境、依赖、应用本身、运行配置等文件,并且打包而成。

而我们要从0部署一个Java应用,大概流程是这样:

  • 准备一个linux服务(CentOS或者Ubuntu均可)

  • 安装并配置JDK

  • 上传Jar包

  • 运行jar包

那因此,我们打包镜像也是分成这么几步:

  • 准备Linux运行环境(java项目并不需要完整的操作系统,仅仅是基础运行环境即可)

  • 安装并配置JDK

  • 拷贝jar包

  • 配置启动脚本

上述步骤中的每一次操作其实都是在生产一些文件(系统运行环境、函数库、配置最终都是磁盘文件),所以镜像就是一堆文件的集合

但是镜像文件不是随意堆放的,而是按照操作的步骤分层叠加而成,每一层形成的文件都会单独打包并标记一个唯一id,称为Layer)。这样,如果我们构建时用到的某些层其他人已经制作过,就可以直接拷贝使用这些层,而不用重复制作。

最终整个Java项目的镜像结构分为三层:

入口层:           镜像运行的入口,一般是程序启动的脚本和参数

层:                  在基础镜像层上再添加安装包、依赖、配置等,每次操作都形成新的一层

基础镜像层:    应用依赖的系统函数库、环境、配置、文件等

Dockerfile

由于制作镜像的过程中,需要逐层处理和打包,比较复杂,所以Docker就提供了自动打包镜像的功能。我们只需要将打包的过程,每一层要做的事情用固定的语法写下来,交给Docker去执行即可。而这种记录镜像结构的文件就称为Dockerfile

而这种记录镜像结构的文件就称为Dockerfile,其对应的语法可以参考官方文档:

Dockerfile reference | Docker Docs

其中的语法比较多,比较常用的有:

指令

说明

示例

FROM

指定基础镜像

FROM centos:6

ENV

设置环境变量,可在后面指令使用

ENV key value

COPY

拷贝本地文件到镜像的指定目录

COPY ./xx.jar /tmp/app.jar

RUN

执行Linux的shell命令,一般是安装过程的命令

RUN yum install gcc

EXPOSE

指定容器运行时监听的端口,是给镜像使用者看的

EXPOSE 8080

ENTRYPOINT

镜像中应用的启动命令,容器运行时调用

ENTRYPOINT java -jar xx.jar

但是以后我们会有很多很多java项目需要打包为镜像,他们都需要Linux系统环境、JDK环境这两层,只有其他几层不同。如果每次制作java镜像都重复制作前两层镜像,是不是很麻烦。

所以,就有人提供了基础的系统加JDK环境,我们在此基础上制作java镜像,就可以省去JDK的配置:

# 基础镜像

FROM openjdk:11.0-jre-buster

# 设定时区

ENV TZ=Asia/Shanghai

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 拷贝jar包

COPY docker-demo.jar /app.jar

# 入口

ENTRYPOINT ["java", "-jar", "/app.jar"]

构建镜像

当Dockerfile文件写好以后,就可以利用命令来构建镜像了。

首先准备好一个demo项目及对应的Dockerfile,接下来开始尝试构建镜像

我们将docker-demo.jar包以及Dockerfile拷贝到虚拟机的/root/demo目录:

然后,执行命令,构建镜像:

# 进入镜像目录

cd /root/demo

# 开始构建

docker build -t docker-demo:1.0 .

  • docker build : 就是构建一个docker镜像

  • -t docker-demo:1.0-t参数是指定镜像的名称(repositorytag

  • . : 最后的点是指构建时Dockerfile所在路径,由于我们进入了demo目录,所以指定的是.代表当前目录(点的前面有一个空格),也可以直接指定Dockerfile目录:

# 直接指定Dockerfile目录

docker build -t docker-demo:1.0 /root/demo

查看结果

查看镜像列表

运行该镜像

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值