目录

  • 一、docker基本信息
  • 1、dockerfile的构成
  • 2、dockerfile操作指令
  • 3、镜像分层
  • 4、docker分层原理
  • 二、用dockerfile创建一个镜像
  • 1、创建Dockerfile文件
  • 2、运行Dockerfile文件


一、docker基本信息

1、dockerfile的构成

docker是一组由指令组成的文件,共有四个结构部分组成:

  1. 基础镜像层 #基础镜像信息一般是指linux的一些发行版本:centos等发行版
  2. 维护者信息 #申明开发者等信息的一个渠道
  3. 镜像操作指令 #镜像封装过程中执行的语句,常用的指令等会写在下面
  4. 容器启动时执行命令 #容器第一个启动的指令,例如:CMD

docker每行支持一个指令,每条指令可以携带多个参数,不同参数之间使用“ && ”隔开,也支持使用#开头的注释信息

2、dockerfile操作指令

指令

含义

FROM

开启一个新的镜像,必须写的一行指令

MAINTAINER名字

说明新镜像的维护人信息

RUN 命令

每个run都代表一条命令,每个run都是一个新的命令,在所基于的镜像上执行命令,并提交到新的镜像中

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

指定启动容器的时候,需要运行的命令,或者脚本,dockerfile只能执行一条CMD,如果指定多条,则是只鞥执行最后一条

EXPOES 端口号

指定新镜像记载到docker是要开启的端口

ENV 环境变量 变量值

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

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

将源文件复制到目标文件,源文件要与dockerfille位于相同的目录中,或者是一个url,同时也可以在复制的途中,对压缩包进行解压

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

将本地主机上的文件或者目录复制到目标地点,源文件或者目录要与dockerfile现在相同的目录中

VOLUME ["目录 "]

在容器中创建一个挂载点

USER 用户名/UID

指定运行容器的首用户

WORKDIR 路径

移动到指定的目录位置,后续的一些列操作都视为在该目录下操作

HEALTHECK

健康检查

上面这些就是在写封装容器镜像的时候,常用到的一些指令信息,每个指令都是代表一行,每一行都是代表的一层封装,层数越多,最终的镜像体积越大。可以合理的使用合并语句来减少封装的层数。例如一个RUN后面使用“ && ”跟随多个命令

3、镜像分层

容器的分层,大致可以分为四层:基础镜像、维护者信息、镜像操作指令、容器启动时执行命令。

在封装镜像的时候,可以对每步进行更改优化,即可是一个容器信息

例如:

容器层

CMD [“nginx”,"-g",“deamon off”]

RUN ./conflgure --preflx && make && make install

WORDIR /usr/local/nginx-1.12.0

ADD nginx-1.12.0.tar.gz /usr/local/

RUN yum install -y gcc gcc-c++ pcre pcre-devel make

基础镜像层 centos (FROM centos:7)

上面这个就是一个简易的容器镜像,将一个nginx编译后封装为镜像。就像是我上面所讲的,在封装镜像的时候,需要注意封装的层数。包括这点,还需要注意另外的几点

  1. dockerfile中每个指令都会创建一个新的镜像层
  2. 镜像层会被缓存和复用,每层的指令都会被缓存,可以被多次使用,直到最后容器层被调用
  3. 当容器dockerfile的指令修改了,复制的文件变化了,或者构建镜像是指定的变量不同了,对应的镜像层缓存就会失效,后面的指令,都会将这个失效的指令再次执行一次,确定新的指令的有效性
  4. 在某一层的镜像失效后,它在之后的镜像层的缓存都会失效
  5. 镜像层是不可变的,如果在某一层中添加一个文件,然后再下一层删除,则镜像中依然还有这个文件,因为在下一层删除的是这个文件的缓存,而不是文件本身。

4、docker分层原理

1、联合挂载——AUFS

联合挂载是为了实现将一个容器中的每个小镜像,整合在一起,将其暴露给容器层。可以实现将其提供给容器层,来进行操作

2、docker镜像分层

docker镜像位于bootfs之上

  1. 每一层镜像的下一层惊喜那个成为父镜像
  2. 每一层镜像成为base image(操作系统会环境镜像)
  3. 容器层,可读可写,在最顶层,容器层以下都是readonly

