如何使用Docker轻松构建和管理应用程序(二)

上一篇文章介绍了 Docker 基本概念,其中镜像、容器和 Dockerfile 。我们使用 Dockerfile 定义镜像,依赖镜像来运行容器,因此 Dockerfile 是镜像和容器的关键,Dockerfile 可以非常容易的定义镜像内容,同时在我们后期的微服务实践中,Dockerfile 也是重点关注的内容,今天我们就来一起学习它。

通过上图可以看出使用 Dockerfile 定义镜像,运行镜像启动容器。

Dockerfile 概念

Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。

Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。有了 Dockerfile,当我们需要定制自己额外的需求时,只需在 Dockerfile 上添加或者修改指令,重新生成 image 即可,省去了敲命令的麻烦。

Dockerfile 文件格式

Dockerfile文件格式如下:

##  Dockerfile文件格式# This dockerfile uses the ubuntu image
# VERSION 2 - EDITION 1
# Author: docker_user
# Command format: Instruction [arguments / command] ..# 1、第一行必须指定 基础镜像信息
FROM ubuntu# 2、维护者信息
MAINTAINER docker_user docker_user@email.com# 3、镜像操作指令
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# 4、容器启动执行指令
CMD /usr/sbin/nginx

Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令、容器启动执行指令。一开始必须要指明所基于的镜像名称,接下来一般会说明维护者信息;后面则是镜像操作指令,例如 RUN 指令。每执行一条RUN 指令,镜像添加新的一层,并提交;最后是 CMD 指令,来指明运行容器时的操作命令。

构建镜像

docker build 命令会根据 Dockerfile 文件及上下文构建新 Docker 镜像。构建上下文是指 Dockerfile 所在的本地路径或一个URL(Git仓库地址)。构建上下文环境会被递归处理,所以构建所指定的路径还包括了子目录,而URL还包括了其中指定的子模块。

将当前目录做为构建上下文时,可以像下面这样使用docker build命令构建镜像:

docker build .
Sending build context to Docker daemon  6.51 MB
...

说明:构建会在 Docker 后台守护进程(daemon)中执行,而不是CLI中。构建前,构建进程会将全部内容(递归)发送到守护进程。大多情况下,应该将一个空目录作为构建上下文环境,并将 Dockerfile 文件放在该目录下。

在构建上下文中使用的 Dockerfile 文件,是一个构建指令文件。为了提高构建性能,可以通过.dockerignore文件排除上下文目录下不需要的文件和目录。

在 Docker 构建镜像的第一步,docker CLI 会先在上下文目录中寻找.dockerignore文件,根据.dockerignore 文件排除上下文目录中的部分文件和目录,然后把剩下的文件和目录传递给 Docker 服务。

Dockerfile 一般位于构建上下文的根目录下,也可以通过-f指定该文件的位置:

docker build -f /path/to/a/Dockerfile .

构建时,还可以通过-t参数指定构建成镜像的仓库、标签。

镜像标签

docker build -t nginx/v3 .

如果存在多个仓库下,或使用多个镜像标签,就可以使用多个-t参数:

docker build -t nginx/v3:1.0.2 -t nginx/v3:latest .

在 Docker 守护进程执行 Dockerfile 中的指令前,首先会对 Dockerfile 进行语法检查,有语法错误时会返回:

docker build -t nginx/v3 .
Sending build context to Docker daemon 2.048 kB
Error response from daemon: Unknown instruction: RUNCMD

缓存

Docker 守护进程会一条一条的执行 Dockerfile 中的指令,而且会在每一步提交并生成一个新镜像,最后会输出最终镜像的ID。生成完成后,Docker 守护进程会自动清理你发送的上下文。
Dockerfile文件中的每条指令会被独立执行,并会创建一个新镜像,RUN cd /tmp等命令不会对下条指令产生影响。
Docker 会重用已生成的中间镜像,以加速docker build的构建速度。以下是一个使用了缓存镜像的执行过程:

$ docker build -t svendowideit/ambassador .
Sending build context to Docker daemon 15.36 kB
Step 1/4 : FROM alpine:3.2---> 31f630c65071
Step 2/4 : MAINTAINER SvenDowideit@home.org.au---> Using cache---> 2a1c91448f5f
Step 3/4 : RUN apk update &&      apk add socat &&        rm -r /var/cache/---> Using cache---> 21ed6e7fbb73
Step 4/4 : CMD env | grep _TCP= | (sed 's/.*_PORT_\([0-9]*\)_TCP=tcp:\/\/\(.*\):\(.*\)/socat -t 100000000 TCP4-LISTEN:\1,fork,reuseaddr TCP4:\2:\3 \&/' && echo wait) | sh---> Using cache---> 7ea8aef582cc
Successfully built 7ea8aef582cc

构建缓存仅会使用本地父生成链上的镜像,如果不想使用本地缓存的镜像,也可以通过--cache-from指定缓存。指定后将不再使用本地生成的镜像链,而是从镜像仓库中下载。

寻找缓存的逻辑

Docker 寻找缓存的逻辑其实就是树型结构根据 Dockerfile 指令遍历子节点的过程。下图可以说明这个逻辑。

     FROM base_image:version           Dockerfile:+----------+                FROM base_image:version|base image|                RUN cmd1  --> use cache because we found base image+-----X----+                RUN cmd11 --> use cache because we found cmd1/ \/   \RUN cmd1     RUN cmd2           Dockerfile:+------+     +------+           FROM base_image:version|image1|     |image2|           RUN cmd2  --> use cache because we found base image+---X--+     +------+           RUN cmd21 --> not use cache because there's no child node/ \                                        running cmd21, so we build a new image here/   \
RUN cmd11     RUN cmd12
+-------+     +-------+
|image11|     |image12|
+-------+     +-------+

大部分指令可以根据上述逻辑去寻找缓存,除了 ADD 和 COPY 。这两个指令会复制文件内容到镜像内,除了指令相同以外,Docker 还会检查每个文件内容校验(不包括最后修改时间和最后访问时间),如果校验不一致,则不会使用缓存。

除了这两个命令,Docker 并不会去检查容器内的文件内容,比如 RUN apt-get -y update,每次执行时文件可能都不一样,但是 Docker 认为命令一致,会继续使用缓存。这样一来,以后构建时都不会再重新运行apt-get -y update。

如果 Docker 没有找到当前指令的缓存,则会构建一个新的镜像,并且之后的所有指令都不会再去寻找缓存。

简单示例

接下来用一个简单的示例来感受一下 Dockerfile 是如何用来构建镜像启动容器。我们以定制 nginx 镜像为例,在一个空白目录中,建立一个文本文件,并命名为 Dockerfile:

mkdir mynginx
cd mynginx
vi Dockerfile

构建一个 Dockerfile 文件内容为:

FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
vi Dockerfile

这个 Dockerfile 很简单,一共就两行涉及到了两条指令:FROM 和 RUN,FROM 表示获取指定基础镜像,RUN 执行命令,在执行的过程中重写了 nginx 的默认页面信息,将信息替换为:Hello, Docker!。

在 Dockerfile 文件所在目录执行:

docker build -t nginx:v1 .

命令最后有一个. 表示当前目录

构建完成之后,使用 docker images 命令查看所有镜像,如果存在 REPOSITORY 为 nginx 和 TAG 是 v1 的信息,就表示构建成功。

docker images
REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE
nginx                           v1                  8c92471de2cc        6 minutes ago       108.6 MB

接下来使用 docker run 命令来启动容器

docker run  --name docker_nginx_v1   -d -p 80:80 nginx:v1

这条命令会用 nginx 镜像启动一个容器,命名为docker_nginx_v1,并且映射了 80 端口,这样我们可以用浏览器去访问这个 nginx 服务器:http://192.168.0.54/,页面返回信息:

这样一个简单使用 Dockerfile 构建镜像,运行容器的示例就完成了!

修改容器内容

容器启动后,需要对容器内的文件进行进一步的完善,可以使用docker exec -it xx bash命令再次进行修改,以上面的示例为基础,修改 nginx 启动页面内容:

docker exec -it docker_nginx_v1   bash
root@3729b97e8226:/# echo '<h1>Hello, Docker neo!</h1>' > /usr/share/nginx/html/index.html
root@3729b97e8226:/# exit
exit

