您现在的位置是:首页 >技术杂谈 >容器(第四篇)创建镜像-dockerfile网站首页技术杂谈

容器(第四篇)创建镜像-dockerfile

只喜欢做实验@ 2024-09-19 12:01:04
简介容器(第四篇)创建镜像-dockerfile

 

创建镜像有三种方法,分别为基于已有镜像创建、基于本地模板创建以及基于Dockerfile创建。
 

基于现有镜像创建:

①先使用现有镜像创建容器   docker run 
②再进入容器进行内容更新   docker exec
③最后提交成新的镜像       docker commit 或 docker export + docker import

基于模板创建:

①可从本地容器导出模板文件  docker export
或从网上下载现成的模板文件   http://openvz.org/Download/template/precreated
②再将模板文件导入成镜像    docker import

dockerfile 构建:

构建的步骤:

①行必须使用 EROM 指令指明所基于的镜像名称;

②使用 MAINTAINER 指令说明维护该镜像的用户信息; 

③然后是镜像操作相关指令,如 RUN 指令。每运行一条指令,都会给基础镜像添加新的一层;

④最后使用 CMD 指令指定启动容器时要运行的命令操作。

dockerfile指令:
FROM  指定基础镜像,dockerfile构建镜像的第一个指令
MAINTAINER  指定镜像维护人信息
RUN 指定Linux命令,建议多个命令用 && 或 ; 串起来使用
ENV 设置镜像环境变量
EXPOSE 暴露容器端口
VOLUME 指定容器的匿名数据卷
ADD/COPY 复制本地文件/目录到镜像中
USER  指定容器运行用户
WORKDIR  指定镜像的工作目录
ARG 指定构建镜像时传入的参数       docker build --build-arg 变量=值
CMD/ENTRYPOINT  指定容器启动时执行的命令

ADD 和 COPY 的区别
COPY只能复制本地文件/目录到镜像中
ADD不光可以复制本地文件/目录到镜像中,还可以通过URL下载文件复制到镜像中,还能将本地tar压缩包解压后复制到镜像中。(URL下载和tar包解压特性不能一起使用)

ENTRYPOINT 和 CMD 的区别
ENTRYPOINT 指定的容器启动时运行命令优先级更高,如果 ENTRYPOINT 和 CMD 同时存在,那么 CMD 指定内容将作为 ENTRYPOINT 指定的命令的选项或参数去使用

容器启动时运行的命令优先级 
docker run --entrypoint 命令  >  镜像里的 ENTRYPOINT ["命令"] >  docker run ... 命令 >  镜像里的 CMD ["命令"]
 

如何缩小镜像的体积大小?
1)尽可能的使用小体积的基础镜像
2)尽可能减少Dockerfile文件中的指令数量
3)构建镜像步骤最后添加清空系统和应用程序的缓存的命令
4)使用多级(多阶段)构建  FROM  AS 别名   
                           COPY --from 别名

联合文件系统(UnionFS)
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。AUFS、OverlayFS 及 Devicemapper 都是一种 UnionFS

镜像加载原理
Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是UnionFS。

bootfs主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统。

在Docker镜像的最底层是bootfs,这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。

rootfs,在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。

我们可以理解成一开始内核里什么都没有,操作一个命令下载debian,这时就会在内核上面加了一层基础镜像;再安装一个emacs,会在基础镜像上叠加一层image;接着再安装一个apache,又会在images上面再叠加一层image。最后它们看起来就像一个文件系统即容器的rootfs。在Docker的体系里把这些rootfs叫做Docker的镜像。但是,此时的每一层rootfs都是read-only的,我们此时还不能对其进行操作。当我们创建一个容器,也就是将Docker镜像进行实例化,系统会在一层或是多层read-only的rootfs之上分配一层空的read-write的rootfs。

dockerfile实例:

①nginx

FROM centos:7
MAINTAINER this is nginx image <wl>
RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make
RUN useradd -M -s /sbin/nologin nginx
ADD nginx-1.12.0.tar.gz /usr/local/src/
WORKDIR /usr/local/src/nginx-1.12.0
RUN ./configure
--prefix=/usr/local/nginx
--user=nginx
--group=nginx
--with-http_stub_status_module && make && make install
ENV PATH /usr/local/nginx/sbin:$PATH
ADD nginx.conf /usr/local/nginx/conf/
ADD wordpress-4.9.4-zh_CN.tar.gz /usr/local/nginx/html/
RUN chmod 777 -R /usr/local/nginx/html/
EXPOSE 80
ENTRYPOINT [ "/usr/local/nginx/sbin/nginx", "-g", "daemon off;" ]

 

 ②mysql

FROM centos:7
MAINTAINER this is mysql image <wl>
RUN yum -y install gcc gcc-c++ ncurses ncurses-devel bison cmake make
ADD mysql-boost-5.7.20.tar.gz /usr/local/src/
WORKDIR /usr/local/src/mysql-5.7.20/
RUN cmake
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql
-DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock
-DSYSCONFDIR=/etc
-DSYSTEMD_PID_DIR=/usr/local/mysql
-DDEFAULT_CHARSET=utf8  
-DDEFAULT_COLLATION=utf8_general_ci
-DWITH_INNOBASE_STORAGE_ENGINE=1
-DWITH_ARCHIVE_STORAGE_ENGINE=1
-DWITH_BLACKHOLE_STORAGE_ENGINE=1
-DWITH_PERFSCHEMA_STORAGE_ENGINE=1
-DMYSQL_DATADIR=/usr/local/mysql/data
-DWITH_BOOST=boost
-DWITH_SYSTEMD=1 && make && make install
ADD my.cnf /etc/
ENV PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH
RUN useradd -M -s /sbin/nologin  mysql
RUN chown mysql:mysql /etc/my.cnf
RUN chown -R mysql:mysql /usr/local/mysql/
RUN /usr/local/mysql/bin/mysqld
--initialize-insecure
--user=mysql
--basedir=/usr/local/mysql
--datadir=/usr/local/mysql/data
EXPOSE 3306
CMD ["/usr/local/mysql/bin/mysqld"]

 ③php

FROM centos:7
MAINTAINER this is php image <wl>
RUN yum -y install gd
libjpeg libjpeg-devel
libpng libpng-devel
freetype freetype-devel
libxml2 libxml2-devel
zlib zlib-devel
curl curl-devel
openssl openssl-devel
gcc gcc-c++ make pcre-devel 
RUN useradd -M -s /sbin/nologin nginx
ADD php-7.1.10.tar.bz2 /usr/local/src/
WORKDIR /usr/local/src/php-7.1.10
RUN ./configure
--prefix=/usr/local/php
--with-mysql-sock=/usr/local/mysql/mysql.sock
--with-mysqli
--with-zlib
--with-curl
--with-gd
--with-jpeg-dir
--with-png-dir
--with-freetype-dir
--with-openssl
--enable-fpm
--enable-mbstring
--enable-xml
--enable-session
--enable-ftp
--enable-pdo
--enable-tokenizer
--enable-zip && make && make install
ENV PATH /usr/local/php/bin:/usr/local/php/sbin:$PATH
ADD php.ini    /usr/local/php/lib/
ADD php-fpm.conf /usr/local/php/etc/
ADD www.conf /usr/local/php/etc/php-fpm.d/
EXPOSE 9000
ENTRYPOINT [ "/usr/local/php/sbin/php-fpm", "-F" ]

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。