NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

“救世主”Docker

  • 2021-04-09
  • 本文字数:2849 字

    阅读完需:约 9 分钟

“救世主”Docker

本文最初发布于 towards data science 博客,经原作者授权由 InfoQ 中文站翻译并分享。

前言

在一个快速变化的环境中工作,越来越多的工具以开源的方式发布,我的笔记本电脑已被我搞得一团糟。我安装了大量的应用程序,却忘了清理它们。类似地,我也用 Python 做过一些事情——没有虚拟环境,所以基本上,很多库分散在笔记本电脑上的各个地方。


最初,我的解决方案是从笔记本电脑中删除 Python 和所有其他杂七杂八的东西。但后来我发现,如果我为一篇博文或与工作相关的事情做 PoC,最终也会遇到同样的情况。然后我找到了 Docker。我花了一段时间弄明白了它的工作原理,以及自己该如何利用它。

准备工作

如果想跟着我做,那么你应该做好以下准备工作:


  • 官网下载 Docker

  • 某种 IDE,或者使用终端或 Jupyter Notebooks

理解 Docker 是什么

那么,Docker 是什么?这个魔术大师是怎么解决我的问题的?


Docker 是一个平台。你可以创建一个特定的配置包,并在你自己的隔离环境(我们称之为容器)中运行它。在某种程度上,容器与虚拟机非常相似。你可以轻松创建一个轻量级容器,其中仅包含一些相关的库和应用程序,并在其上运行代码。如果你决定与别人分享代码,则只需要分享 Docker 镜像。


那么镜像又是什么?一些用来设置容器的指令,其中包含所有的配置,以及工作目录中的相关文件。


因为它是一个平台,所以我们有一个服务器-客户端关系。


  • 客户端——最有可能是 CLI,用于和 Docker 引擎交互;

  • 服务器——在 Docker 引擎中编排和映射不同的东西;

  • 注册中心——存储 Docker 镜像的地方,后续可以被其他用户拉取。


好了,理论讲够了,我们来实践一下。

开始

好了,首先检查下 Docker 版本:



如果看到任何 Docker 版本输出,就可以开始了。


如果你多少了解一些终端的基本知识,那么你可能很熟悉下面这条命令:


ps
复制代码


这条命令会列出所有运行中的进程及其 PID。Docker 也提供了类似的命令:



可以看到,正在运行的 Docker 进程数为 0。如何让 Docker 进程运行起来呢?可以像下面这样:



让我们分别做下说明:


  • docker—— 在 Docker 上运行;

  • run—— 创建/拉取并运行容器;

  • hello-world—— 要加载到容器的镜像。

Postgres 数据库

假如我们要运行 Postgres DB 来做一些 PoC。为此,我们需要完成以下工作:


  • 在 Docker Hub 或我们的私有库中找到相应的 Docker 镜像;

  • 确定我们将要使用的版本;

  • 在 Docker 上运行它。

步骤 1

如果我们在谷歌上搜索 docker Postgres,那么最上面就是指向 Postgres 镜像的 Docker Hub链接。从中我们可以看到关于该镜像的大量信息及其用法。

步骤 2


我们看到,这里有 13.2、13、latest、13-alpine。这是什么意思呢?


举例来说,数字 13.2 表示一个特定的 Postgres 版本。Latest 指最新版本,如果有新版本,就会更新。最后但同样重要的是 alpine 版本。Alpine 版本是应用程序运行所需的最基本的框架。Alpine 版本会尽可能轻量化,它只包含必要的部分,比其他版本小。使用 alpine 的好处是可以最低限度地添加相关的东西。这样可以保证 Docker 容器尽可能小,易于移动和部署。


我们选 13.2。

步骤 3

执行以下命令:


docker run postgres:13.2
复制代码



好吧,有东西没运行,让我们看下出了什么问题——我们需要通过**-e**(是指环境变量)传入密码:



我们看到,终端进入运行进程模式,要在同一个会话中执行某些操作,就需要终止 Postgres 进程。有一种方法可以让我们在同一个终端会话上运行 Postgress docker 进程,并做一些事情。我们可以使用**-d**来运行分离式进程。



上述命令返回了一个长字符串。该字符串是 Docker 容器的 ID。如果运行 docker ps,就可以看到 Docker 容器已经启动并运行:



可以看到,命令 docker ps 返回的容器 id 和 docker run 返回的容器 id 不一样。仔细看下可以发现,docker ps 返回的字符串是那个长字符串的子串。Docker 很酷的一点是,它匹配容器 id 的开头,你不需要粘贴其完整版本!


但等一下,我不是说 Docker 是个隔离的环境吗?是的。我们不会对数据库做任何事情,因为我们没有公开任何可以用来与它交互的端口。要做到这一点,我们需要借助**-p**:


docker run -e POSTGRES_PASSWORD=myplaintextpassword -p HOST_PORT:DOCKER_CONTAINER -d postgres:13.2
复制代码

Dockerfile

好了,现在你可能会问,为什么这个家伙要向我解释如何输入这么一长串命令来运行一些隔离的东西,重复而乏味。我如何分享它?把命令发给下一个人?那并不是十分有效…


是的,玩一下可以,但要创建一个环境,这就不合适了。这就是为什么要有 Dockerfile。


基本上,Dockerfile 就是所有这些环境变量映射出来的指令。因此,对于 Postgres,可以创建这样一个 Dockerfile:



要进行构建,在 Dockerfile 所在的文件夹下运行如下命令:


docker build .
复制代码


输入如下所示:



bd9416c1457a 是新构建的 Docker 镜像的 id。现在,我们可像下面这样运行容器了:



值得一提的是,Docker 在每一步构建 Dockerfile 时,都会创建一个新的 Docker 镜像并将其传递给下一步。所有这些镜像都保存在缓存中,如果有需要就可以重用它们,例如,在末尾添加一个新的环境变量:



它的好处是,如果我们只在末尾做了修改,就可以更快地构建镜像。我们只需要从头开始构建新添加的部分!不过,如果我们要改变密码和用户名的位置,就不得不重新构建镜像了:


与容器交互

如果你希望优雅地关闭容器,可以使用如下命令:


docker stop CONTAINER_ID
复制代码


你也可以使用如下命令杀掉它:


docker kill CONTAINER_ID
复制代码


稍后,你可以使用如下命令查看已经停掉的进程:



如果要恢复容器,则可以通过以下命令:


运行多个 Docker 进程

好了,运行一个 Docker 进程很简单;我们创建一个 Dockerfile 并运行它。如果我另外还需要一个进程,我也可以创建并运行它。但这很快就会失去控制,因为每个 docker run 都需要设置端口和其他信息。


对于这种情况,可以使用 docker-compose

Docker compose

这是一个 YAML 文件,关于构建内容以及如何使用多个不同的 Dockerfile,其中包含了更多的信息。



让我来介绍一下:


  • version—— Compose 文件格式的版本。对照Docker文档,看下你的 Docker 引擎是否兼容;

  • app —— 使用一些预定义 Docker 镜像(即 airflow)的应用程序/服务,8080 端口映射到本机的 8080 端口;

  • db —— 一个数据库应用程序,我们将使用数据库目录下的 Dockerfile 把它容器化。


如果我们已经有这个文件了,该如何构建呢?如果已经在这个目录下,则可以执行以下命令:


docker-compose up -d --build
复制代码


此外,你也可以指定这个文件的完整路径:


docker-compose -f "PATH/YOU/HAVE/PUT/DOCKERCOMPOSE/FILE/docker-compose.yml" up -d --build
复制代码

总结

Docker 简化了开发工作。创建一个镜像,在上面运行你的应用,看看它是否可以工作。


我之所以使用 Docker,有以下几个方面的考虑:


  • 需要一个隔离的环境来进行基准测试/测试等(借助 GitHub Actions 和 Travis,你可以在 Docker 镜像中测试你的应用);

  • 测试版本升级,看看是否造成了什么破坏;

  • 如果你懒得清理本机环境,它就会变得一团糟。


