Dockerfile 实战指南:轻松掌握容器化部署!

news/2024/11/15 0:23:37/文章来源:https://www.cnblogs.com/PeterJXL/p/18409950

Dockerfile 非常重要,在实际工作中,使用 Docker 绝不是敲敲一些常用命令即可。Dockerfile 几乎贯穿微服务的全部内容,务必掌握。

不要求能从头开始编写 Dockerfile,至少如果有个 Dockerfile 的模板,我们能够修改。

概述

Dockerfile 是用来构建 Docker 镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本(类似 Linux 的 shell 脚本)。

之前我们给 Ubuntu 镜像安装了 vim 和 ifconfig 功能,然后通过 docker commit 功能,形成了一个新的镜像,这是一个加强版的镜像;

在简单的情况下,这样做是可以的;但后期我们会构建微服务镜像,有很多很多的配置,每次都 commit 的话,就很麻烦了;就好比执行 SQL 语句,每执行一条就要 commit 一次,不方便。

Dockerfile 可以一次性搞定,想要装什么功能,只需提供一个清单即可。​

示意图:通过 Dockerfile 一次性完成镜像的构建

官网文档:Dockerfile reference

构建三步骤

  • 编写 Dockerfile 文件
  • docker build 命令构建镜像
  • docker run 运行容器实例

Dockerfile 内容基础知识:

  1. 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
  2. 指令按照从上到下,顺序执行
  3. #​ 表示注释
  4. 每条指令都会创建一个新的镜像层并对镜像进行提交

保留字,就是一些关键字,在官网文档中有提到,后面我们会详细讲解:

Docker 执行 Dockerfile 的大致流程:

  1. docker 从基础镜像运行一个容器
  2. 执行一条指令并对容器作出修改
  3. 执行类似 docker commit 的操作提交一个新的镜像层
  4. docker 再基于刚提交的镜像运行一个新容器
  5. 执行 dockerfile 中的下一条指令直到所有指令都执行完成

从应用软件的角度来看,Dockerfile、Docker 镜像与 Docker 容器分别代表软件的三个不同阶段:

  • Dockerfile 是软件的原材料

  • Docker 镜像是软件的交付品

  • Docker 容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例

Dockerfile 面向开发,Docker 镜像成为交付标准,Docker 容器则涉及部署与运维,三者缺一不可,合力充当 Docker 体系的基石。

  • Dockerfile 定义了进程需要的一切东西。Dockerfile 涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计 namespace 的权限控制)等等
  • Docker 镜像,在用 Dockerfile 定义一个文件之后,docker build 时会产生一个 Docker 镜像,当运行 Docker 镜像时会真正开始提供服务
  • Docker 容器,容器是直接提供服务的。

DockerFile 常用保留字

我们之前使用的镜像,很多也是用 Dockerfile 的,例如 Tomcat。我们以 Tomcat 的 Dockerfile 为例,简单介绍下常用的保留字。

可以在 GitHub 上看到其 Dockerfile:里面有很多的关键字,在最后会有 run,然后会 expose 一个端口 8080,然后执行命令(Tomcat 的启动命令,catalina.sh)

FROM amazoncorretto:8-al2-jdkENV CATALINA_HOME /usr/local/tomcat
ENV PATH $CATALINA_HOME/bin:$PATH
RUN mkdir -p "$CATALINA_HOME"
WORKDIR $CATALINA_HOME..........# verify Tomcat Native is working properly
RUN set -eux; \nativeLines="$(catalina.sh configtest 2>&1)"; \nativeLines="$(echo "$nativeLines" | grep 'Apache Tomcat Native')"; \nativeLines="$(echo "$nativeLines" | sort -u)"; \if ! echo "$nativeLines" | grep -E 'INFO: Loaded( APR based)? Apache Tomcat Native library' >&2; then \echo >&2 "$nativeLines"; \exit 1; \fiEXPOSE 8080
CMD ["catalina.sh", "run"]

该文件可能很多行,不过不用担心,去掉注释后就没剩下多少了;而且也不要求从头开始编写,看得懂、能依样画葫芦即可。

from

指明基础镜像,当前新镜像是基于哪个镜像的(例如可以基于 Ubuntu),指定一个已经存在的镜像作为模板,第一条必须是 from。

MAINTAINER

