DockerFile构建过程

DockerFile构建过程

了解镜像加载原理

Docker镜像加载原理

UnionFS ( 联合文件系统)

UnionFS ( 联合文件系统): Union文件系统(UnionFS )是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtualfilesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

Docker镜像加载原理

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS.
**bootfs(boot file system)**主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs (root file system),在bootfs之上。包含的就是典型Linux系统中的/dev, /proc,/bin, letc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu , Centos等等。

Docker镜像的分层

1、初识Dockerfile
Dockerfile就是用来构建docker镜像的构建文件!命令脚本

通过脚本可以生成镜像,镜像是一层一层的,脚本是一个个的命令,每个命令都是一层
DockerFile构建过程_第1张图片

Docker镜像的创建

Docker镜像

  • 应用发布的标准格式
  • 支撑一个Docker容器的运行

Docker镜像的创建方法

  • 基于已有镜像创建
  • 基于本地模板创建
  • 基于Dockerfile创建

基本结构
Dockerfile 是一个文本格式的配置文件,用户可以使用 Dockerfile 快速创建自定义镜像。

Dockerfile 由一行行命令语句组成,并且支持以 # 开头的注释行。

Docker分为四部分:

  • 基础镜像信息
  • 维护者信息
  • 镜像操作指令
  • 容器启动时默认要执行的指令

DockerFile构建过程
dockerfile是用来构建dokcer镜像的文件!命令参数脚本!

构建步骤︰

1、编写一个dockerfile 文件
2、docker build构建成为一个镜像
3、docker run运行镜像
4、docker push发布镜像(DockerHub、阿里云镜像仓库!)

基础知识:

1、每个保留关键字(指令)都是必须是大写字母
2、执行从上到下顺序执行
3、#表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交

模板

创建目录,然后

# 第一行必须指定基于的基础镜像
FROM ubuntu

# 维护者信息
LABEL MAINTAINER='seancheng [email protected]'

# 镜像操作指令
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf

# 容器启动时默认要执行的指令
CMD /usr/sbin/nginx

注意:其中,一开始必须指明所基于的镜像名称,接下来一般会说明维护者信息。
后面则是镜像操作指令,例如RUN指令,RUN指令将对镜像执行跟随的命令。每运行一条RUN指令,镜像添加新的一层,并提交。
最后是CMD指令来指定运行容器时的操作指令。

Dockefile的指令

指令的一般格式为INSTRUCTION arguments,指令包括:

指令 含有
FROM 镜像 指定新镜像所基于的镜像,第一条指令必须为FROM指令,每创建一个镜像就需要一条FROM指令
MAINTAINER 名字 说明新镜像的维护人信息
RUN 命令 在所基于的镜像上执行命令
CMD [“要执行的命令”,“参数1”,“参数2”] 指令启动容器时要运行的命令或者脚本,Dockerfile只能由一条CMD命令,如果指定多条则只能最后一条被执行
EXPOSE 端口号 指定新镜像加载到Docker时要开启端口
ENV 环境变量 变量值 设置一个环境变量的值,会被后面的RUN使用
ADD 源文件/目录 目标文件/目录 将源文件复制到目标文件,源文件要与Dockerfile位于相同的目录中,或者是一个URL
COPY 源文件/目录 目标文件/目录 将本地主机上的文件/目录复制到目标地点,源文件/目录要与Dockerfile在相同目录中
VOLUME [“目录”] 在容器中创建一个挂载点
USER 用户名/UID 指定运行容器时的用户
WORKDIR 路径 为后续的RUN、CMD、ENTRYPOINT指定工作目录
ONBUILD 命令 指定生成的镜像作为一个基础镜像时所要运行的命令
HEALTHCHECK HEALTHCHECK
ENTRYPOINT 指定这个容器启动的时候要运行的命令,可以追加命令

格式为FROM 或FROM :。

第一条指令必须为FROM指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令(每个镜像一次)。

LABEL MAINTAINER
格式为LABEL MAINTAINER ,指定维护者信息

RUN
格式为RUN 或RUN [“executable”,“param1”,“param2”]。

前者将在shell终端中运行命令,即/bin/sh -c;后者则使用exec执行。指定使用其他终端可以通过第二种方式实现,例如:

RUN ["/bin/bash","-c","echo hello"]

每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \ 来换行,例如:

RUN echo "hello world\nhello tom" > /tmp/abc && \
    cat /tmp/abc

CMD
CMD支持三种格式:

CMD ["executable","param1","param2"]使用exec执行,推荐方式
CMD command param1 param2在/bin/sh中执行,提供给需要交互的应用
CMD ["param1","param2"]提供给ENTRYPOINT的默认参数

