写点什么

Docker 入坑篇

作者:青柚1943
  • 2022 年 6 月 21 日
  • 本文字数:2871 字

    阅读完需:约 9 分钟

Docker入坑篇

1 什么是 Docker?

1.1 Docker 概述

Docker 是一个用于开发、打包、分发和运行容器的容器化平台,项目基于 golang 语言并遵从 Apache2.0 协议开源。它可以让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行操作系统的机器上,容器是完全使用沙箱机制,相互之间不会有任何接口。正如 Docker 的图标含义一样,在一艘大船上,可以把货物规整的摆放起来,并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响。

1.2 核心概念

  • 镜像(Image)

镜像本质是一种包含软件的可移植程序包,它是创建 Docker 容器实例的基础,也是分发应用程序的基本单位。另外,镜像是不可变的(只读模板),生成之后则不可更改。

  • 容器(Container)

容器是一种松散且相互隔离的环境, 容器是映像的内存中实例。Docker 利用容器来运行和隔离应用。

  • 仓库(Repository)

用于存放和分发镜像的地方(如官方提供的共有或私有的镜像仓库:DockerHub)。


1.3 Dockerfile

Dockerfile 是一个文本格式的配置文件,它由一条条命令和说明组成,用户可以使用 Dockerfile 来快速创建自定义的镜像。如下面代码实例:

# syntax=docker/dockerfile:1FROM node:12-alpineRUN apk add --no-cache python2 g++ makeWORKDIR /appCOPY . .# shell格式:就像在命令行中输入的Shell脚本命令一样。RUN <command> RUN yarn install --productionCMD ["node", "src/index.js"]EXPOSE 3000
复制代码


  • 1.3.1 FROM-指定基础镜像

指定基础镜像,并且 Dockerfile 中第一条指令必须是 FROM 指令,且在同一个 Dockerfile 中创建多个镜像时,可以使用多个 FROM 指令。

FROM <image>:<tag> 
复制代码
  • 1.3.2 RUN-运行指定的命令

运行指定的命令。多行命令不要写多个 RUN,原因是 Dockerfile 中每一个指令都会建立一层。多少个 RUN 就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错。RUN 书写时的换行符是\

# shell格式:就像在命令行中输入的Shell脚本命令一样。RUN <command> 
# exec格式:就像是函数调用的格式。RUN ["executable", "param1", "param2"]
复制代码
  • 1.3.3 CMD-容器启动时要运行的命令

容器启动时要运行的命令。推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是sh

# 第一种就是shell这种执行方式和写法CMD command param1 param2
# 第二种是可执行文件加上参数的形式(推荐)CMD ["executable","param1","param2"]
# 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数CMD ["<param1>","<param2>",...]
复制代码
  • 1.3.4 COPY-复制文件或者目录到容器里指定路径

从上下文目录中复制文件或者目录到容器里指定路径。

COPY [--chown=<user>:<group>] <src>... <dest>COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
复制代码
  • 1.3.5 ADD-复制文件或者目录到容器里指定路径

ADD 指令和 COPY 的使用类似 (同样需求下,官方推荐使用 COPY) ,功能也类似。除此之外,ADD 还支持使用 TAR 文件和 URL 路径,并且会将 tar 压缩文件(gzip, bzip2 以及 xz 格式)解压缩,如果指定的是 url,会从指定的 url 下载文件放到目录中( 如果 url 下载的文件为 tar 文件,则不会展开)

ADD [--chown=<user>:<group>] <src>... <dest>ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
复制代码
  • 1.3.6 EXPOSE-为容器打开指定要监听的端口以实现与外部通信

用于为容器打开指定要监听的端口以实现与外部通信,这个只是声明,真正要暴露这个端口需要再构建容器的时候使用"-P"选项。其格式为:

EXPOSE <port> [<port>/<protocol>...]
复制代码
  • 1.3.7 ENV-设置环境变量