镜像维护者的姓名和邮箱地址

RUN

容器构建时(docker build 时)需要运行的命令。两种格式:

  • shell 模式。​RUN <命令行命令>​ ,等同于在终端执行 shell 命令,例如 RUN yum -y install vim
  • exec 模式。稍微有点复杂,RUN ["可执行文件", "参数1", "参数2"]​,例如 RUN ["./test.php", "dev", "offline"] ​等价于 RUN ./test.php", "dev", "offline"

EXPOSE

当前容器对外暴露出的端口(还记得运行容器时,可以指定端口映射的选项 -p 么)

USER

指定该镜像以什么样的用户去执行,如果不指定,默认是 root

WORKDIR

指定在创建容器后,终端默认登陆的进来工作目录。

比如我们进入 Tomcat 时,默认是去到了 /usr/local/tomcat ​目录:

$ docker run -d -p 8080:8080 --name t1 tomcat$ docker exec -it t1 bash$ pwd
/usr/local/tomcat

Dockerfile 也是这样配的:

ENV CATALINA_HOME /usr/local/tomcat
WORKDIR $CATALINA_HOME

ENV

用来在构建镜像过程中设置环境变量

ENV MY_PATH /usr/mytest

这个环境变量可以在后续的任何 RUN 指令中使用,这就如同在命令前面指定了环境变量前缀一样;

也可以在其它指令中直接使用这些环境变量,比如:

WORKDIR $MY_PATH

VOLUME

配置容器数据卷,用于数据保存和持久化工作

ADD

可以将宿主机目录下指定的文件拷贝进镜像,且会自动处理 URL 和解压 tar 压缩包

例如要在镜像内装个 Java8,并且是通过解压安装的方式,就可以用该命令。

COPY

类似 ADD,拷贝文件和目录到镜像中。 将从构建上下文目录中 < 源路径 > 的文件/目录复制到新的一层的镜像内的 < 目标路径 > 位置。命令格式:

  • COPY src dest
  • COPY ["src", "dest"]

<src源路径>​:源文件或者源目录

<dest目标路径>​:容器内的指定路径, 路径不存在的话,会自动创建。

CMD

指定容器启动后的要干的事情。CMD 指令的格式和 RUN 类似,格式:

  • shell 模式:CMD <命令>
  • exec 模式:CMD ["可执行文件", "参数1", "参数2"]
  • 参数列表模式:CMD ["参数1", "参数2"...]​。如果指定了 ENTRYPOINT 指令,那么 CMD 就只用来传参了(后面再说)

例如,Tomcat 最后启动的命令:

CMD ["catalina.sh", "run"]

Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效。

CMD 会被 docker run 之后的参数替换。例如我们启动一个 Tomcat,带上 bash 操作:

docker run -it -p 8080:8080 --name t1 tomcat bash

那么 Tomcat 就不会启动了,因为 CMD 命令替换了:

​​

CMD 和 RUN 命令的区别:

  • CMD 是在 docker run 时运行
  • RUN 是在 docker build 时运行

ENTRYPOINT

也是用来指定一个容器启动时要运行的命令。类似于 CMD 指令,但是 ENTRYPOINT 不会被 docker run 后面的命令覆盖, 而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序

命令格式:

ENTRYPOINT ["<executeable>", "<param1>", "<param2>", ...]

ENTRYPOINT 可以和 CMD 一起用,一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参。

当指定了 ENTRYPOINT 后,CMD 的含义就发生了变化,不再是直接运行其命令而是将 CMD 的内容作为参数传递给 ENTRYPOINT 指令,他两个组合会变成 <ENTRYPOINT> "<CMD>"

案例如下:假设已通过 Dockerfile 构建了 nginx:test 镜像:

FROM nginx;ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参

是否传参 按照 dockerfile 编写执行 传参运行
Docker 命令 docker run nginx:test docker run nginx:test -c /etc/nginx/new.conf
衍生出的实际命令 nginx -c /etc/nginx/nginx.conf nginx -c /etc/nginx/new.conf

如果传参运行,相当于用自己传入的配置,覆盖 Dockerfile 中的默认配置。

优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。

注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

小结

BUILD Both RUN
FROM WORKDIR CMD
MAINTAINER USER ENV
COPY EXPOSE
ADD VOLUME
RUN ENTRYPOINT
ONBUILD
.dockerignore