CMD用于指定启动容器时默认要执行的命令,每个Dockerfile只能有一条CMD命令。如果指定了多条命令,只有最后一条会被执行。

如果用户启动容器时指定了运行的命令,则会覆盖掉CMD指定的命令。

EXPOSE
格式为EXPOSE […]。
例如:

EXPOSE 22 80 8443

EXPOSE用于告诉Docker服务器容器暴露的端口号,供互联系统使用。

在启动容器时通过-P,Docker主机会自动分配一个端口转发到指定的端口;
使用-p则可以具体指定哪个本地端口映射过来。

ENV
格式为ENV 。指定一个环境变量,会被后续RUN指令使用,并在容器运行时保持。例如:

ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && ...
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH

ADD
格式为ADD 。

该命令将复制指定的到容器中的。其中可以是Dockerfile所在目录的一个相对路径(文件或目录);也可以是一个URL;还可以是一个tar文件(会自动解压为目录)。

COPY
格式为COPY 。

复制本地主机的(为Dockerfile所在目录的相对路径,文件或目录)为容器中的。目标路径不存在时会自动创建。
当使用本地目录为源目录时,推荐使用COPY。

ENTRYPOINT
ENTRYPOINT有两种格式:

  • ENTRYPOINT [“executable”,“param1”,“param2”]
  • ENTRYPOINT command param1 param2(在shell中执行)

配置容器启动后执行的命令,并且不可被docker run提供的参数覆盖。而且,如果在docker run的后面提供了参数,这些命令行参数会被当作参数传递给ENTRYPOINT指定的程序。

每个Dockerfile中只能有一个ENTRYPOINT,当指定多个ENTRYPOINT时,只有最后一个生效。

VOLUME
格式为VOLUME [“/data”]。

创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。

USER
格式为USER daemon。

指定运行容器时的用户名或UID,后续的RUN也会使用指定用户。

当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如:

RUN groupadd -r postgres && useradd -r -g postgres postgres

要临时获取管理员权限可以使用gosu,而不推荐sudo。如果不指定,容器默认是root运行。

WORKDIR
格式为WORKDIR /path/to/workdir。

为后续的RUN、CMD、ENTRYPOINT指令配置工作目录。
可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

则最终路径为/a/b/c。

ONBUILD
格式为ONBUILD [INSTRUCTION]。

配置当所创建的镜像作为其他镜像的基础镜像时,所执行的操作指令。

例如,Dockerfile使用如下的内容创建了镜像image-A

[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]

此时,如果基于image-A创建新的镜像时,新的Dockerfile中使用FROM image-A指定基础镜像时,会自动执行ONBUILD指令的内容,等价于在后面添加了两条指令。

FROM image-A

#Automatically run the following
ADD . /app/src
RUN /usr/local/bin/python-build --dir /app/src

使用ONBUILD指令的镜像,推荐在标签中注明,例如ruby:1.9-onbuild。

Dockefile实列

创建Dockerfile相应目录和下载源码包

[root@localhost ~]# mkdir httpd
[root@localhost ~]# cd httpd/
[root@localhost httpd]# touch Dockerfile
[root@localhost httpd]# mkdir files
[root@localhost httpd]# ls
Dockerfile  files 
[root@localhost httpd]# cd files/
#下载源码包
[root@localhost files]# wget
https://downloads.apache.org/apr/apr-1.7.0.tar.gz
https://downloads.apache.org/httpd/httpd-2.4.54.tar.gz
https://downloads.apache.org/apr/apr-util-1.6.1.tar.gz
[root@localhost files]# tree
.
├── apr-1.7.0.tar.gz
├── apr-util-1.6.1.tar.gz
└── httpd-2.4.54.tar.gz

0 directories, 3 files
[root@localhost files]# 

编写Dockerfile文件内容

[root@localhost httpd]# vim Dockerfile 
[root@localhost httpd]# cat Dockerfile 
FROM centos

LABEL MAINTAINER='GIN [email protected]'

ENV apache_version 2.4.54
ENV PATH /usr/local/apache/bin:$PATH

ADD files/apr-1.7.0.tar.gz /usr/src/
ADD files/apr-util-1.6.1.tar.gz /usr/src/
ADD files/httpd-${apache_version}.tar.gz /usr/src/

