docker

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > docker > Dockerfile创建镜像

使用Dockerfile创建镜像过程

作者:LKAI.

本文介绍Docker安装及镜像分类,详解Dockerfile指令如FROM、RUN、CMD等,涵盖制作镜像步骤与优化技巧,如减少分层和清理数据,适用于自定义镜像构建实践

实验环境

安装好Docker服务

一、容器镜像分类

1、操作系统类

CentOS、Ubuntu

在dockerhub下载或自行制作

示例:把操作系统的文件系统打包生成镜像

1)开启最小化安装的CentOS

2)打包制作CentOS镜像

tar --numeric-owner --exclude=/proc --exclude=/sys -cvf centos7.tar /

3)导入制作的镜像

docker import centos7.tar centos7:v1

cat centos7.tar | docker import - centos7:v1
docker images

4)使用制作的镜像开启容器

docker run -it centos7:v1 /bin/bash

yum -y install httpd

启动http服务

/usr/sbin/apachectl

ctrl+p+q

2、应用类

Tomcat、Nginx、MySQL、Redis

下载、制作均可

为满足不同环境需求,我们经常自己制作

二、利用Dockerfile制作镜像

1、Dockerfile介绍

Dockerfile是一种能够被Docker程序解释的脚本

Dockerfile由一条一条的指令组成,并且有自己的书写格式和支持的命令,当需要在容器镜像中指定自己额外的需求时,只需在Dockerfile上添加或修改指令,然后通过docker build生成我们自定义的容器镜像。

2、Dockerfile指令

(1)构建类指令:用于构建image

其指定的操作不会运行在image的容器上执行

如:FROM、MAINTAINER、RUN、ENV、ADD、COPY

(2)设置类指令:用于设置image的属性

其指定的操作将运行image的容器中执行

如:CMD、ENTRYPOINT、USER、EXPOSE、WORKDIR、VOLUME

对应指令说明:

3、Dockerfile指令的详细解释

(1)FROM

(2)RUN

RUN指令用于在构建镜像中执行命令,有以下两种格式:

shell格式

exec格式

注意:

按优化的角度来讲,当有多条要执行的命令时,不要使用多条RUN,尽量使用&&符号与\符号连接成一行,因为多条RUN命令会让镜像建立多层

例如:

RUN yum install httpd httpd-devel -y
RUN echo test > /var/www/html/index.html

可以改成

RUN yum install httpd httpd-devel -y && echo test > /var/www/html/index.html

或者改成

RUN yum install httpd httpd-devel -y \ && echo test > /var/www/html/index.html

(3)CMD

CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。

格式有三种:

CMD ["executable","param1","param2"]

CMD ["param1","param2"]

CMD command param1 param2

每个Dockerfile只能有一条CMD命令,如果指定了多条命令,只有最后一条会被执行;如果用户启动容器时候指定了运行的命令,则会覆盖掉CMD指定的命令。

什么是启动容器时指定运行的命令?

# docker run -d -p 80:80 镜像名 运行的命令

(4)EXPOSE

EXPOSE指令用于指定容器在运行时监听的端口

上述运行的端口还需要使用docker run运行容器时通过-p参数映射到宿主机的端口。

(5)ENV

ENV指令用于指定一个环境变量。

(6)ADD

ADD指令用于把宿主机上的文件拷贝到镜像中。

(7)COPY

COPY指令与ADD指令类似,但COPY的源文件只能是本地文件或目录

(8)ENTRYPOINT

ENTRYPOINT与CMD非常类似

相同点:

不同点:

格式有两种:

ENTRYPOINT      ["executable", "param1", "param2"]
ENTRYPOINT      command param1 param2

(9)VOLUME

VOLUME指令用于把宿主机里的目录与容器里的目录映射指定挂载点,docker宿主机映射的目录为自动生成的。

(10)USER

USER指令设置启动容器的用户,即程序用户

像hadoop需要hadoop用户操作;oracle需要oracle用户操作,可以是用户名或UID

如:

注意:

如果设置了容器以daemon用户去运行,那么RUN,CMD和ENTRYPOINT都会以这个用户去运行;镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖指定的用户

(11)WORKDIR

WORKDIR指令设置工作目录,类似于cd命令,不建议使用RUN cd /root,建议使用WORKDIR

如:

4、Dockerfile基本构成

三、Dockerfile生成容器镜像方法

1、使用Dockerfile生成容器镜像步骤

2、使用Dockerfile生成Nginx容器镜像

mkdir nginxdir

cd nginxdir

echo "nginx is running" > index.html

编写Dockerfile文件

vim Dockerfile

添加:

FROM centos:7

MAINTAINER "lkk"

RUN rm -rf /etc/yum.repos.d/*

RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo

RUN yum -y install wget

RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

RUN yum -y install nginx

ADD index.html /usr/share/nginx/html/

RUN echo "daemon off;" >> /etc/nginx/nginx.conf

EXPOSE 80

CMD /usr/sbin/nginx

生成镜像

docker build -t nginx:v1 .

3、使用Dockerfile生成容器镜像优化

(1)减少镜像分层

Dockerfile中包含多种指令,如果涉及到部署最多使用的算是RUN命令了,使用RUN命令时,不建议每次安装都使用一条单独的RUN命令,可以把能够合并安装指令合并为一条,这样就可以减少镜像分层。

FROM centos:7

MAINTAINER lkk

RUN rm -rf /etc/yum.repos.d/*

RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo

RUN yum -y install epel-release

RUN yum -y install gcc gcc-c++ make libxml2 libxml2-devel wget

RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz

RUN tar zxf php-5.6.36.tar.gz

RUN cd php-5.6.36

RUN ./configure --prefix=/usr/local/php

RUN make -j 4

RUN make install

优化如下:

mkdir /root/phpdir
cd /root/phpdir

将php-5.6.27.tar.gz包上传到/root/phpdir/

进入/root/phpdir目录

vim Dockerfile

添加:

FROM centos:7

MAINTAINER lkk

RUN rm -rf /etc/yum.repos.d/* && curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo && yum -y install epel-release && yum -y install gcc gcc-c++ make libxml2 libxml2-devel wget

ADD ./php-5.6.27.tar.gz /

RUN cd /php-5.6.27 && ./configure --prefix=/usr/local/php && make -j 4 && make install

-j(表示 job 的数目)参数可以对项目在进行并行编译。

make -j 4,让make 最多允许 4 个编译命令同时执行,这样可以更有效的利用 CPU 资源。在多核 CPU 上,适当的进行并行编译还是可以明显提高编译速度的,但并行的任务不宜太多,一般是以 CPU 的核心数目的两倍为宜

(2)清理无用数据

一次RUN形成新的一层,如果没有在同一层删除,无论文件是否最后删除,都会带到下一层,所以要在每一层清理对应的残留数据,减小镜像大小。

把生成容器镜像过程中部署的应用软件包做删除处理

vim Dockerfile

添加粗体部分内容:

FROM centos:7

MAINTAINER lkk

RUN rm -rf /etc/yum.repos.d/* && curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo && yum -y install epel-release && yum -y install gcc gcc-c++ make libxml2 libxml2-devel wget && yum clean all && rm -rf /var/cache/yum/*

ADD ./php-5.6.27.tar.gz /

RUN cd /php-5.6.27 && ./configure --prefix=/usr/local/php && make -j 16 && make install && rm -rf /php*

生成镜像

docker build -t php:v1 .

四、通过Dockerfile方式创建tomcat镜像

1、创建目录准备相关文件

mkdir tomcatdir
cd tomcatdir/
echo "tomcat test page" > index.html

上传jdk-8u91-linux-x64.tar.gz包到tomcatdir目录

2、编辑Dockerfile文件

vim Dockerfile

注意安装版本(粗体部分)

添加:

FROM centos:7
MAINTAINER "lkk"
ENV VERSION=9.0.99
ENV JAVA_HOME=/usr/local/jdk
ENV TOMCAT_HOME=/usr/local/tomcat
ENV PATH=$TOMCAT_HOME/bin:$JAVA_HOME/bin:$PATH
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo && \
    yum -y install wget && \
    wget https://dlcdn.apache.org/tomcat/tomcat-9/v${VERSION}/bin/apache-tomcat-${VERSION}.tar.gz --no-check-certificate && \
    tar xf apache-tomcat-${VERSION}.tar.gz && \
    mv apache-tomcat-${VERSION} /usr/local/tomcat && \
    rm -rf apache-tomcat-${VERSION}.tar.gz /usr/local/tomcat/webapps/* && \
    mkdir /usr/local/tomcat/webapps/ROOT
ADD ./index.html /usr/local/tomcat/webapps/ROOT/
ADD ./jdk-8u91-linux-x64.tar.gz /
RUN mv /jdk1.8.0_91/ /usr/local/jdk
EXPOSE 8080
CMD ["/usr/local/tomcat/bin/catalina.sh","run"]

3、构建镜像

docker build -t tomcat:v1 .

4、创建并启动容器

docker run -d -p 8080:8080 tomcat:v1

docker ps -a

curl 192.168.10.11:8080

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文