docker镜像创建 dockerfile

dockerfile介绍

dockerfile是创建自定义镜像的一种方式

包括配置文件,挂载点,对外暴露的端口,设置环境变量。

docker的创建镜像的方式

1.基于已有镜像创建-----docker pull centos:7

根据官方提供的镜像源,创建镜像,然后拉取容器。是一个白板,只能提供基础的功能,扩展性的功能还是需要自定义(进入容器进行操作)

2.基于模板进行创建

3.基于dockerfile创建

联合文件系统(UnionFS),docker镜像的基础。

镜像是通过分层来进行集成,特性是一次同时加载多个文件系统,但是从外面来看,就是一个文件系统

docker镜像实际上就是由一层一层的文件系统组成,这种层级的文件系统就是UnionFS。

每一层都是layers,每一层都是包含文件系统的一部分,这些层次叠加在一起,最终形成rootfs。

docker镜像创建 dockerfile_第1张图片

docker镜像创建 dockerfile_第2张图片

docker镜像创建 dockerfile_第3张图片

bootfs:宿主机提供的内核和引导程序

rootfs:就是容器的操作系统,在dockerfile中,我们可以自己指定。

rootfs是多个基础镜像和应用镜像结合起来的只读层。镜像实际上就是一个只读文件。

容器基于镜像实例,运行起来之后,容器变成可读可写层。

dockerfile的镜像分层

在dockerfile中,每创建一个指定都是一个镜像层。

镜像层会被缓存和复用。

一旦有一层缓存镜像失败,所有镜像都会失败。镜像也不会创建。

镜像层是不可变的,你在某一层当中添加一个新的命令,但是下一层删除了指令,镜像中基于这个命令创建的文件还会存在,但是在容器中看不见。

dockerfile的镜像分层

镜像不是一个单一的文件,而是有多层构成。容器其实是在镜像的最上面加了一层读写层,在运行容器里做的任何文件改动,都会写到这个读写层。如果删除了容器,也就删除了其最上面的读写层,文件改动也就丢失了。Docker使用存储驱动管理镜像每层内容及可读写层的容器层。

(1)Dockerfile中的每个指令都会创建一个新的镜像层;

(2)镜像层将被缓存和复用;

(3)当Dockerfile的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效;

(4)某一层的镜像缓存失效,它之后的镜像层缓存都会失效;

(5)镜像层是不可变的,如果在某一层中添加一个文件,然后在下一层中删除它,则镜像中依然会包含该文件,只是这个文件在Docker 容器中不可见了。
docker镜像创建 dockerfile_第4张图片

dockerfile的核心:用户的个性化定制docker的镜像。

dockerfile的文件结构

  • 1.基础镜像信息
  • 2.维护者信息
  • 3.镜像的操作指令
  • 4.容器启动时,执行的命令

dockerfile的语法

FROM 指定基础镜像信息。指定容器的操作系统。
MAINTAINER 指定维护者信息(可有可无)
RUN 在这个基础镜像上执行的命令,每个RUN就是一层,分层越多,镜像越大
ENTRYPOINT 设置容器运行时的默认命令(容器内部运行的主程序)
CMD 指定容器运行时的默认命令(docker run /bin/bash后面加了其他命令。cmd的指令会被覆盖。)
EXPOSE 暴露端口(指定容器的运行端口)
ENV 设置环境变量,环境变量可以被run命令使用(声明容器运行需要的环境变量)
ADD 复制,解压。解压不支持 .zip 和 .tar 。 支持URL地址解压和复制
COPY 复制文件,不能解压,而且只能复制本地文件。文件要和dockerfile在一个目录。(官方推荐复制用copy)
VOLUME 创建一个容器内的挂载点既可以为宿主机挂载,也可以供容器挂载。
USER 设置运行镜像时使用的用户或者UID。(可以不加)
WORKDIR 为后续指令设置的工作目录。
ONBUILD 这个镜像可以被其他镜像引用,需要这个命令。
ARG

