Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Docker速学(二) Dockerfile和数据卷

Docker速学(二) Dockerfile和数据卷

原创
作者头像
w9
修改于 2021-08-27 03:11:10
修改于 2021-08-27 03:11:10
90500
代码可运行
举报
运行总次数:0
代码可运行

在前文,我们介绍了Docker学习的基本方法和原理,以及基础三大件:镜像、容器、仓库。

回顾:

Docker小白入门建议及基本原理介绍

Docker速学(一) 镜像和容器

今天,小九介绍的内容是Dockerfile和数据卷。Docker的镜像生产:通过 Dockerfile 编排镜像所需的资源。而数据卷,是Docker的数据存储方案。

下面我们开始正式的介绍~

Dockerfile

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令 (opens new window)和说明。

理解每个指令的用法是掌握 Docker 技术的关键

具体使用请直接阅读官方文档 (opens new window)

关于 Dockerfile,下面我们再传递几个重要的观点:

  • Dockerfile 是 Docker 运维开发工作的关键
  • Dockerfile 文件主要用于编写应用的安装过程
  • 应用的初始化过程可以在 Dockerfile 中引入,然后在独立的脚本中编写
  • Dockerfile 必须构建成镜像后再供用户使用,直接基于 Dockerfile 运行容器可能会由于网络问题导致无法达成预期目的

指令不仅仅用于设计 Docker 镜像,还有一部分指令与容器运行时密切相关,包括:

  • CMD
  • ENTRYPOINT
  • WORKDIR
  • ENV
  • USER
  • VOLUME

CMD 和 ENTRYPOINT

它们都是容器启动时运行的指令。

有如下几个关键技术点需要掌握:

  1. CMD 与 ENTRYPOINT 的区别:CMD 直接运行单条命令,ENTRYPOINT 用于运行一个脚本
  2. 指令的 Shell 和 Exec 语法模式
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Shell 模式
CMD ping localhost
​
# Exec 模式
CMD ["/bin/ping","localhost"] 

可见它们从写法上一种是命令行模式,一种是数组模式。

但它们不仅仅写法上不同,更重要的是运行方式不同。

  • CMD 模式相当于调用 Shell 后再运行指令,例如上面的例子实际上相当于: /bin/sh -c "ping localhost"
  • ENTRYPOINT 模式相当于直接运行指令,例如上面的例子实际上相当于: /bin/ping localhost
  1. CMD 与 ENTRYPOINT 组合使用:组合使用的时候 CMD 作为 ENTRYPOINT 的一个参数

组合使用 ENTRYPOINT 和 CMD 命令式, 确保你一定用的是 Exec 表示法. 如果用其中一个用的是Shell表示法, 或者一个是Shell表示法, 另一个是Exec表示法, 你永远得不到你预期的效果.

下表列出了如果把Shell表示法和Exec表示法混合, 最终得到的命令行, 可以看到如果有Shell表示法存在, 很难得到正确的效果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Dockerfile    Command
​
ENTRYPOINT /bin/ping -c 3
CMD localhost               /bin/sh -c '/bin/ping -c 3' /bin/sh -c localhost
​
​
ENTRYPOINT ["/bin/ping","-c","3"]
CMD localhost               /bin/ping -c 3 /bin/sh -c localhost
​
ENTRYPOINT /bin/ping -c 3
CMD ["localhost"]"          /bin/sh -c '/bin/ping -c 3' localhost
​
ENTRYPOINT ["/bin/ping","-c","3"]
CMD ["localhost"]            /bin/ping -c 3 localhost

从上面看出, 只有ENTRYPOINT 和 CMD 都用 Exec 表示法, 才能得到预期的效果。

WORKDIR

ENV

USER

先看官方的定义:

The USER instruction sets the user name (or UID) and optionally the user group (or GID) to use when running the image and for any RUN, CMD and ENTRYPOINT instructions that follow it in the Dockerfile.

有几个关键信息:

  • 适用于 RUN, CMD and ENTRYPOINT 三个指令

VOLUME

对于 VOLUME 申明的目录,容器运行后会自动在 /var/lib/docker/volumes 下创建如下的匿名卷。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/var/lib/docker/volumes/b58ec6901901202b215315db8d958848d910d51dc37c781e29c133064ed5842d

