一、 镜像组成
在制作自己镜像前,我们需要了解一个镜像的组成结构。
镜像,之所以可以能够忽略运行环境配置而首先跨操作系统(不同的linux系统)部署,是因为一个镜像包含了应用、应用所需要的系统函数库、应用依赖、以及应用配置等文件。把应用所需要的运行环境全部打包到一起。
所以,我们自己制作镜像也应该包括当前应用所需的依赖、配置、系统函数库,等文件。
根据上面讲解,我们知道了一个镜像的组成部分,把这些文件全部打包一起就可以形成一个镜像文件。
但是,仅仅一股脑的全部打包一起就可以了吗?
当然不是,Docker 会对镜像各个组成进行分层。
二、镜像分层
1、为什么要分层
镜像就是一堆文件的集合。
但需要注意的是,镜像文件不是随意堆放的,而是按照操作的步骤分层叠加而成,每一层形成的文件都会单独打包并标记一个唯一id,称为Layer(层)。
这样,如果我们构建时用到的某些层其他人已经制作过,就可以直接拷贝使用这些层,而不用重复制作,极大的提高了镜像制作的效率和难度。
2、镜像如何分层
例如,上面所说的制作 JAVA 镜像 ,需要的Linux运行环境,通用性就很强,所以Docker官方就制作了这样的只包含Linux运行环境的镜像。我们在制作java镜像时,就无需重复制作,直接使用Docker官方提供的CentOS或Ubuntu镜像作为基础镜像。
然后再搭建其它层即可,这样逐层搭建,最终整个Java项目的镜像结构如图所示:
三、制作镜像
由于制作镜像的过程中,需要逐层处理和打包,比较复杂,所以Docker就提供了自动打包镜像的功能。我们只需要将打包的过程,每一层要做的事情用固定的语法写下来,交给Docker去执行帮助创建镜像即可。
而这种记录镜像结构的文件就称为 Dockerfile ,
1、制作 Dockerfile 文件
Dockerfile ,其对应的语法可以参考官方文档:
Dockerfile 文档
下面介绍 Dockerfile:
指令 | 说明 | 示例 |
---|---|---|
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 |
例如,要基于Ubuntu镜像来构建一个Java应用,其Dockerfile内容如下:
# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录、容器内时区
ENV JAVA_DIR=/usr/local
ENV TZ=Asia/Shanghai
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 设定时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 安装JDK,cd 进入安装文件夹,tar 解压文件,mv 重命名。
RUN cd $JAVA_DIR \
&& tar -xf ./jdk8.tar.gz \
&& mv ./jdk1.8.0_144 ./java8
# 配置 javaHome 环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 指定项目监听的端口
EXPOSE 8080
# 入口,java项目的启动命令
ENTRYPOINT ["java", "-jar", "/app.jar"]
观察上面,以后我们会有很多很多java项目需要打包为镜像,他们都需要Linux系统环境、JDK环境这两层,只有上面的几层不同(因为每次jar包不同)。如果每次制作java镜像都重复制作前两层镜像,是不是浪费资源。
所以,就有人提供了基础的系统加JDK环境,我们在此基础上制作java镜像,就可以省去JDK的配置了:
# 基础镜像,包含了linux系统环境,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"]
2、构建镜像
当Dockerfile文件写好以后,就可以利用命令来构建镜像了。
①将 jar 包和 dockerfile 文件cope到 Linux 服务器。
② 进入该目录,并且执行镜像构建命令
# 进入镜像目录
cd /root/demo
# 开始构建
docker build -t docker-demo:1.0 /dockerDemo
命令说明:
- docker build : 就是构建一个docker镜像
- -t docker-demo:1.0 :-t 参数是指定镜像的名称(repository和tag)
- /dockerDemo: 是指构建时Dockerfile所在路径
因为是初次下载docker的jdk基础镜像,时间比较长。
③查看镜像
docker images
可以看见docker镜像构建成功。
3、运行镜像
镜像文件在运行的时候,docker会创建一个对外隔离的容器运行整个镜像。
对于 Docker 镜像容器不是很清楚,可以看一下:Docker容器
# 创建容器并运行
docker run -d --name docker-demo -p 8082:8090 docker-demo:1.0
# 查看运行的容器
docker ps
# 查看容器日志
docker logs -f docker-demo
这里命令不清楚的,可以去看一下我之前的文章:
我这里容器名字弄错了,成了docker-name,大家看的时候注意下。
下面可以看到容器启动成功。