RUN   useradd -r -M -s /sbin/nologin    apache && \
   cd /etc/yum.repos.d/ && rm -rf * && \
   curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo && \
   sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo && \
   yum clean all && yum makecache && \
   yum -y install gcc gcc-c++ make   openssl-devel pcre-devel expat-devel libtool  && \
   cd /usr/src/apr-1.7.0  && \
   sed -i '/$RM "$cfgfile"/d'  configure  && \
   ./configure --prefix=/usr/local/apr && \
   make && make install  && \
   cd ../apr-util-1.6.1  && \
   ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr   && \
   make && make install  && \
   cd ../httpd-${apache_version}  && \
   ./configure --prefix=/usr/local/apache \
        --enable-so \
        --enable-ssl \
        --enable-cgi \
        --enable-rewrite \
        --with-zlib \
        --with-pcre \
        --with-apr=/usr/local/apr \
        --with-apr-util=/usr/local/apr-util/ \
        --enable-modules=most \
        --enable-mpms-shared=all \
        --with-mpm=prefork     && \
   make && make install    && \
   yum clean all && \
   yum  -y remove gcc gcc-c++ make && \
   rm -rf /tmp/* /usr/src/* 


WORKDIR /usr/local/apache
EXPOSE 80
CMD  ["-D","FOREGROUND"]
ENTRYPOINT  ["/usr/local/apache/bin/httpd"]

创建镜像

[root@localhost httpd]# podman build -t httpd:v1 .
....
Successfully tagged localhost/httpd:v1
26016b81b29be08c8b241a5af86a12368d4d7bf8cb9bfb6de13b8886762f8ea5
[root@localhost httpd]# podman images
REPOSITORY                 TAG         IMAGE ID      CREATED         SIZE
localhost/httpd            v1          26016b81b29b  30 seconds ago  405 MB

基于镜像创建容器进行测试

[root@localhost httpd]# podman ps
CONTAINER ID  IMAGE               COMMAND        CREATED         STATUS             PORTS                  NAMES
fdbd24ab9d4a  localhost/httpd:v1  -D FOREGROUND  59 seconds ago  Up 59 seconds ago  0.0.0.0:42701->80/tcp  web
[root@localhost httpd]# podman inspect -l | grep -i 'ipaddr'
            "IPAddress": "10.88.0.2",
                    "IPAddress": "10.88.0.2",
[root@localhost httpd]# curl 10.88.0.2
<html><body><h1>It works!</h1></body></html>
[root@localhost httpd]# 

Dockerfile上传镜像

登录Docker.io

[root@localhost httpd]# podman login docker.io
Username: kuilingwu
Password: 
Login Succeeded!
[root@localhost httpd]# 

上传Docker.io个人仓库

[root@localhost httpd]# podman tag localhost/httpd:v1 docker.io/kuilingwu/httpd:v2022.8.31
[root@localhost httpd]# podman images
REPOSITORY                 TAG         IMAGE ID      CREATED         SIZE
localhost/httpd            v1          26016b81b29b  8 minutes ago   405 MB
docker.io/kuilingwu/httpd  v2022.8.31  26016b81b29b  8 minutes ago   405 MB
[root@localhost httpd]# podman push docker.io/kuilingwu/httpd:v2022.8.31 
Getting image source signatures
Copying blob 5431d8710a4c done  
Copying blob 735aed9d027d done  
Copying blob 1bb3db1b8c12 done  
Copying blob e9b60e06a7d0 done  
Copying blob 2653d992f4ef skipped: already exists  
Copying config 26016b81b2 done  
Writing manifest to image destination
Storing signatures
[root@localhost httpd]# 

在个人仓库仓库是否上传成功

DockerFile构建过程_第2张图片

通过脚本创建镜像

编写entrypoint.sh脚本文件内容

[root@localhost httpd]# mkdir scripts
[root@localhost httpd]# ls
Dockerfile  files  scripts
[root@localhost httpd]# vim scripts/entrypoint.sh

#!/bin/bash

sed -i '/#ServerName/s/#//g' /usr/local/apache/conf/httpd.conf

exec "$@"

修改Dockerfile文件内容

[root@localhost httpd]# cd scripts/
[root@localhost scripts]# ls
entrypoint.sh
[root@localhost scripts]# chmod +x entrypoint.sh 
[root@localhost scripts]# ls
entrypoint.sh
[root@localhost httpd]# vim Dockerfile 

LABEL MAINTAINER='GIN [email protected]'

ENV apache_version 2.4.54
ENV PATH /usr/local/apache/bin:$PATH

ADD files/apr-1.7.0.tar.gz /usr/src/
ADD files/apr-util-1.6.1.tar.gz /usr/src/
ADD files/httpd-${apache_version}.tar.gz /usr/src/
ADD scripts/entrypoint.sh /   
#添加执行脚本

RUN   useradd -r -M -s /sbin/nologin    apache && \
   cd /etc/yum.repos.d/ && rm -rf * && \
   yum clean all && yum makecache && \
   yum -y install gcc gcc-c++ make   openssl-devel pcre-devel expat-devel libtool  && \
   cd /usr/src/apr-1.7.0  && \
   sed -i '/$RM "$cfgfile"/d'  configure  && \
   ./configure --prefix=/usr/local/apr && \
   make && make install  && \
   cd ../apr-util-1.6.1  && \
   ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr   && \
   make && make install  && \
   cd ../httpd-${apache_version}  && \
   ./configure --prefix=/usr/local/apache \
        --enable-so \
        --enable-ssl \
        --enable-cgi \
        --enable-rewrite \
        --with-zlib \
        --with-pcre \
        --with-apr=/usr/local/apr \
        --with-apr-util=/usr/local/apr-util/ \
        --enable-modules=most \
        --enable-mpms-shared=all \
        --with-mpm=prefork     && \
   make && make install    && \
   yum clean all && \
   yum  -y remove gcc gcc-c++ make && \
   rm -rf /tmp/* /usr/src/*

WORKDIR /usr/local/apache
EXPOSE 80
CMD  ["/usr/local/apache/bin/httpd","-D","FOREGROUND"]
ENTRYPOINT  ["/bin/bash","/entrypoint.sh"]

创建镜像

[root@localhost httpd]# podman build -t httpd:v2 .
.....
Successfully tagged localhost/httpd:v2
75755b5c0cb18b462b26e7aee574a466de89e8e8d2e3bae771cd7be12475a03f
[root@localhost httpd]# 
[root@localhost httpd]# podman images
REPOSITORY                 TAG         IMAGE ID      CREATED         SIZE
localhost/httpd            v2          75755b5c0cb1  33 seconds ago  405 MB

基于镜像创建容器进行测试

[root@localhost httpd]# podman run -d httpd:v2
3d3d603580bc1f911acf5413af5077383d79dd13c145018fd417a6da5150e94c
[root@localhost httpd]# podman ps
CONTAINER ID  IMAGE               COMMAND               CREATED        STATUS            PORTS       NAMES
3d3d603580bc  localhost/httpd:v2  /usr/local/apache...  8 seconds ago  Up 8 seconds ago              recursing_goldstine
[root@localhost httpd]# podman inspect -l | grep -i 'ipaddr'
            "IPAddress": "10.88.0.3",
                    "IPAddress": "10.88.0.3",
[root@localhost httpd]# curl 10.88.0.3
<html><body><h1>It works!</h1></body></html>
[root@localhost httpd]# podman inspect -l
        ...#查看执行方式   
            "Cmd": [
                "/usr/local/apache/bin/httpd",
                "-D",
                "FOREGROUND"
#另一种方法查看脚本是否可以执行                
[root@localhost httpd]# podman exec -itl /bin/bash
[root@3d3d603580bc apache]# pwd
/usr/local/apache
[root@3d3d603580bc apache]# cd /
[root@3d3d603580bc /]# ls
bin  entrypoint.sh  home  lib64       media  opt   root  sbin  sys  usr
dev  etc	    lib   lost+found  mnt    proc  run	 srv   tmp  var
#这里是会有颜色变化
[root@3d3d603580bc /]# ls --color
bin  entrypoint.sh  home  lib64       media  opt   root  sbin  sys  usr
dev  etc            lib   lost+found  mnt    proc  run   srv   tmp  var
[root@3d3d603580bc /]# 
#或者查看脚本的执行权限
[root@3d3d603580bc /]# ls -l /
total 4
lrwxrwxrwx.   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x.   5 root root 340 Aug 30 16:53 dev
-rwxr-xr-x.   1 root root  87 Aug 30 15:46 entrypoint.sh
drwxr-xr-x.   1 root root 236 Aug 30 16:51 etc

上传Docker.io个人仓库

[root@localhost httpd]# podman stop recursing_goldstine 
recursing_goldstine
[root@localhost httpd]# podman ps
CONTAINER ID  IMAGE       COMMAND     CREATED     STATUS      PORTS       NAMES
[root@localhost httpd]# podman tag localhost/httpd:v2 docker.io/kuilingwu/httpd:v2
[root@localhost httpd]# podman push docker.io/kuilingwu/httpd:v2
Getting image source signatures
Copying blob 23922a5fba9b done  
Copying blob 5d02ddf4632c done  
Copying blob 2653d992f4ef skipped: already exists  
Copying blob 735aed9d027d skipped: already exists  
Copying blob 1bb3db1b8c12 skipped: already exists  
Copying blob 5431d8710a4c skipped: already exists  
Copying config 75755b5c0c done  
Writing manifest to image destination
Storing signatures
[root@localhost httpd]# 

在个人仓库查看是否上传成功

DockerFile构建过程_第3张图片

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