关注我的个人博客:www.yaoxinlei.com

姚鑫磊的博客园

翻过一座山,山后一片海。

Docker File基础

Docker_File指令介绍

什么是Docker_Flie?

  • Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
  • Dockerfile中每条指令都是新建一层,一层一层叠加,最终组成我们想要的镜像

Docker镜像的分层

  • Dockerfile中的每个指令都会创建一个新的(临时)镜像层,镜像层将被缓存和复用,当Dockerfile的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效,某一层的镜像缓存失效之后,它之后的镜像层缓存都会失效,,镜像层是不可变的,如果在某一层中添加一个文件,然后在下一层中删除它,则镜像中依然会包含该文件
  • 容器(可读,可写层)
  • 服务本身镜像层(只读层,模板)
  • 依赖环境镜像层(只读层,模板)
  • 基础镜像镜像层(为以上的系统服务提供支持)
  • 底层内核层
    image

例如上面这个指令就会创建三层,每层只记录本层所做的更改,且这些成都是只读成。当启动一个容器,Docker会在最顶部添加读写层,一般都称该层为容器层。

image

每个容器都有自己独立的容器层,所以修改只会存在自己的容器层,容器之间并无影响,这种方式就可以实现不同容器共享一个镜像层。

image

为什么要采用分层结构?

  • 最大的好处就是共享资源,比如很多镜像都是从base镜像构建而来的,我们保存一份到磁盘后,就可以被所有镜像共享了

Docker_File指令介绍:

语法组成:

1 注释信息
2 指令---参数 [通常要大写|实质上不区分大小写]
3 顺序执行
4 第一个非注释行必须是from [基于那个基础镜像制作]  
5 需要一个专用目录[自己创建]
6 首字目必须大写---Dockerfile
7 制作镜像依赖到文件或者包组时,必须提前准备至专用目录下

.dockerignore file --每一行中定义一个忽略文件
    --创建在工作目录中
    例如:pam.d/su*
1.FROM指令:基础镜像,FROM命令必须是dockfile的首个命令
使用格式: 
FROM <镜像>:[tag]    
FROM <镜像>@digest[校验码]
当前主机没有此镜像时,会自动去官网HUB下载
2.LABEL指令:为镜像生成元数据标签信息
LABLE --替代MAINTANIER
具体使用:
LABLE maintainer="作者信息"
使用格式:
MAINTANIER "Yaoxinlei <xxx@163.com>"
3.USER指令:指定运行容器时的用户名或UID,后续RUN也会使用指定用户
默认情况下,container的运行身份为root
格式:
USER <UID>|<UserName>
需要注意的是<UID>可以为任意数字,但实践中其必须为/etc/passwd中某用户的有效
UID否则docker run命令将运行失败!

必须要在容器中的/etc/passwd文件中个存在
4.RUN指令:RUN命令是Dockfile执行命令的核心部分。它接受命令作为参数并用于创建镜像。每条RUN命令在当前镜像基础上执行,并且会提交一个新镜像层。
指令指定的程序时的用户名或UID
默认情况下,container的运行身份为root
格式:
USER <UID>|<UserName>
5.WORKDIR指令:设置CMD指明的命令的运行目录。为后续的RUN、CMD、ENTRYPOINT、ADD指令配置工作目录
每次只会影响这个指令后续的指令
ADD nginx-1.14.2.tar.gz /usr/local/src/ --不受影响
WORKDIR /usr/local/src/
ADD nginx-1.14.2.tar.gz ./ --受影响
6.ENV指令:容器启动的环境变量
调用格式:
$A 或 ${A}
ENV <key> <value>
ENV <key>=<value>
第一种格式中,key之后的所有内容均会被其视作<value>的组成部分
因此,一次只能设置一个变量!
第二种格式可用一次设置多个变量,每个变量为一个<key>=<value>
的键值对,如果<value>中包含空格,可以反斜线(\)进行转义
也可以通过对<value>加引号进行标识。另外,反斜线也可用于续航
定义多个变量时。建议使用第二种方式,以便在同一层中完成所有功能
具体用法:
ENV JAVA_HOME /usr/local/jdk
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/:$JRE_HOME/lib/
ENV PATH $PATH:$JAVA_HOME/bin/
ENV A /web/html
COPY index.html ${A:-/web/html}
在docker run 中传递变量:
docker run -e [list] 传变量值
如果在dockerfile中赋值变量后也能在docker run中继续赋值
docker run --name b1 --rm -e A=xx [镜像ID]
不会影响docker build 的过程!
printenv --输出环境变量信息
7.ARG指令:构建环境的环境变量
具体应用:
ARG auther=tim
LABLE maintainer=${auther}
docker build --build-arg auther=tom -t xxx ./
在dockerfile中存在的arg变量,如果在docker build 时也
设置了--build-arg变量,这样最终以命令行界面的变量值为
最终值!
8.COPY指令:复制文件到镜像中,格式: COPY 源路径 目标路径
文件要在Dockerfile工作目录
src 原文件
    --支持通配符
    --通常相对路径
