【docker】之dockerfile镜像制作

docker容器的隔离性 要比虚拟机弱,因为共享内核

怎么打包制作镜像:

  • 手动打包:先启动一个基础镜像,系统类的比如centos、ubuntu等。进到镜像中,一步步修改镜像,直到达到你需要的。但是这样会存在一个问题:黑箱操作!!!就是无法追溯!!!
  • 自动打包:dockerfile 类似跑脚本。优点是可重复使用、并且可以保证环境一致。 run cmd add from 这些命令

1、镜像制作和管理

Dockerfile 一般存放位置:/data/dockerfile/system/centos/centos7/

默认文件名称:Dockerfile 如果想要修改为别的名称,需要使用-f 选项

  • commit
  • build

基于容器手动制作镜像步骤具体如下:

  1. 下载一个系统的官方基础镜像,如: CentOS 或 Ubuntu

  2. 基于基础镜像启动一个容器,并进入到容器

  3. 在容器里面做配置操作

    • 安装基础命令
    • 配置运行环境
    • 安装服务和配置服务
    • 放业务程序代码
  4. 提交为一个新镜像 docker commit。将修改过的容器重新打包为一个新的镜像

  5. 基于自己的的镜像创建容器并测试访问

2、docker commit 手动构建镜像

不建议使用,可能会存在黑箱操作。

docker commit 格式:

js 复制代码
 docker commit [选项] 容器id 镜像名称:tag
选项 含义
-a 描述信息、作者,标注镜像的一些基本信息
-c 调用dockerfile的指令,比如CMD指令
-m 备注,提交信息
-p 暂停 pause
-h 主站点

示例:基于 busybox 制作httpd镜像⭐

js 复制代码
 [root@7-3 ~]# docker run -it --name aaa1 busybox
 / # mkdir -p /data/html
 / # echo "hello wxy" > /data/html/index.html
 / # cat /data/html/index.html
 hello wxy
 ​
 [root@7-3 ~]# docker ps -a
 CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS                      PORTS     NAMES
 94eb16bf1036   busybox   "sh"      51 minutes ago   Up 51 minutes                         aaa1
 f9559d24deb1   centos    "bash"    2 hours ago      Exited (0) 52 minutes ago             thirsty_mclean
 [root@7-3 ~]# docker commit -a "cxk" -c "CMD /bin/httpd -f -h /data/html" -c "EXPOSE 80" 94eb16bf1036 busybox-httpd:v1.0     //制作一个镜像,制作的作者是cxk,要执行的命令是在httpd软件中,前台运行,定义了主站点,容器中要使用80端口,对应的容器id,并且对容器进行重新命名和改标签
 -a是作者   -c执行的命令  -f前台运行  -h主站点   EXPOSE暴露端口⭐
 sha256:0cd460acb7dbd1e8f56dd2556bea6ce6062fb71a009b1b78f2facfd9e36ca89a
 [root@7-3 ~]# docker run -d -P busybox-httpd:v1.0   //大P是随机端口
 8a9328b1b39500434bf1440d76a0d93e3eb701e6cf2c67acbd26290163824ef1
 [root@7-3 ~]# docker port 8a9
 80/tcp -> 0.0.0.0:32768
 80/tcp -> [::]:32768
 [root@7-3 ~]# curl 127.0.0.1:32768
 hello wxy

3、docker build 自动构建镜像

利用DockerFile 文件 执行docker build自动构建镜像

build是把容器变成镜像。

docker build选项 含义
-f 指定运行的文件夹。默认是Dockerfile。如果不想命名为Dockerfile,那么修改的话需要加上-f指令。注意Dockerfile的D是大写!!!
-t 给镜像打标签, 比如 c7:v1
--no-cache 不使用之前构件中创建的缓存

3.1 Dockfile 使用流程

  • Dockerfile的指令,通过dockerd 翻译成linux能识别的指令
  • 然后dockerd再给翻译后的指令,发送给容器

3.2 Dockerfile的分层结构

  • 基础层
  • 系统层
  • 应用层
  • 数据层

3.3 Dockerfile 文件格式

Dockerfile 是一个有特定语法格式的文本文件

dockerfile 官方说明: docs.docker.com/engine/refe...

帮助: man 5 dockerfile