传参,用于创建容器时,传递参数。ENV用于容器运行时设置环境变量

注意!!dockerfile的语法都是大写!!!

1.FROM 镜像 

指定新镜像所基于的基础镜像,第一条指令必须为FROM指令,每创建一-个镜像就需要一条FROM指令。

2 MAINTAINER 名字

说明新镜像的维护人信息

3 RUN 命令

在所基于的镜像上执行命令,并提交到新的镜像中.

尽量减少run命令的条数。

当命令较长时,可以使用 \ 来换行;
多条命令可以使用 ; 或 && 合并成一条命令,减少镜像的层数。


4 ENTRYPOINT

ENTRYPOINT ["要运行的程序","参数1","参数2"]

设定容器启动时第一个运行的命令及其参数。
 

5 CMD

CMD ["要运行的程序","参数1","参数2"]

 *  *  *  ENTRYPOINT和CMD的区别 *  *  *

1.CMD可以吧参数传给ENTRYPOINT

2.多个entrypoint和多个cmd只会运行最后一个(一个dockerfile当中只会有一个entrypoint和cmd)

3.entrypoint的指令不会被覆盖,CMD的指令如果在docker run的后面加上输出,会被覆盖

4.entrypoint的指令在容器启动时执行,都会成为容器的主进程。主进程负责接收信号,处理容器的声明周期,主进程一旦退出,容器也将终止运行

6 EXPOSE 端口号

指定新镜像加载到Docker 时要开启的端口。

用于暴露端口,否则即使做了端口映射,外部也找不到。

7 ENV

ENV 环境变量 变量值

设置一个环境变量的值,会被后面的RUN使用。

8 ADD

ADD 源文件/目录 目标文件/目录

将源文件复制到镜像的指定路径中,源文件要与 Dockerfile 位于相同目录中,或者是一个URL。(URL路径,在线路径)

  • ADD 的优点: 在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip、bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
  • ADD 的缺点: 在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
     

9.COPY

COPY 源文件/目录 目标文件/目录

只复制本地主机上的文件/目录复制到目标地点,源文件/目录要与Dockerfile在相同的目录中。

copy和add区别:

copy和add都可以把本地文件复制到镜像中,但是官方推荐如果是复制,使用copy。

区别在于add可以解压,如果是一个压缩文件,add在复制之后会自动解压(tar.gz和tar.bz2)可以支持URL下载源文件。支持下载,但是不能解压。通过URL拷贝的文件无法自动解压。

copy只能复制,不能解压,而且只能是本地文件,不支持URL路径。

10.RUN

RUN命令的优化

主要是减少镜像的层数:把多个RUN命令写在一块。

&&符号:

举个例子:

RUN yum -y install nginx && make -j 4 && make install

前一个命令运行成功才会运行后面

;符号

RUN yum -y install nginx;make -j 4 ; make install

不管前面的是否成功,后面的命令都会执行

||

RUN yum -y install nginx || make -j 4

如果前一个命令执行失败,才会执行后面的命令

反斜杠 \ 换行

RUN yum -y install nginx\

&& make -j 4 \

&& make install

可读性更高

实战训练---基于centos7构建一个apache的dockerfile(编译安装)

mkdir apache
cd apache
拖入三个包

docker镜像创建 dockerfile_第5张图片

vim Dockerfile

#创建基础镜像
FROM centos:7
MAINTATNER "this is my apache "
RUN yum install -y gcc gcc-c++ make pcre pcre-devel expat-devel perl
ADD apr-1.6.2.tar.gz /opt/
ADD apr-util-1.6.0.tar.gz /opt/
ADD httpd-2.4.29.tar.bz2 /opt/
//解压到镜像的/opt中

RUN mv /opt/apr-1.6.2 /opt/httpd-2.4.29/srclib/apr && mv /opt/apr-util-1.6.0 /opt/httpd-2.4.29/srclib/apr-util &&\ 
cd /opt/httpd-2.4.29/ &&\