顺便说一下,代码托管在GitHubhttps://github.com/TomasPel/workshops/tree/main/docker_101)上,你可以在 Jupyter Notebook 中交互式地运行它并查看结果。


原文链接:


https://towardsdatascience.com/docker-101-ee3d2b8ace11

公众号推荐:

跳进 AI 的奇妙世界,一起探索未来工作的新风貌!想要深入了解 AI 如何成为产业创新的新引擎?好奇哪些城市正成为 AI 人才的新磁场?《中国生成式 AI 开发者洞察 2024》由 InfoQ 研究中心精心打造,为你深度解锁生成式 AI 领域的最新开发者动态。无论你是资深研发者,还是对生成式 AI 充满好奇的新手,这份报告都是你不可错过的知识宝典。欢迎大家扫码关注「AI前线」公众号,回复「开发者洞察」领取。

2021-04-09 10:002680
用户头像
刘燕 InfoQ高级技术编辑

发布了 1112 篇内容, 共 493.9 次阅读, 收获喜欢 1967 次。

关注

评论

发布
暂无评论
发现更多内容

前端架构师神技,三招统一代码风格

杨成功

大前端 架构师 代码规范 代码格式化 签约计划第二季

微博系统中”微博评论“的高性能高可用计算架构

Geek_cb2b43

在线火星文转换器工具

入门小站

工具

1.《重学JAVA》开篇

杨鹏Geek

Java Java 25 周年 28天写作 12月日更

架构实战营 - 模块5 - 作业

lucian

架构实战营

记录:一个从0-1打磨演讲的技术专家

将军-技术演讲力教练

微博评论的高性能高可用架构设计

zjluoyue

互联网公司如何塑造一支有创业精神的技术团队?

阿里巴巴中间件

创业 阿里云 中间件

模块五作业

小鹿

Rust 元宇宙 12 —— 序列化和存储

Miracle

rust 元宇宙

Prometheus Exporter (十四)MySQL Server Exporter

耳东@Erdong

MySQL Prometheus 28天写作 12月日更

微信小程序开发:新建文件报错Error:pages/xxx/xxx.json Expecting ’STRING’,’NUMBER’,’NULL’,’TRUE’

三掌柜

28天写作 12月日更

模块五作业

侠客行

架构实战营 「架构实战营」

架构实战-模块五

唐敏

「架构实战营」

Dubbo-Admin 正式支持 3.0 服务治理

阿里巴巴中间件

阿里云 云原生 dubbo 中间件 服务治理

TypeScript 之常见类型(下)

冴羽

JavaScript typescript 翻译 大前端

数据也需要滴血认亲?

Justin

大数据 数据治理 28天写作

架构训练营 - 模块五作业

VegetableBird

架构实战营 架构师实战营 「架构实战营」

模块五作业

panxiaochun

架构实战营

模块五作业

心怀架构

微博系统中”微博评论“的高性能高可用计算架构设计

stars

架构训练营

如何掌握智识?

卢卡多多

28天写作 12月日更

如何构建“深入浅出,喜闻乐见”的界面

Ian哥

28天写作 沟通界面 深入浅出 喜闻乐见

架构实战营第五课作业微博评论高性能高可用架构

Geek_99eefd

架构实战营 「架构实战营」

从deadline和被狗追说起(2/28)

赵新龙

28天写作

有人问你什么是CAP?你就把这篇文章发给他

李子捌

redis CAP理论 28天写作 12月日更

聊聊SAAS

Im胡子

SaaS

ASP.NET Core中三个egg疼的路由函数

喵叔

28天写作 12月日更

基于云的技术架构设计实践-第1篇

hackstoic

云计算 容器 云原生 CI/CD 签约计划第二季

x

Nydia

自定义规则删除过期文件(linux)

liuzhen007

28天写作 12月日更

“救世主”Docker_AI&大模型_Tomas Peluritis_InfoQ精选文章