<math xmlns="http://www.w3.org/1998/Math/MathML"> D o c k e r f i l e 文件说明: \color {red}{Dockerfile 文件说明:} </math>Dockerfile文件说明:

  • 每一行以Dockerfile的指令开头,指令不区分大小写,但是一般使用大写

  • 使用 # 开始作为注释

  • 每一行只支持一条指令,每条指令可以携带多个参数

    格式:指令+参数

  • 指令按文件的顺序从上至下进行执行

  • 每个指令的执行会生成一个新的镜像层,为了减少分层和镜像大小,尽可能将多条指令合并成一条指令

  • 制作镜像一般可能需要反复多次,每次执行dockfile都按顺序执行,从头开始,已经执行过的指令已经缓存,不需要再执行,如果后续有一行新的指令没执行过,其往后的指令将会重新执行,所以为加速镜像制作,将最常变化的内容放下dockerfile的文件的后面

3.4 Dockerfile 相关指令⭐⭐⭐⭐⭐

dockerfile 文件中的常见指令:

指令 含义
FROM 指定基础镜像,就是基础镜像从哪来:先本地、再官方仓库
LABEL(MAINTAINER) 标签(不写就是latest 最新) 说明信息
RUN(command命令) 执行命令。 上下指令之间是隔离的,如果想放在一条,可以使用&&
ENV(key=value) 指定环境变量(可以设置多条)
COPY 复制文件
ADD(源地址到目的地址) 复制文件并解压。 ADDA是更高级的COPY指令
CMD 容器启动命令。 如果后面有ENTRYPOINT,那么会作为参数传递给ENTRYPOINT
ENTRYPOINT 入口点。功能类似于CMD, 配置容器启动后执行的命令及参数
ARG 构建参数
VOLUME 设置容器的挂载卷
WORKDIR 设置工作目录
EXPOSE 暴露端口

小拓展:RUN命令如何优化?

尽量使用连接符,将多个命令合并为一个命令。

例如:RUN cd /opt && touch 123

常见的连接符号有:

  • && :且
  • || :或,相当于判断。如果前一个命令失败,才会执行后面的命令
  • 分号(;):按顺序执行,无论第一个成不成功,都会执行下一个。

示例:创建Dockerfile

js 复制代码
 [root@7-2 data]# mkdir -p /data/dockerfile/system/centos/centos7/
 [root@7-2 data]# cd /data/dockerfile/system/centos/centos7/
 [root@7-2 centos7]# vim Dockerfile
 FROM centos:7
 LABEL author="cxk"
       version="1.0"
       description="ctrl"
 RUN mkdir /xyz
 ENV name=cxk  class=123
 ​
 [root@7-2 centos7]# docker run -it centos:7 bash
 [root@ed325d3ef29c /]# exit
 ​
 [root@7-2 centos7]# docker build -t centos:7 .    //制作镜像,并打标签,注意.点代表当前目录

3.4.1 FROM 指定基础镜像

FROM 就是指定基础镜像,此指令通常必需放在Dockerfile文件第一个非注释行。后续的指令都是运行于此基准镜像所提供的运行环境

基础镜像可以是任何可用镜像文件,默认情况下,docker build会在docker主机上查找指定的镜像文件,在其不存在时,则会从Docker Hub Registry上拉取所需的镜像文件.如果找不到指定的镜像文件,docker build会返回一个错误信息

示例:

js 复制代码
 [root@7-2 ~]# cd /data/dockerfile/system/centos/centos7/
 [root@7-2 centos7]# vim Dockerfile
 FROM centos:7

3.4.2 LABEL 指定标签

LABEL: 说明信息

可以指定镜像元数据,如: 镜像作者、版本等

LABEL=MAINTAINER,MAINTAINER是前期使用的,后期都改成LABEL了。

示例:

js 复制代码
 [root@7-2 ~]# cd /data/dockerfile/system/centos/centos7/
 [root@7-2 centos7]# vim Dockerfile
 FROM centos:7
 LABEL author="cxk"\       //作者
       version="1.0"\      //版本
       description="ctrl"  //描述

3.4.3 RUN 执行命令⭐⭐⭐

每个RUN都是独立运行的 和前一个RUN无关

  • 格式一:这种更方便
js 复制代码
 RUN <命令>    //后面直接加命令
  • 格式二:
js 复制代码
 RUN ["可执行文件", "参数1", "参数2"]    //注意:是双引号,不能是单引号