设置环境变量,无论是接下来的指令(如ENVADDCOPY等,其调用格式为$variable_name${variable_name}),还是在容器中运行的程序,都可以使用这里定义的环境变量。

ENV <key> <value> 
ENV <key>=<value> ...
复制代码

1.4 数据卷(Volume)

指定的目录文件,绕过联合文件系统,提供数据持久化机制,与容器生命周期无关。


2 为什么使用 Docker?

2.1 传统迭代模式

现在的团队必须快速迭代,以吸引和留住客户。 由于存在这种要求,软件开发和支持团队必须始终考虑可节省时间和成本的解决方案。 理想的解决方案将减少创建和配置部署环境所花费的时间,并简化软件部署过程

普遍认为可以将软件容器化技术用作节省时间和降低成本的解决方案。 容器化的一项优势是,无需配置硬件和花费时间安装操作系统和软件来托管部署。 容器之间彼此隔离,并且多个容器可以在相同硬件上运行。 此配置可帮助我们更加高效地使用硬件,并且可以帮助提升应用程序的安全性。

另外,在传统模式中,一个软件生命周期中我们可能诸多的挑战:

  • 托管环境的管理

这些不同的环境都需要软件和硬件管理。 必须确保每个环境中已安装的软件和已配置的硬件相同。 此外,还需要以一致且易于复制的方式配置每个环境的网络访问、数据存储和安全性等方面。

  • 软件交付的连续性

将应用程序部署到环境的过程必须始终一致。 每个部署包都必须包含所有系统包、库、配置文件以及将确保应用程序功能完备的其他项。 此外,还需要确保所有这些依赖项都与软件版本和体系结构相匹配。

  • 硬件的高效使用

每个已部署应用程序都必须通过与在同一硬件上运行的其他应用程序隔离的方式运行。 我们的目标是在每个服务器上运行多个应用程序以充分利用资源,并使这些应用程序不会相互影响。

  • 应用程序可移植性

托管环境可能出现故障,或者我们可能需要横向扩展应用程序,应用程序可移植性不可或缺。我们想要将软件从一个主机移动到另一个主机, 此类移动需要尽量快速地完成,以便为客户减少停机时间。

2.2 Docker 优势

  • 更快速的交付和部署

开发人员可以通过使用镜像来快速构建一套标准的开发环境;开发完成之后,测试和运维人员可以直接使用完全相同的环境来部署代码。只要是开发测试过的代码,就可以确保在生产环境无缝运行。 Docker 可以快速创建和删除容器,实现快速迭代,节约开发、测试、部署的大量时间。

  • 更高效的资源利用

运行 Docker 容器不需要额外的虚拟化管理程序的支持, Docker 是内核级的虚拟化,可以实现更高的性能,同时对资源的额外需求很低。

  • 更轻松的资源利用和扩展

Docker 容器儿乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等,同时支持主流的操作系统发行版本。这种兼容性让用户可以在不同平台之间轻松地迁移应用。

  • 更简单更新管理

使用 Dockerfile, 只需要小小的配置修改,就可以替代以往大量的更新工作。所有修改都以增量的方式被分发和更新,从而实现自动化并且高效的容器管理。


3 Docker 架构和工作原理

Docker 官网写着这样一句话:「Build and Ship any Application Anywhere」。

Docker 采用的是 C/S 架构。Docker 客户端与 Docker 守护程序(dockerd)通信,Docker 守护程序执行构建、运行和分发 Docker 容器的工作。Docker 客户端和守护程序通过 REST API 或网络接口通信。客户端是 Docker 用户与 Docker 交互的主要方式,当用户使用命令时, 客户端发送并执行这些命令,从而调用 Docker API。用户可以使用命令,将镜像推送到配置的注册表中,或者从上面拉去所需的镜像。


(未完待续......)


用户头像

青柚1943

关注

生命不息,代码不止。 2020.08.04 加入

还未添加个人简介

评论

发布
暂无评论
Docker入坑篇_Docker_青柚1943_InfoQ写作社区