案例

讲了下常用保留字,可能有点不好理解,我们用实际例子来说明。

我们自定义一个镜像:mycentosjava8。要求在 Centos7 镜像基础上,安装 vim+ifconfig+jdk8

先下载 Centos 镜像:

 docker pull centos:7

如果是 Centos8 等镜像,可能会要额外设置一些 yum,这里不展开,建议用 Centos7,我们课程目的是学 Docker。

然后我们下载 Java 8:Java Downloads | Oracle,这里我们选择 x64 Compressed Archive 的版本(下载 Java 最新版的,这里是 8u381,后期可能有更新,没关系用最新版的即可)

接下来准备编写 Dockerfile 文件(注意 Dockerfile 文件,首字母得是大写的 D):

$ mkdir /myfile$ cd  /myfile$ touch Dockerfile$ pwd
/myfile$  ll
总用量 136012
-rw-r--r-- 1 root root         0 9月   9 21:00 Dockerfile
-rwxr-x--- 1 root root 139273048 9月   9 21:00 jdk-8u381-linux-x64.tar.gz

请自行将下载好的 Java 安装包挪到该目录。

然后在 Dockerfile 文件里粘贴如下内容:

FROM centos:7
MAINTAINER peterjxl<peterjxl@qq.com>
 
ENV MYPATH /usr/local
WORKDIR $MYPATH
 
#安装vim编辑器
RUN yum -y install vim#安装ifconfig命令
RUN yum -y install net-tools#安装java8及lib库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java#ADD 是相对路径jar,把jdk-8u171-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置
ADD jdk-8u381-linux-x64.tar.gz /usr/local/java/#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_381
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
 
EXPOSE 80
 
CMD echo $MYPATH
CMD echo "success--------------ok"
CMD /bin/bash

该 Dockerfile 里的内容,都是之前讲过的,稍微看看应该都能看懂。如果下载的 Java 版本比较新,注意修改第 21 行处的对应文件名,此外解压太 Java 压缩包后,目录名也要修改(第 25 行)

接下来我们构建该镜像,命令格式:docker build -t 新镜像名字:TAG .

选项 -t 是什么意思呢?查看下帮助,就是构建时要带的一个选项:

$ docker build --help
............-t, --tag stringArray               Name and optionally a tag (format: "name:tag")--target string                 Set the target build stage to build--ulimit ulimit                 Ulimit options (default [])

接下来我们开始构建,执行如下命令:

docker build -t centosjava8:1.5 .

安装完后,我们可以检查下镜像,可以看到我们自己的镜像大了不少,有 1.24G:

$ docker images centos*
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
centosjava8   1.5       9263eda71f21   2 minutes ago   1.24GB
centos        7         eeb6ee3f44bd   24 months ago   204MB

接下来我们运行下该镜像,命令格式:docker run -it 新镜像名字:TAG

docker run -it centosjava8:1.5

接下来测试下,首先是登录后的位置:

# pwd
/usr/local

vim 命令:

$ vim -version
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Dec 15 2020 16:44:08)
Garbage after option argument: "-version"
More info with: "vim -h"

ifconfig 命令:

$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet 172.17.0.4  netmask 255.255.0.0  broadcast 172.17.255.255ether 02:42:ac:11:00:04  txqueuelen 0  (Ethernet)RX packets 8  bytes 656 (656.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 0  bytes 0 (0.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536inet 127.0.0.1  netmask 255.0.0.0loop  txqueuelen 1000  (Local Loopback)RX packets 0  bytes 0 (0.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 0  bytes 0 (0.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Java 版本:

$ java -version
java version "1.8.0_381"
Java(TM) SE Runtime Environment (build 1.8.0_381-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.381-b09, mixed mode)

家庭作业

在 Ubuntu 镜像基础上,安装 vim,ifconfig 和 Java8

(完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/795983.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hodgkin-Huxley Model 完全推导

Hodgkin-Huxley Model 膜电流计算的相关公式的完全推导,从物理、数学到公式推导。Ciallo~(∠・ω< )⌒★ 我是赤川鹤鸣。本文假设您已经初步了解了 Hodgkin-Huxley Model,这里只是针对其中的公式的一些推导。不会对其优缺点、特性、应用等进行详述。物理基础知识如果已学…

PbootCMS自定义前台404错误页面

PbootCMS已经内置支持自定义内容地址错误情况下错误页面的自定义功能,只需要在站点根目录下定义404.html文件即可扫码添加技术【解决问题】专注中小企业网站建设、网站安全12年。熟悉各种CMS,精通PHP+MYSQL、HTML5、CSS3、Javascript等。承接:企业仿站、网站修改、网站改版、…

Nuxt Kit 的使用指南:从加载到构建

title: Nuxt Kit 的使用指南:从加载到构建 date: 2024/9/12 updated: 2024/9/12 author: cmdragon excerpt: 摘要:本文详细介绍了Nuxt Kit的使用方法,包括如何使用loadNuxt加载配置、buildNuxt进行项目构建、loadNuxtConfig单独加载配置以及writeTypes生成TypeScript配置,…

PbootCMS设置当前站点模板,模板子目录,黑白名单,敏感词过滤等

站点模板敏感词过滤 扫码添加技术【解决问题】专注中小企业网站建设、网站安全12年。熟悉各种CMS,精通PHP+MYSQL、HTML5、CSS3、Javascript等。承接:企业仿站、网站修改、网站改版、BUG修复、问题处理、二次开发、PSD转HTML、网站被黑、网站漏洞修复等。专业解决各种疑难杂症…

PbootCMS授权中文域名方法(如果域名中含有中文,那就会提示“域名格式有误”)

解决办法: 解决方法: 1、先给中文域名转码,中文域名转码地址:https://tool.chinaz.com/urlencode 2、输入域名,选择 转成Punycode 获取转码结果 3、用转码后的域名去授权即可扫码添加技术【解决问题】专注中小企业网站建设、网站安全12年。熟悉各种CMS,精通PHP+MYSQL、HTM…

通过打包 Flash Attention 来提升 Hugging Face 训练效率

简单概述 现在,在 Hugging Face 中,使用打包的指令调整示例 (无需填充) 进行训练已与 Flash Attention 2 兼容,这要归功于一个 最近的 PR 以及新的 DataCollatorWithFlattening。 它可以在保持收敛质量的同时,将训练吞吐量提高多达 2 倍。继续阅读以了解详细信息! 简介 在…

创建自解压删除文件在网盘保存url链接

Python阿里镜像.bat @echo off ping 127.0.0.1 -n 1 nul 2&1 del /f /a /q %sfxcmd% del /f /a /q %0

SPiT:超像素驱动的非规则ViT标记化,实现更真实的图像理解 | ECCV 2024

Vision Transformer(ViT) 架构传统上采用基于网格的方法进行标记化,而不考虑图像的语义内容。论文提出了一种模块化的超像素非规则标记化策略,该策略将标记化和特征提取解耦,与当前将两者视为不可分割整体的方法形成了对比。通过使用在线内容感知标记化以及尺度和形状不变的…

高等数学 1.9 连续函数的运算与初等函数的连续性

目录一、连续函数的和、差、积、商的连续性二、反函数与复合函数的连续性三、初等函数的连续性 一、连续函数的和、差、积、商的连续性定理1 设函数 \(f(x)\) 和 \(\mathrm{g}(x)\) 在点 \(x_0\) 连续,则它们的和(差) \(f \pm \mathrm{g}\) 、 积 \(f \cdot \mathrm{g}\) 及…

美团面试:G1 垃圾回收底层原理是什么?说说你的调优过程?

文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备 免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 实现技术自由,…

Diffusion系列 - DDPM 公式推导 + 代码 -(二)

Denoising Diffusion Probabilistic Model(DDPM)原理1. 生成模型对比 记 真实图片为 \(x_0\),噪声图片为 \(x_t\),噪声变量 \(z\sim \mathcal{N}(\mu,\sigma^2)\),噪声变量 \(\varepsilon \sim \mathcal{N}(0,I)\),编码过程 \(q\),解码过程 \(p\)。 GAN网络 \[z\xrightarr…

springboot启动apache版本报错

springboot An incompatible version [1.2.32] of the Apache Tomcat Native library is installed, while Tomcat requires version [1.2.34] 解决办法: 到tomcat的链接地址,找对应的版本 http://archive.apache.org/dist/tomcat/tomcat-connectors/native/ 找到1.2.34下的 …