3.4.4 ENV 指定环境变量

ENV 可以定义环境变量和值,会被后续指令(如:ENV,ADD,COPY,RUN等)通过$KEY$(KEY)进行引用,并在容器运行时保持

js 复制代码
 #变量赋值格式1
 ENV <key> <value>    //键+值。此格式只能对一个key赋值,<key>之后的所有内容均会被视作其<va1ue>的组成部分
 ​
 #变量赋值格式2
 ENV <key1>=<value1> <key2>=<va1ue2>\   //键=值,多个用空格隔开。此格式可以支持多个key赋值,定义多个变最建议使用,减少镜像层
  <key3>=xvalue3> ...
 ​
 #变量支持高级赋值方式:
 ${key:+word}
 ${key:-word}   //用的比较多,如果$key变量原来有值,就用原来的值;如果原来没值,就用word的值

-e的优先级比 env高

3.4.5 COPY 复制文本

复制本地(宿主机)的文件,到容器里面

js 复制代码
 COPY [--chown=<user>:<group>] <源地址>... <目标地址>
 COPY [--chown=<user>:<group>] ["<源地址>",... "<目标地址>"]   //路径中有空白字符时,建议使用此格式

说明:⭐

  • 可以是多个,可以使用通配符,通配符规则满足Go的filepath.Match 规则filepath.Match 参考链接: golang.org/pkg/path/fi...
  • 复制的文件,必须和绝对路径/data/dockerfile/system/centos/centos7/Dockerfile文件在同一级或者是下一级,绝对不能复制其父目录中的文件
  • 如果是目录,则其内部文件或子目录会被递归复制,但目录自身不会被复制
  • 文件夹必须要以/结尾。 如果指定了多个, 或在中使用了通配符,则必须是一个目录,且必须以 / 结尾,不加/不会报错,但是类似于改名!!!
  • 可以是绝对路径或者是 WORKDIR 指定的相对路径
  • 使用 COPY 指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等
  • 如果事先不存在,它将会被自动创建,这包括其父目录路径,即递归创建目录

示例1:源地址和目标地址

js 复制代码
 [root@7-2 ~]# cd /data/dockerfile/system/centos/centos7/
 [root@7-2 centos7]# vim Dockerfile
 FROM centos:7
 LABEL author="cxk"\
       version="1.0"\
       description="ctrl"
 #RUN mkdir /xyz
 COPY 123 /cxk/     //从源地址123,拷到目标地址/cxk,没有目标地址,会自动新建。
 ​
 [root@7-2 centos7]# docker build -t centos:7 .   //制作镜像
 [root@7-2 centos7]# docker run -it centos:7      //进入到容器
 [root@5bcce081b43c /]# cd cxk     //验证
 [root@5bcce081b43c cxk]# ls
 123   //拷贝成功!

示例2:在原基础上,指定权限--chown=属主:属组

js 复制代码
 [root@7-2 ~]# cd /data/dockerfile/system/centos/centos7/
 [root@7-2 centos7]# vim Dockerfile
 FROM centos:7
 LABEL author="cxk"\
       version="1.0"\
       description="ctrl"
 RUN useradd zs       //新建用户zs
 COPY --chown=zs:zs 123 /cxk/    //拷贝的文件,定义属主和属组
 [root@7-2 centos7]# docker build -t centos:7 .     //制作镜像
 [root@7-2 centos7]# docker run -it centos:7
 [root@a09277a40aa6 /]# cd /cxk
 [root@a09277a40aa6 cxk]# ll
 total 0
 -rw-r--r-- 1 zs zs 0 Aug  4 03:23 123    //权限已经变化!
 ​

过程可以总结为三步:

  • 创建Dockerfile
  • 制作镜像。格式: docker build -t 镜像名称(尽量不要重名) 文件夹路径
  • 进入到容器。格式:docker run -it 制作镜像的名称
  • 验证

3.4.6 ADD 复制文件并解压⭐⭐⭐

ADD是 更强大的COPY命令!!!

可以自动解压缩,但是系统中要有相应的解压缩工具!!!比如tar gz等

该命令可认为是增强版的COPY,不仅支持COPY,还支持自动解缩。可以将复制指定的 到容器中的

js 复制代码
 ADD [--chown=<user>:<group>] <源地址>... <目的地址>
 ADD [--chown=<user>:<group>] ["<源地址>",... "<目的地址>"]