./configure --prefix=/usr/local/httpd --enable-so --enable-rewrite --enable-charset-lite --enable-cgi &&\
make -j 4 && make install
EXPOSE 80
CMD ["/usr/local/httpd/bin/apachectl","-D","FOREGROUND"]
在Docker容器启动时,以前台守护进程模式运行Apache HTTP服务器。
wq!

docker build -t apache:centos .
.:执行当前目录的dockerfile

docker run -itd --name httpd1 -p 1314:80 apache:centos 
docker ps

浏览器访问
20.0.0.20:1314

如何基于镜像进行二次构建

#创建基础镜像
FROM centos:7
MAINTATNER "this is my apache "
RUN yum install -y gcc gcc-c++ make pcre pcre-devel expat-devel perl
ADD apr-1.6.2.tar.gz /opt/
ADD apr-util-1.6.0.tar.gz /opt/
ADD httpd-2.4.29.tar.bz2 /opt/
//解压到镜像的/opt中

RUN mv /opt/apr-1.6.2 /opt/httpd-2.4.29/srclib/apr && mv /opt/apr-util-1.6.0 /opt/httpd-2.4.29/srclib/apr-util &&\ 
cd /opt/httpd-2.4.29/ &&\

./configure --prefix=/usr/local/httpd --enable-so --enable-rewrite --enable-charset-lite --enable-cgi &&\
make -j 4 && make install
#二层构建
FROM centos:7
COPY --from=first /usr/local/httpd /usr/local/httpd
RUN yum -y install pcre pcre-devel expat-devel perl
EXPOSE 80
CMD ["/usr/local/httpd/bin/apachectl","-D","FOREGROUND"]
wq!

docker镜像创建 dockerfile_第6张图片

实战演练二----基于centos编译安装nginx

首先在创建dockerfile文件
Cd opt
Mkdir test
将ngin软件包拖入/opt/test

Vim dockerfile
FROM centos:7
创建基础镜像
MAINTAINER "this is my nginx "

RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make &&\
useradd -M -s /sbin/nologin nginx
在镜像上运行命令:安装依赖环境,并创建用户


ADD /nginx-1.22.0.tar.gz /opt/test
解压nginx到指定路径


RUN cd /opt/test/nginx-1.22.0 &&\
./configure --prefix=/usr/local/nginx --group=nginx --user=nginx --with-http_stub_status_module &&\
make && make install
进行编译安装


EXPOSE 80
指定端口

#ENTRYPOINT ["nginx"]
ENTRYPOINT [ "/usr/local/nginx/sbin/nginx", "-g", "daemon off;" ]
前台守护进程,让他不会一次运行就退出

Docker build -t nginx:centos .

.:执行当前目录的dockerfile

docker镜像创建 dockerfile_第7张图片

docker镜像创建 dockerfile_第8张图片

docker镜像创建 dockerfile_第9张图片

最后浏览器访问

docker镜像创建 dockerfile_第10张图片

########如果有网络报错提示########
[Warning] IPv4 forwarding is disabled. Networking will not work.
 
解决方法:
vim /etc/sysctl.conf
net.ipv4.ip_forward=1
 
sysctl -p
systemctl restart network
systemctl restart docker

总结

Dockerfile结构大致分为四个部分:基础镜像信息(用from指定)、维护者信息(maintainer、镜像操作指令和容器启动时执行指令。

  • 第一行必须使用FROM指令指明所基于的镜像名称;
  • 之后使用MAINTAINER 指令说明维护该镜像的用户信息;
  • 然后是镜像操作相关指令,如RUN指令/EXPOSE/ADD/ENV/ARG等等。每运行一条指令,都会给基础镜像添加新的一层。(多条命令可以使用 ; 或 && 合并成一条命令,减少镜像的层数)
  • 最后使用CMD或者ENTRYPOINT指令指定启动容器时要运行的命令操作。
     

你可能感兴趣的:(docker,容器,运维)