使用Dockerfile创建镜像
实验环境
安装好Docker服务
一、容器镜像分类
1、操作系统类
CentOS、Ubuntu
在dockerhub下载或自行制作
示例:把操作系统的文件系统打包生成镜像
1)开启最小化安装的CentOS
2)打包制作CentOS镜像
tar --numeric-owner --exclude=/proc --exclude=/sys -cvf centos7.tar /
--numeric-owner:以数字形式保存文件的所有者和组信息,而不是名称。这在跨系统打包时非常有用。
--exclude=/proc:排除 /proc 目录。/proc 是一个虚拟文件系统,包含系统运行时的进程信息,不适合打包。
--exclude=/sys:排除 /sys 目录。/sys 是另一个虚拟文件系统,包含内核和设备的运行时信息,也不适合打包。
-c:创建新的归档文件。
-v:显示详细输出,列出正在处理的文件。
-f centos7.tar:指定归档文件名为 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
对应指令说明:
FROM 构建新镜像基于的基础镜像(必须为第一条指令)
RUN 执行命令,通常用于安装软件或运行脚本
COPY 将文件或目录从主机复制到镜像中
ADD 类似 COPY,但支持自动解压 tar 文件和从 URL 下载文件
ENV 设置环境变量
USER 指定运行后续指令的用户
EXPOSE 声明容器运行时监听的端口(容器内打开的端口)
WORKDIR 设置工作目录,后续指令默认在该目录下执行
CMD 指定容器启动时默认执行的命令(可以被 docker run 覆盖)
ENTRYPOINT 指定容器启动时默认执行的命令(不会被 docker run 覆盖,但可以追加参数)
3、Dockerfile指令的详细解释
(1)FROM
FROM指令用于指定其后构建新镜像所使用的基础镜像。
FROM指令必是Dockerfile文件中的首条命令。
FROM指令指定的基础image可以是官方远程仓库中的,也可以位于本地仓库,优先本地仓库。
(2)RUN
RUN指令用于在构建镜像中执行命令,有以下两种格式:
shell格式
格式:RUN <命令>
例:RUN echo 'test' > /var/www/html/index.html
exec格式
格式:RUN ["可执行文件", "参数1", "参数2"]
例:RUN ["/bin/bash", "-c", "echo test > /var/www/html/index.html"]
注意:
按优化的角度来讲,当有多条要执行的命令时,不要使用多条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指令用于指定容器在运行时监听的端口
格式:EXPOSE
例:EXPOSE 80 3306 8080
上述运行的端口还需要使用docker run运行容器时通过-p参数映射到宿主机的端口。
(5)ENV
ENV指令用于指定一个环境变量。
格式:ENV
例:ENV JAVA_HOME /usr/local/jdkxxxx/
(6)ADD
ADD指令用于把宿主机上的文件拷贝到镜像中。
格式:ADD
(7)COPY
COPY指令与ADD指令类似,但COPY的源文件只能是本地文件或目录
格式:COPY
(8)ENTRYPOINT
ENTRYPOINT与CMD非常类似
相同点:
一个Dockerfile只写一条,如果写了多条,那么只有最后一条生效,都是容器启动时才运行
不同点:
如果用户启动容器时候指定了运行的命令,ENTRYPOINT不会被运行的命令覆盖,而CMD则会被覆盖。
格式有两种:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
(9)VOLUME
VOLUME指令用于把宿主机里的目录与容器里的目录映射指定挂载点,docker宿主机映射的目录为自动生成的。
格式:VOLUME ["
(10)USER
USER指令设置启动容器的用户,即程序用户
像hadoop需要hadoop用户操作;oracle需要oracle用户操作,可以是用户名或UID
如:
USER daemon
USER 1001
注意:
如果设置了容器以daemon用户去运行,那么RUN,CMD和ENTRYPOINT都会以这个用户去运行;镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖指定的用户
(11)WORKDIR
WORKDIR指令设置工作目录,类似于cd命令,不建议使用RUN cd /root,建议使用WORKDIR
如:
WORKDIR /root
4、Dockerfile基本构成
基础镜像信息 FROM
维护者信息 MAINTAINER
镜像操作指令 RUN
容器启动时执行指令 CMD
三、Dockerfile生成容器镜像方法
1、使用Dockerfile生成容器镜像步骤
第一步:创建一个文件夹(目录)
第二步:在文件夹(目录)中创建Dockerfile文件及其它文件
第三步:使用docker build命令构建镜像
第四步:使用构建的镜像启动容器
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