说明:

  • 可以是Dockerfile所在目录的一个相对路径;也可是一个 URL;还可是一个 tar 文件(自动解压)
  • 可以是绝对路径或者是 WORKDIR 指定的相对路径
  • 如果是目录,只复制目录中的内容,而非目录本身
  • 如果是一个 URL ,下载后的文件权限自动设置为 600
  • 如果为URL且不以/结尾,则指定的文件将被下载并直接被创建为,如果以 / 结尾,则文件名URL指定的文件将被直接下载并保存为/< filename>
  • 如果是一个本地文件系统上的打包文件,如: gz, bz2 ,xz ,它将被解包 ,其行为类似于"tar -x"命令,但是通过URL获取到的tar文件将不会自动展开
  • 如果有多个,或其间接或直接使用了通配符,则必须是一个以/结尾的目录路径;如果不以/结尾,则其被视作一个普通文件,的内容将被直接写入到

示例:

js 复制代码
 [root@7-2 centos7]# tar tf abc.tar.gz   //查看压缩包里的内容
 index.html
 [root@7-2 centos7]# vim Dockerfile 
 [root@7-2 centos7]# docker build -t centos:7-4 .
 ​
 FROM centos:7
 LABEL author="cxk"\
       version="1.0"\
       description="ctrl"
 #RUN mkdir /xyz
 #COPY 456  123 /lyf/
 ADD abc.tar.gz /fcc/    //压缩包
 [root@7-2 centos7]# docker build -t centos:7-4 .
 [root@7-2 centos7]# docker run -it centos:7-4
 [root@2c3ca6b036fa /]# cd fcc
 [root@2c3ca6b036fa fcc]# ls
 index.html     //自动解压缩!

3.4.7 CMD 容器启动命令⭐⭐⭐

容器要想持久运行,必须有前台执行的命令程序。

一个容器中需要持续运行的进程一般只有一个,CMD 用来指定启动容器时默认执行的一个命令,且其运行结束后,容器也会停止,所以一般CMD 指定的命令为持续运行且为前台命令

说明:

  • 如果docker run没有指定任何的执行命令,或者dockerfile里面也没有ENTRYPOINT,那么开启容器时就会使用执行CMD指定的默认的命令
  • 前面介绍过的 RUN 命令是在构建镜像进执行的命令,注意二者的不同之处
  • 每个 Dockerfile 只能有一条 CMD 命令。如指定了多条,只有最后一条被执行
  • 如果用户启动容器时用 docker run xxx 指定运行的命令,则会覆盖 CMD 指定的命令

语法格式:

js 复制代码
 `格式1:`
 # 在 /bin/sh 中执行,提供给需要交互的应用;此种形式支持环境变量
 CMD 命令  参数1  参数2
 ​
 `格式2:`
 # 使用 exec 执行,推荐方式,第一个参数必须是命令的全路径,此种形式不支持环境变量
 CMD ["命令","参数1","参数2"] 

示例1:

js 复制代码
 [root@7-2 centos7]# vim Dockerfile 
 FROM centos:7
 LABEL author="cxk"\
       version="1.0"\
       description="ctrl"
 #RUN mkdir /xyz
 #COPY 456  123 /lyf/
 #ADD abc.tar.gz /fcc/
 CMD tail -f /etc/passwd
 [root@7-2 centos7]# docker build -t centod:7-5 .
 [root@7-2 centos7]# docker run -d centod:7-5  //不用-it交互进入,直接后台运行
 [root@7-2 centos7]# docker ps -a
 CONTAINER ID   IMAGE                COMMAND                   CREATED          STATUS                         PORTS                                     NAMES
 180f96549621   centod:7-5           "/bin/sh -c 'tail -f..."   9 seconds ago    Up 7 seconds       //后台运行,容器也不会自动退出。因为CMD里有前台运行的命令

示例2:第二种,格式稍微麻烦一些。

js 复制代码
 CMD  ["tail","-f","/etc/hosts"]
 CMD  ["nginx", "-g", "daemon off;"]

3.4.8 ENTRYPOINT 入口点⭐⭐⭐

功能类似于CMD,配置容器启动后执行的命令及参数

格式:

js 复制代码
 # 使用 exec 执行
 ENTRYPOINT ["executable", "param1", "param2"]
 ​
 # shell中执行
 ENTRYPOINT command param1 param2

说明:

  • ENTRYPOINT 不能被 docker run 提供的参数覆盖,而是追加,即如果docker run 命令有参数,那么参数全部都会作为ENTRYPOINT的参数
  • 如果ENTRYPOINT和 CMD同时存在,那么CMD的内容就作为参数传给ENTRYPOINT。
  • 如果docker run 后面有额外参数,同时Dockerfile中即有CMD也有ENTRYPOINT,那么docker run后面的参数覆盖掉CMD参数内容,最终作为ENTRYPOINT的参数
  • 可以通过docker run --entrypoint string 参数在运行时替换,注意string不要加空格
  • 使用CMD要在运行时重新写命令本身,然后在后面才能追加运行参数,ENTRYPOINT则可以运行时无需重写命令就可以直接接受新参数
  • 每个 Dockerfile 中只能有一个 ENTRYPOINT或CMD,当指定多个时,只有最后一个生效

示例1:CMD为 ENTRYPOINT传参

js 复制代码
 [root@7-2 centos7]# vim Dockerfile
 CMD ["world"]
 ENTRYPOINT ["echo","hello"]
 [root@7-2 centos7]# docker build -t centos:7-6 .
 [root@7-2 centos7]# docker run -it centos:7-6
 hello world     //CMD追加到了ENTRYPOINT后面。这是一次性命令

示例2:安装nginx软件

  1. 首先,先准备清华源
js 复制代码
 [root@7-2 centos7]# vim qh.repo
 [base]
 name=CentOS-$releasever - Base - mirrors.aliyun.com
 failovermethod=priority
 baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos-vault/7.9.2009/os/x86_64/
 gpgcheck=0
 gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7

拓展:如果清华源解析有问题,可能是快照的原因,建议重启docker软件

js 复制代码
 systemctl restart docker
  1. 再准备软件安装包
js 复制代码
 ***将安装包nginx-1.22.0.tar.gz放入/data/dockerfile/system/centos/centos7/绝对路径下***
  1. 准备Dockerfile文件
js 复制代码
 [root@7-2 centos7]# vim Dockerfile
 FROM  centos:7
 LABEL author="cxk"  \
       version="1.0"       \
       description="test"
 ​
 RUN   rm -rf  /etc/yum.repos.d
 ADD   qh.repo /etc/yum.repos.d/
 RUN   yum -y install gcc gcc-c++ make automake pcre pcre-devel zlib  zlib-devel openssl openssl-devel wget net-tools vim
 ADD   nginx-1.22.0.tar.gz   /usr/local/src
 RUN   cd  /usr/local/src/nginx-1.22.0  && ./configure  --prefix=/apps/nginx/  && make   &&  make install
 VOLUME [ "/apps/nginx/html" ]
 COPY  index.html    /apps/nginx/html
 CMD   ["-g","daemon off;"]
 EXPOSE 80 443
 ENTRYPOINT   ["/apps/nginx/sbin/nginx"]
 ​
 ​
 解释:
 FROM  centos:7
 LABEL author="cxk"  \
       version="1.0"       \
       description="test"
 ​
 RUN   rm -rf  /etc/yum.repos.d    //删除原来的网络源
 ADD   qh.repo /etc/yum.repos.d/   //使用清华源,需要自己建立
 RUN   yum -y install gcc gcc-c++ make automake pcre pcre-devel zlib  zlib-devel openssl openssl-devel wget net-tools vim
 ADD   nginx-1.22.0.tar.gz   /usr/local/src
 RUN   cd  /usr/local/src/nginx-1.22.0  && ./configure  --prefix=/apps/nginx/  && make   &&  make install
 VOLUME [ "/apps/nginx/html" ]
 COPY  index.html    /apps/nginx/html
 CMD   ["-g","daemon off;"]       //作为参数传给下面的ENTRYPOINT
 EXPOSE 80 443   //暴露多个端口
 ENTRYPOINT   ["/apps/nginx/sbin/nginx"]    //容器的默认进口
  1. 制作镜像并验证