当我们运行 docker-compose down 删除容器时,匿名卷不会被删除,只有运行 docker-compose down -v 才会删除这个卷。

数据卷

Docker 容器的理念是运行时,因此它并不向普通的虚拟机一样,可以方便的更改任何文件。

但用户在实际使用 Docker 的过程中,一定有持久保存数据(包含配置文件)的需求,那么 Docker 是如何解决这个问题的呢?

概述

Docker 提供了一套数据存储的方案(卷 (opens new window)):

主要有两种形式的存储卷模式:

Named Volumes

Bind Mounts

路径

/var/lib/docker/volumes 目录下

任意位置

启用方式

my-volume:/usr/local/data

/path/to/data:/usr/local/data

预先定义

可以先定义,也可以不定义

不需要

名称

my-volume_default 或 my-volume

data

文件权限

权限宽松

受制于宿主机文件权限

空目录下数据方向

容器 → Named Volume

Bind Volume → 容器

非空目录下数据方向

Named Volume → 容器

Bind Volume → 容器

我们根据持久化数据挂载的几种场景进行试验,得出如下的现象:

  • 容器启动后由 CMD 和 ENTRYPOINT 产生的数据区别于镜像中 COPY/ADD 层的数据,前者我们称之动态数据,后者为静态数据。显然,动态数据不受挂载影响。
  • 宿主机目录优先定律:挂载双方都有数据时,宿主机目录覆盖容器目录
  • Bind Mounts 与 Named Volumes 有差异:Bind Mounts 任何情况下都会覆盖容器目录,而 Named Volumes 挂载空目录时会先拷贝容器目录的数据

Named Volumes 在 Docker 中被推荐为首选方式,它与 Bind Mounts 相比,有以下优点:

  • 与 Bind Mounts 相比,Named Volumes 更容易备份或迁移。
  • 可以使用 Docker CLI 命令或 Docker API 来管理。
  • Named Volumes 在 Linux 和 Windows 容器上都能工作。
  • Named Volumes 可以在多个容器之间更安全的共享。
  • Named Volumes 驱动程序允许你在远程主机或云上提供存储、加密或其他功能。
  • 新 Named Volumes 的内容可以由容器预填充。

使用卷

下面是一个通过 -v 使用卷的范例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 docker run -dp 3000:3000 \
     -w /app -v "$(pwd):/app" \
     node:12-alpine \
     sh -c "yarn install && yarn run dev"

共享卷

多个容器共享一个存储卷是非常典型的应用场景:

下篇内容:

  • 端口与互联:容器与宿主机、容器与容器、容器与外部的连接与通信机制
  • 用户权限:容器中的用户与宿主机的用户之间的关系

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Dockerfile 指令
1、Dockerfile基本结构 Dockerfile由一行行命令语句组成,并且支持以#开头的注释行。
小手冰凉
2020/08/06
5150
Dockerfile 指令
Docker 入门笔记
ContainerViewer does not support full SVG 1.1
Rikka
2022/01/20
1.2K0
Docker 入门笔记
Docker 学习总结
推荐安装 vagrant + VirtualBox 快速搭建 docker host,不推荐直接使用 Docker for Mac
CS逍遥剑仙
2020/06/07
3.1K0
docker | dockerfile指令详解
Dockerfile用于构建docker镜像, 实际上就是把在linux下的命令操作写到了Dockerfile中, 通过Dockerfile去执行设置好的操作命令, 保证通过Dockerfile的构建镜像是一致的.
Amadeus
2023/04/17
1.9K0
Dockerfile、Docker-Compose基本命令与介绍
每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像,后续的RUN都在之前RUN提交后的镜像为基础,镜像是分层的,可以通过一个镜像的任何一个历史提交点来创建,类似源码的 版本控制 。
唐成勇
2019/05/26
2K0
Docker-容器数据卷与DockerFile解析(三)
Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了。
IT小马哥
2021/06/03
1.6K0
Docker-容器数据卷与DockerFile解析(三)
五分钟学K8S系列<四>-深入浅出Dockerfile
在讨论 Dockerfile 的制作流程之前,我们先来探讨为什么要使用 Dockerfile 进行自动构建。
五分钟学SRE
2024/05/01
4230
docker 实践手册
其他参考 https://blog.csdn.net/styshoo/article/details/55657714
orientlu
2020/04/18
1.1K0
【云原生 | Docker篇】实战Dockerfile(五)
Dockerfile基础知识已经在上一篇做了详细介绍,如果还不是很清楚的同学可以点击传送门再复习一遍。
Lansonli
2022/05/11
8570
【云原生 | Docker篇】实战Dockerfile(五)
docker命令实战
docker分层:每一次对原始镜像的修改都会形成新的一层,一层层的叠加,多个不同的容器实例可以共享原始镜像,并在磁盘记录新的修改,即采用写时复制的技术,可以节省磁盘空间
素履coder
2022/08/30
7260
docker命令实战
Docker是什么?
Docker是什么? Docker是 Docker.Inc 公司开源的一个基于 LXC技术之上构建的Container容器引擎,基于Go语言并遵从Apache2.0协议开源。 开发者可以搭建他们的应用
小小科
2018/05/04
2.1K0
Docker是什么?
docker容器dockerfile详解
Dockerfile是一个镜像构建命令集合的文本文件,下面是我们最常见的Dockerfile构建,假如我们目录下有一个文件Dockerfile
用户8851537
2021/08/20
1.5K0
Docker 高级
数据 不应该放在容器中,因为容器一旦删除,数据就会丢失! 数据卷就相当于数据可持久化。
收心
2022/01/20
9340
Docker 高级
DockerFile就这么简单
当我们在使用docker时,最重要的就是镜像,只要有了镜像,我们就可以随时随地的根据镜像来创建一个容器,从而做到让我们的服务可以在任何时间任何地点任何环境下运行起来。那么镜像是怎么制作的呢?总体来讲,制作镜像有两种方法:
后场技术
2020/09/03
1.7K0
DockerFile就这么简单
kubernetes(五)之Dockerfile
Dockerfile 镜像相关的操作 镜像生成的途径 Dockerfile 基于容器制作docker commit 定义 构建docker镜像的源码 docker可以根据Dockerfile中的
alexhuiwang
2020/09/23
8470
kubernetes(五)之Dockerfile
《前端运维》三、Docker--2其他
   docker的镜像类似于用一层一层的文件组成。inspect命令可以查看镜像或容器的的信息,其中Layers就是镜像的层文件,只读不能修改,基于镜像创建的容器会共享这些层。下面我们先来学习一下dockerFile中的一些命令:
zaking
2022/05/10
7770
《前端运维》三、Docker--2其他
docker浅入深出续
假设启动镜像仓库服务的主机地址为192.168.136.10,该目录中已存在的镜像列表:
萧晚歌
2020/08/28
7830
docker浅入深出续
docker-Dockerfile
Dockerfile是为了快速构建镜像 Dockerfile由一行行命令语句组成,并且支持以#开头的注释行。 一般而言,Dockerfile分为4个部分: 基础镜像信息<br/>维护者信息<br/>镜像操作指令<br/>容器启动时执行指令
yuezhimi
2020/09/30
8650
docker-Dockerfile
Docker容器学习梳理--基础知识(2)
之前已经总结了Docker容器学习梳理--基础知识(1),但是不够详细,下面再完整补充下Docker学习的一些基础。 Docker是个什么东西 Docker是一个程序运行、测试、交付的开放平台,Docker被设计为能够使你快速地交付应用。 在Docker中,你可以将你的程序分为不同的基础部分,对于每一个基础部分都可以当做一个应用程序来管理。 Docker能够帮助你快速地测试、快速地编码、快速地交付,并且缩短你从编码到运行应用的周期。 Docker使用轻量级的容器虚拟化平台,并且结合工作流和工具,来帮助你管
洗尽了浮华
2018/01/23
2.1K0
Docker容器学习梳理--基础知识(2)
Docker重学系列之Dockerfile
Dockerfile可以认为是Docker镜像的描述文件,是由一系列命令和参数构成的脚本。主要作用是用来构建docker镜像的构建文件。
大忽悠爱学习
2022/05/10
2K0
Docker重学系列之Dockerfile
相关推荐
Dockerfile 指令
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验