以交互式终端方式进入 docker_nginx_v1 容器,并执行了 bash 命令,也就是获得一个可操作的 Shell。然后,我们用<h1>Hello, Docker neo!</h1>覆盖了 /usr/share/nginx/html/index.html 的内容。

再次刷新浏览器,会发现内容被改变。

修改了容器的文件,也就是改动了容器的存储层,可以通过 docker diff 命令看到具体的改动。

  1. docker diff docker_nginx_v1

  2. ...

这样 Dockerfile 使用方式就为大家介绍完了,下期为大家介绍 Dockerfile 命令的详细使用。

行动吧,在路上总比一直观望的要好,未来的你肯定会感 谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入扣群:731789136,里面有各种软件测试+开发资料和技术可以一起交流学习哦。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

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

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

相关文章

【Consul】Linux安装Consul保姆级教程

【Consul】Linux安装Consul保姆级教程 大家好 我是寸铁&#x1f44a; 总结了一篇【Consul】Linux安装Consul保姆级教程✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 前言 今天要把编写的go程序放到linux上进行测试Consul服务注册与发现&#xff0c;那怎么样才能实现这一过程&am…

docker在线安装centos7(windows版)

目录 1、docker本地安装2、拉取centos7镜像3、启动容器4、配置SSH以访问centos7 1、docker本地安装 windows安装docker比较简单&#xff0c;官网搜索有个docker desktop装上就完事。 2、拉取centos7镜像 可以登录到docker hub上拉&#xff0c;也可以搜出来对应的centos7镜像…

3D检测:从pointnet,voxelnet,pointpillar到centerpoint

记录centerpoint学习笔记。目前被引用1275次&#xff0c;非常高。 地址&#xff1a;Center-Based 3D Object Detection and Tracking (thecvf.com) GitHub - tianweiy/CenterPoint CenterPoint&#xff1a;三维点云目标检测算法梳理及最新进展&#xff08;CVPR2021&#xff…

【蓝桥杯嵌入式】六、真题演练(一)-1演练篇:第 届真题

温馨提示&#xff1a; 真题演练分为模拟篇和研究篇。本专栏的主要作用是记录我的备赛过程&#xff0c;我打算先自己做一遍&#xff0c;把遇到的问题和不同之处记录到演练篇&#xff0c;然后再返回来仔细研究一下&#xff0c;找到最佳的解题方法记录到研究篇。 解题记录&#x…

android WMS服务

android WMS服务 WMS的定义 窗口的分类 WMS的启动 WindowManager Activity、Window、DecorView、ViewRootImpl 之间的关系 WindowToken WMS的定义 WMS是WindowManagerService的简称&#xff0c;它是android系统的核心服务之一&#xff0c;它在android的显示功能中扮演着…

python基础——异常捕获【try-except、else、finally】

&#x1f4dd;前言&#xff1a; 这篇文章主要介绍一下python基础中的异常处理&#xff1a; 1&#xff0c;异常 2&#xff0c;异常的捕获 3&#xff0c;finally语句 &#x1f3ac;个人简介&#xff1a;努力学习ing &#x1f4cb;个人专栏&#xff1a;C语言入门基础以及python入门…

github配置ssh

生成公钥 在电脑用户的目录下打开终端执行 ssh-keygen -t rsa: 执行完不要关 配置文件 看看用户的目录里 .ssh 目录&#xff1a; Host github.comHostname ssh.github.comPort 443配置公钥 复制 id_rsa.pub 文件里的内容 粘贴到 github上 连接密钥 回到刚才的终端…

牛客NC30 缺失的第一个正整数【simple map Java,Go,PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/50ec6a5b0e4e45348544348278cdcee5 核心 Map参考答案Java import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可…

AcWing刷题-区间合并

校门外的树 区间合并&#xff1a; from typing import List def merge(intervals: List[List[int]]) -> List[List[int]]:# 按照第一个元素从小到大进行排序intervals.sort(keylambda x: x[0])# 初始化一个新的数组new_list list()for i in intervals:# 把第一个数组元素添…

Dockerfile:自定义镜像