dest 目标路径  
    --通常绝对路径

有空白字符隔开的字串需要用"",否则会被当做两个文件!

文件复制准则:
1 src必须是build上下文中的路径,不能是其父目录
2 如果src是目录,则其内部文件或子目录会被递归复制
   但src目录自身不会被复制
3 如果指定了多个src,或在src中使用了通配符,则dest必须是一个
  目录,且必须以/结尾
4 如果dest实现不存在,它将会被自动创建,这包括其父目录
9.ADD指令:拷复制文件到镜像中,格式: ADD 源路径 目标路径
支持URL路径----如果可以访问网络的话,会访问网络下载
到本地然后打包进镜像!

操作准则:
1 如果src为URL且dest不以/结尾,则src指定的文件将被下载并
直接被创建为dest;如果dest以/结尾,则文件名URL指定的文件
将被直接下载并保存为dest/filename

2 如果是压缩包会被解压,但通过URL路径获取到的tar文件不会被展开

3 如果src有多个,或其间接或直接使用了通配符,则dest必须是一个
以/结尾的目录路径,如果dest不以/结尾,则其被视为一个普通文件
src的内容将被直接写入到dest中!
10.CMD指令:容器运行时执行的默认命令
1. CMD ["executable","param1","param2"] --启动为ID为1的进程
具体实例:
CMD ["/bin/sh","-c","/bin/httpd","-f","-h /web/html]
2. CMD ["param1","param2"]
3. CMD command param1 param2 --直接运营为shell的子进程
param*=执行参数
例如第二种:
CMD ["nginx"]
docker run -it -p 8888:80 172.20.23.31/server1/nginx-base:v1 nginx
只能是双引号!

CMD ["param1","param2"]
 --此种用法用于为ENTRYPOINT指令提供默认参数

可用于执行脚本:
添加脚本:

ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh

RUN chmod +x /apps/tomcat/bin/run_tomcat.sh

RUN chown -R tomcat:tomcat /apps /data/tomcat

CMD ["/apps/tomcat/bin/run_tomcat.sh"] -- 引用脚本!
11.ENTRYPOINT指令:指定容器的“入口
类似CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一个单独
的可执行程序

与CND不同的是,由这个指令启动的程序不会被docker run 命令行指定的参数所覆盖
而且,这些命令行参数会被当做参数传递给ENTRYPOINT指定的程序

使用格式:
ENTRYPOINT <command>
ENTRYPOINT ["<executable>","<param1>","<param2>"]

docker run 命令传入的命令参数会覆盖CMD指定的内容并且附加到ENTRYPOINT
命令最后作为其参数使用

Dockerfile文件中也可以存在多个此指令,但仅有最后一个生效!

在docker run时,使用--entrypoint string选项传递的命令 可以覆盖Dockerfile中
定义的ENTRYPOINT指令

如何让Nginx配置文件接收参数

创建一个脚本:
#!/bin/bash
#
cat > /etc/nginx/conf.d/www.conf <<EOF
 server {
        server_name ${HOSTNAME};
        listen ${IP:-0.0.0.0}:${PORT:-80};
        root ${ROOT:-/web/html};
}
EOF
exec "$@"
chmod +x nginx-conf.sh

Dockerfile文件:

FROM xxx
ENV ROOT='/web/html/'
ADD index.html ${ROOT}
ADD nginx-conf.sh /bin/nginx-conf.sh
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/nginx-conf.sh"]
docker run --name b1 --rm -P -e "PORT=8080" [镜像ID]

注意:必须使用双引号!!!
12.HEALTHCHECK指令:容器健康状态检查
健康状态监测
HEALTHCHECK NONE --不要做监测

常用选项:
--interval=DURATION 默认30秒 --多长时间监测一次
--timeout=DURATION 默认30秒 --监测超时时间
--start-period=DURATION --当docker容器启动后,延迟多长时间才健康检查
默认0秒
--retries=N 默认3次
默认检查多少次在认为失败

响应值:
0--成功
1--失败
2--自定义

应用示例:
HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ || exit1

Dockerfile中应用:
HEALTHCHECK --start-period=3s CMD wget -O - -q http://{IP:-0.0.0.0}:${PORT:-80}/

也可以在docker run中定义:
--health-cmd string            
--health-interval duration      
--health-retries int           
--health-start-period duration  
--health-timeout duration   

posted @ 2022-01-05 23:58  姚鑫磊  阅读(79)  评论(0编辑  收藏  举报
区顶部