js 复制代码
 [root@7-2 centos7]# docker build -t centos:7 .
 [root@7-2 centos7]# docker run -d -P --name nginx1 centos:7 
 [root@7-2 centos7]# docker port nginx1   //查看nginx1对应的端口
 80/tcp -> 0.0.0.0:32771
 80/tcp -> [::]:32771
 443/tcp -> 0.0.0.0:32770
 443/tcp -> [::]:32770
 [root@7-2 centos7]# curl 192.168.125.120:32771    //访问80端口对应的,如果使用443对应的真机端口会报错!!!因为我们没有指定!!!
 abc123
  1. 进入到容器中
js 复制代码
 [root@7-2 centos7]# docker exec -it nginx1 bash   //进入到nginx1的容器中
 [root@1511a756e91e /]# cd /apps/nginx
 [root@1511a756e91e nginx]# ls
 client_body_temp  conf  fastcgi_temp  html  logs  proxy_temp  sbin  scgi_temp  uwsgi_temp
 [root@1511a756e91e nginx]# cd html
 [root@1511a756e91e html]# ls
 50x.html  index.html
 [root@1511a756e91e html]# touch aa    //新建文件aa
 [root@1511a756e91e html]# ls
 50x.html  aa  index.html     //现在,容器内和真机是关联起来的。使用的是宿主机的目录
  1. 查看对应的宿主机中的位置:
js 复制代码
 [root@7-2 centos7]# docker inspect nginx1
  "Mounts": [
             {
                 "Type": "volume",
                 "Name": "eb7b4181ff072891bd614167eeda01ab8f7b4b283ba9d1ce1b824a6951e3ab48",
                 "Source": "/var/lib/docker/volumes/eb7b4181ff072891bd614167eeda01ab8f7b4b283ba9d1ce1b824a6951e3ab48/_data",      //容器中的内容,对应宿主机中这个位置!!!
                 "Destination": "/apps/nginx/html",
                 "Driver": "local",
                 "Mode": "",
                 "RW": true,
                 "Propagation": ""
             }
         ],
js 复制代码
 [root@7-2 centos7]# cd /var/lib/docker/volumes/eb7b4181ff072891bd614167eeda01ab8f7b4b283ba9d1ce1b824a6951e3ab48/_data
 [root@7-2 _data]# ls
 50x.html  aa  index.html     //在宿主机中也可以看到,刚才在容器中新建的文件aa
 [root@7-2 _data]# touch test    //在宿主机新建test文件夹
 ​
 [root@7-2 centos7]# docker exec -it nginx1 bash   //再进入容器
 [root@1511a756e91e /]# cd /apps/nginx/html
 [root@1511a756e91e html]# ls
 50x.html  aa  index.html  test   //容器中也会看到,宿主机中的文件夹。相当于真机和容器进行了关联。
 ​
 ​

3.4.9 ARG 构建参数

也是唯一 一个可以在FROM前面的指令。

ARG指令在build 阶段指定变量,和ENV不同的是,容器运行时不会存在这些环境变量

js 复制代码
 ARG <name>[=<default value>]

如果和ENV同名,ENV覆盖ARG变量

3.4.10 VOLUME 设置容器的挂载卷⭐⭐⭐

在容器中创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等,一般会将宿主机上的目录挂载至VOLUME 指令指定的容器目录。即使容器后期被删除,此宿主机的目录仍会保留,从而实现容器数据的持久保存。

语法:

js 复制代码
 VOLUME ["<容器内路径1>", "<容器内路径2>"...]

注意:

  • Dockerfile中的VOLUME实现的是匿名数据卷,无法指定宿主机路径和容器目录的挂载关系
  • 通过docker rm -fv <容器ID>可以删除容器的同时删除VOLUME指定的卷

宿主机目录为:

js 复制代码
 /var/lib/docker/volumes/匿名卷id/_data

拓展:怎么查看容器中的目录对应在宿主机中的位置:

js 复制代码
 docker inspect +容器名称

示例:

js 复制代码
 [root@7-2 centos7]# vim Dockerfile 
 ​
 FROM  centos:7
 LABEL author="wyf"  \
       version="1.0"       \
       description="test"
 VOLUME ["/data","/data1"]    //注意:/data和/data1是容器中的文件夹。/data和/data1没有的话,会自动创建
 ​
 [root@7-2 centos7]# docker build -t centos:7-1 .
 [root@7-2 centos7]# docker run -it centos:7-1
 [root@18a89e4a2463 /]# cd /data1    
 [root@18a89e4a2463 data1]# touch 13    //在/data1目录里新建文件13
 [root@18a89e4a2463 data1]# cd /data
 [root@18a89e4a2463 data]# touch 24    //在/data目录里新建文件24
 ​
 [root@7-2 _data]# docker inspect 18a89e4a2463   //查看详细信息