Dockerfile 是一个文本文件&#xff0c;其中包含了一系列用于自动化构建Docker镜像的指令。通过编写Dockerfile&#xff0c;开发者能够明确地定义一个软件应用及其运行环境应该如何被封装进一个可移植、可重复构建的Docker镜像中。 第一步&#xff1a;在/tmp文件下新建docker…

阿里云效CICD流水线提交前后端项目

后端 一、新建流水线 1进入流水线 2新建流水线 3选择流水线模板 二、上传后端项目 1 将后端项目发布至代码仓库后&#xff0c;在流水线中选择流水线源 我们在选择流水线源之后会出现扫描失败的情况 查看日志发现是因为我们的项目是多模块项目&#xff0c;再扫描的时候无法在…

Android MediaRecorder

AndroidManifest.xml中添加权限标记 <uses-permission android:name"android.permission.RECORD_AUDIO"/> 动态添加权限MainActivity requestPermissions(new String[]{Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO},100); 创建MediaReco…

深度学习基础模型之Mamba

Mamba模型简介 问题&#xff1a;许多亚二次时间架构(运行时间复杂度低于O(n^2)&#xff0c;但高于O(n)的情况)&#xff08;例如线性注意力、门控卷积和循环模型以及结构化状态空间模型&#xff08;SSM&#xff09;&#xff09;已被开发出来&#xff0c;以解决 Transformer 在长…

centos2anolis

我的centos7原地升级到anolis7记录 注意&#xff1a;如果是桌面版请先卸载firefox&#xff0c;否则so文件冲突。 参考&#xff1a; CentOS 7和8Linux系统迁移到国产Linux龙蜥Anolis OS 8手册_disable pam_pkcs11 module in pam configuration-CSDN博客 关于 CentOS 迁移龙蜥…

Intellij IDEA 类注释模板设置

1、配置全局USER 在此配置全局USER&#xff0c;用于填充自动生成的注释中的作者author属性。 注释模板中的user参数是默认是获取系统的用户&#xff08;当然注释作者也可以直接写固定值&#xff09;&#xff0c;如果不想和系统用户用同一个信息&#xff0c;可以在IDEA中进行配…

【42 可视化大屏 | 某瓣电影Top250数据分析可视化大屏】

文章目录 &#x1f3f3;️‍&#x1f308; 1 普版大屏&#x1f3f3;️‍&#x1f308;2 Flask版大屏&#x1f3f3;️‍&#x1f308;3 FlaskMysql版大屏&#x1f3f3;️‍&#x1f308; 4. 可视化项目源码数据 大家好&#xff0c;我是 &#x1f449;【Python当打之年(点击跳转)…

快速上手Spring Cloud 十一:微服务架构下的安全与权限管理

快速上手Spring Cloud 一&#xff1a;Spring Cloud 简介 快速上手Spring Cloud 二&#xff1a;核心组件解析 快速上手Spring Cloud 三&#xff1a;API网关深入探索与实战应用 快速上手Spring Cloud 四&#xff1a;微服务治理与安全 快速上手Spring Cloud 五&#xff1a;Spring …

Flink SQL 基于Update流出现空值无法过滤问题

问题背景 问题描述 基于Flink-CDC &#xff0c;Flink SQL的实时计算作业在运行一段时间后&#xff0c;突然发现插入数据库的计算结果发生部分主键属性发生失败&#xff0c;导致后续计算结果无法插入&#xff0c; 超过失败次数失败的情况问题报错 Caused by: java.sql.BatchUp…

(南京观海微电子)——GOA介绍

GOA是Gate on Array的简写&#xff0c;简单可以理解为gate IC集成在玻璃上了&#xff0c;面板就可以不用gate ic了&#xff0c;是一种低成本的设计&#xff0c;窄边框面板大多数都用了GOA技术。还有一些公司叫GIP&#xff08;Gate in Panel&#xff09;&#xff0c;GDM等等。 …

软考数据库

目录 分值分布1. 事务管理1.1 事物的基本概念1.2 数据库的并发控制1.2.1 事务调度概念1.2.2 并发操作带来的问题1.2.3 并发控制技术1.2.4 隔离级别&#xff1a; 1.3 数据库的备份和恢复1.3.1 故障种类1.3.2 备份方法1.3.3 日志文件1.3.4 恢复 SQL语言发权限收权限视图触发器创建…