3、docker镜像分层每层的名称

  1. container 读写层,容器层
  2. images 只读
  3. base image 基础镜像
  4. bootfs+rootfs+aufs/overlay2+LXC(kernel)

bootfs:作用引导加载内核,系统刚启动的时候没回加载bootfs文件系统,在docker镜像中,最底层就是bootfs

LXC:是早起版本,支持docker实现容器化的插件

rootfs:rootfs是个性化的版本信息,含义是linux系统中的每个不同的版本信息。而bootfs是一种统一化的版本信息,含义是linux这个大类的操作系统,rootfs是在这个基础上的运行一些不同版本的操作系统,例如linux系统中的centos、Ubuntu等。

aufs:是一种联合挂载的功能,作用是实现将多个小镜像,连接在一起,将其暴露给容器

二、用dockerfile创建一个镜像

1、创建Dockerfile文件

FROM centos:7
ADD nginx-1.12.0.tar.gz /tmp
RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make &> /dev/null \
    && useradd -M -s /sbin/nologin nginx \
    && cd /tmp/nginx-1.12.0/ \
    && ./configure \
    --prefix=/usr/local/nginx \
    --user=nginx \
    --group=nginx \
    --with-http_stub_status_module &> /dev/null \
    && make &> /dev/null \
    && make install &> /dev/null \
    && ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/ \
    && rm -rf /tmp/nginx-1.12.0 \
    && cd /lib/systemd/system \
    && echo -e "[Unit] \
\nDescription=nginx \
\nAfter=network.target \
\n[Service] \
\nType=forking \
\nPIDFile=/usr/local/nginx/logs/nginx.pid \
\nExecStart=/usr/local/nginx/sbin/nginx \
\nExecReload=/usr/bin/kill -s HUP $MAINPID \
\nExecStop=/usr/bin/kill -s QUIT $MAINPID \
\nPrivateTmp=true \
\n[Install] \
\nWantedBy=multi-user.target" > nginx.service
ENV PATH $PATH:/usr/local/nginx/sbin
COPY nginx.conf /usr/local/nginx/conf/nginx.conf
WORKDIR /usr/local/nginx
EXPOSE 80
CMD ["nginx","-g","daemon off;"]

上面就是实际的编译nginx的一个过程,对编译过程进行了简略的优化,将多个相同指令的容器层使用“ && ”进行合并。

并且,为了方便,事先把nginx的配置文件配置好,复制一份放在了Dockerfile同目录中

tree
.
├── Dockerfile
├── nginx-1.12.0.tar.gz
├── nginx.conf
└── nginx.service

2、运行Dockerfile文件

docker build -t nginx:1.12 .

“ . ”代表的是运行当前目录下的Dockerfile文件,镜像名字为nginx:1.12

输入命令之后,等待编译完成,完成之后查看镜像

docker images
REPOSITORY                TAG       IMAGE ID       CREATED          SIZE
nginx                     1.12      9c6cfe218d1c   55 seconds ago   466MB

刚刚创建的镜像已经成功了,下面我们再运行一下试试

docker run -d -p 8081:80 nginx:1.12

docker PS -a
CONTAINER ID   IMAGE        COMMAND                  CREATED         STATUS         PORTS                                   NAMES
03d258d40fec   nginx:1.12   "nginx -g 'daemon of…"   7 seconds ago   Up 5 seconds   0.0.0.0:8081->80/tcp, :::8081->80/tcp   heuristic_wescoff

启动成功之后,再去网站或者别的地方测试一下是否正常运行

curl http://192.168.75.51:8081
#因为我们上面暴露的端口是8081,所以在连接的时候需要进行指定这个端口信息
显示结果如下:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

如果网站浏览是显示这个结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GV53Vt9i-1644143111540)(C:\Users\李洪坤\AppData\Roaming\Typora\typora-user-images\image-20220130193641105.png)]

有需要,也可以登录进容器内部,对容器进行一些管理

docker exec -it 03d258d40fec /bin/bash
#指定容器ID号,进行登录

到这里,dockerfile一些简单的原理就介绍完毕

```

如果网站浏览是显示这个结果

[外链图片转存中…(img-GV53Vt9i-1644143111540)]

有需要,也可以登录进容器内部,对容器进行一些管理

docker exec -it 03d258d40fec /bin/bash
#指定容器ID号,进行登录

到这里,dockerfile一些简单的原理就介绍完毕