对应的真机里,会有两个挂载信息:

js 复制代码
 [root@7-2 _data]# cd /var/lib/docker/volumes/9bd772b3e42a77fe6eba907094bd089026bdf44c4359a7088fad6c6a5cbb446e/_data
 [root@7-2 _data]# ls
 13
 ​
 [root@7-2 _data]# cd /var/lib/docker/volumes/04da271cbebd94a6336a509568a9a764d251e47fefc586d61262d5739744bc1a/_data
 [root@7-2 _data]# ls
 24
 ​
 [root@7-2 _data]# docker rm -fv 18a89e4a2463    //加-v选项,会同时删除真机和容器里的内容

3.4.11 WORKDIR 指定工作目录

为后续的 RUN、CMD、ENTRYPOINT 指令配置工作目录,当容器运行后,进入容器内WORKDIR指定的默认目录

  • 如果 RUN、CMD等的指令中是相对路径,那么就会使用WORKDIR 指定工作目录
  • 如果 RUN、CMD等的指令中是绝对路径,那么就会使用指令自己本身的路径。
js 复制代码
 [root@7-2 ~]# cd /data/dockerfile/system/centos/centos7/
 [root@7-2 centos7]# vim Dockerfile
 FROM centos:7
 LABEL author="cxk"\
       version="1.0"\
       description="ctrl"
 #RUN mkdir /xyz
 WORKDIR /opt
 RUN cd /mnt && touch 2024
 RUN touch 0804
 ​
 [root@7-2 centos7]# docker build -t centos:7-1 .    //创建新的镜像
 ​
 验证:
 [root@7-2 centos7]# docker run -it --rm centos:7-1 bash    //进入到容器
 [root@d549a775360a opt]# cd /opt
 [root@d549a775360a opt]# ls
 0804       //不是绝对路径,就会被WORKDIR影响
 [root@d549a775360a opt]# cd /mnt
 [root@d549a775360a mnt]# ls
 2024        //是绝对路径,那么绝对路径的优先级高

3.4.12 EXPOSE 暴露端口

指定服务端的容器需要对外暴露(监听)的端口号,以实现容器与外部通信。EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会真正暴露端口,即不会自动在宿主进行端口映射因此,在启动容器时需要通过 -P 或-p ,Docker 主机才会真正分配一个端口转发到指定暴露的端口才可使用

注意:即使Dockerfile没有EXPOSE 端口指令,也可以通过docker run -p临时暴露容器内程序真正监听的端口,所以EXPOSE 相当于指定默认的暴露端口,可以通过docker run -P 进行真正暴露

js 复制代码
 EXPOSE <端口>[/ <协议>] [<端口>[/ <协议>] ..]
     
 #说明
 <protocol>用于指定传输层协议,可为tcp或udp二者之一,默认为TCP协议

示例:

js 复制代码
 EXPOSE 80 443
 EXPOSE 11211/udp 11211/tcp
相关推荐
山河君7 分钟前
ubuntu使用DeepSpeech进行语音识别(包含交叉编译)
linux·ubuntu·语音识别
鹏大师运维12 分钟前
【功能介绍】信创终端系统上各WPS版本的授权差异
linux·wps·授权·麒麟·国产操作系统·1024程序员节·统信uos
筱源源14 分钟前
Elasticsearch-linux环境部署
linux·elasticsearch
川石课堂软件测试28 分钟前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
pk_xz1234562 小时前
Shell 脚本中变量和字符串的入门介绍
linux·运维·服务器
小珑也要变强2 小时前
Linux之sed命令详解
linux·运维·服务器
九河云4 小时前
AWS账号注册费用详解:新用户是否需要付费?
服务器·云计算·aws
Lary_Rock4 小时前
RK3576 LINUX RKNN SDK 测试
linux·运维·服务器
神一样的老师4 小时前
利用亚马逊AWS IoT核心和MQTT进行数据采集的综合指南
云计算·aws
云飞云共享云桌面6 小时前
8位机械工程师如何共享一台图形工作站算力?
linux·服务器·网络