Docker到底是不是一个玩具? 或者说这仍然是真的吗?

您好!

我真的很想直入主题,但更正确的说法是讲一下我的故事:

输入

我是一名程序员,拥有在服务器上开发前端单页应用程序、scala/java 和 Nodejs 的经验。

在相当长的一段时间内(肯定是一两年或三年),我认为 Docker 是天赐之物,总的来说是一个非常酷的工具,绝对每个开发人员都应该能够使用它。 由此可见,每个开发人员都应该在他们的本地计算机上安装 Docker。 我的意见呢,看看同一天发布的职位空缺……。 每一秒都会提到 docker,如果你拥有它,这将是你的竞争优势😉

在路上,我遇到了很多人,他们对 Docker 及其生态系统有着不同的态度。 有人说这是一个方便的东西,保证了跨平台功能。 第二个不明白为什么他们应该在容器中运行以及从中获得什么利润,第三个根本不关心也不打扰(他们只是写了代码就回家了 - 我羡慕他们,由方式 :)

使用理由

我为什么使用docker? 大概有以下几个原因:

  • 数据库启动,99%的应用程序使用它们
  • 启动 nginx 进行前端分发并代理到后端
  • 你可以将应用程序打包在docker镜像中,这样我的应用程序将在任何docker存在的地方运行,分发问题立即得到解决
  • 开箱即用的服务发现,可以创建微服务,每个容器(连接到公共网络)都可以通过别名轻松到达另一个容器,非常方便
  • 创建一个容器并在其中“玩”很有趣。

我一直不喜欢 docker 的地方:

  • 为了让我的应用程序正常工作,我需要在服务器上安装 Docker。 如果我的应用程序在 jre 或 nodejs 上运行并且它们的环境已经在服务器上,为什么我需要这个?
  • 如果我想在远程服务器上运行我的(私有)本地构建的映像,那么我需要我自己的 docker 存储库,我需要注册表在某个地方工作,并且我还需要配置 https,因为 docker cli 只能通过 https 运行。 哦该死...当然,还有一些选项可以通过以下方式将图像保存在本地 docker save 然后通过 scp 发送图像...但这需要很多身体动作。 此外,在您自己的存储库出现之前,它看起来像是一个“拐杖”解决方案
  • docker-compose。 只需要运行容器即可。 就这样。 他无能为力。 Docker-compose 有很多版本的文件,有自己的语法。 无论它多么声明,我都不想阅读他们的文档。 我在其他地方不需要它。
  • 在团队中工作时,大多数人写 Dockerfile 的方式很歪,不明白它是如何缓存的,将自己需要和不需要的所有内容添加到镜像中,继承 Dockerhub 或私有存储库中没有的镜像,创建一些 docker-compose 带有数据库的文件,并且没有任何内容保留。 与此同时,开发人员自豪地宣称 Docker 很酷,一切都在本地为他们工作,HR 在空缺职位中重要地写道:“我们使用 Docker,我们需要有这样工作经验的候选人。”
  • 我经常被在 Docker 中提升一切的想法所困扰:postgresql、kafka、redis。 遗憾的是,并非所有东西都可以在容器中运行,也不是所有东西都易于配置和运行。 这是由第三方开发人员支持的,而不是由供应商本身支持的。 顺便说一句,问题立即出现:供应商不担心在 Docker 中维护他们的产品,这是为什么,也许他们知道一些事情?
  • 关于容器数据的持久性的问题总是会出现。 然后你会想,我应该挂载主机目录还是创建一个 docker 卷或创建一个数据容器(现在是这样) deprecated? 如果我挂载一个目录,那么我需要确保容器中用户的uid和gid与启动容器的用户的id匹配,否则容器创建的文件将以root权限创建。 如果我使用 volume 那么数据将简单地在某些地方创建 /usr/* uid 和 gid 的情况与第一种情况相同。 如果您要启动第三方组件,则需要阅读文档并寻找以下问题的答案:“组件在哪些容器目录中写入文件?”

我一直不喜欢这样一个事实:我必须花很长时间修改 Docker 在初始阶段:我弄清楚了如何启动容器、从什么映像启动、制作了包含长 Docker 命令别名的 Makefile。 我讨厌 docker-compose,因为我不想学习 docker 生态系统中的另一个工具。 和 docker-compose up 这让我很困扰,尤其是如果他们仍然在那里见面的话 build 结构,而不是已经组装好的图像。 我真正想要的只是高效、快速地制造产品。 但我不知道如何使用 docker。

介绍 Ansible

最近(三个月前),我在一个 DevOps 团队中工作,几乎每个成员都对 Docker 持消极态度。 原因:

  • docker 规则 iptables(尽管您可以在 daemon.json 中禁用它)
  • docker 有问题,我们不会在生产中运行它
  • 如果 docker 守护进程崩溃,那么所有具有基础设施的容器都会相应崩溃
  • 不需要码头工人
  • 如果有 Ansible 和虚拟机,为什么还要使用 docker

在同一份工作中,我熟悉了另一个工具——Ansible。 我听说过一次,但我没有尝试编写自己的剧本。 现在我开始写我的任务,然后我的愿景完全改变了! 因为我意识到:Ansible 具有用于运行相同 docker 容器、镜像构建、网络等的模块,并且容器不仅可以在本地运行,还可以在远程服务器上运行! 我高兴极了 - 我找到了一个普通工具并扔掉了我的 Makefile 和 docker-compose 文件,它们被 yaml 任务替换了。 通过使用类似的结构减少了代码 loop, when等等。

用于运行数据库等第三方组件的 Docker

我最近开始熟悉 ssh 隧道。 事实证明,将远程服务器的端口“转发”到本地端口是非常容易的。 远程服务器可以是云中的计算机,也可以是 VirtualBox 中运行的虚拟机。 如果我的同事或我需要数据库(或其他第三方组件),我们可以简单地使用该组件启动服务器,并在不需要服务器时将其关闭。 端口转发与在 Docker 容器中运行的数据库具有相同的效果。

此命令将我的本地端口转发到运行 postgresql 的远程服务器:

ssh -L 9000:本地主机:5432 [电子邮件保护]

使用远程服务器解决了团队开发的问题。 这样的服务器可以同时由多个开发人员使用;他们不需要能够配置 postgresql、了解 Docker 和其他复杂的知识。 在远程服务器上,如果安装特定版本有困难,您可以在 Docker 本身中安装相同的数据库。 开发人员所需要的只是提供 ssh 访问权限!

我最近读到,SSH 隧道是常规 VPN 的有限功能! 您只需安装 OpenVPN 或其他 VPN 实现、设置基础设施并将其提供给开发人员使用即可。 这太酷了!

幸运的是,AWS、GoogleCloud 和其他公司为您提供一年的免费使用权,所以请使用它们! 如果您在不使用时将其关闭,它们会很便宜。 我一直想知道为什么我需要像 gcloud 这样的远程服务器,看来我找到了它们。

作为本地虚拟机,您可以使用相同的 Alpine,它在 docker 容器中积极使用。 好吧,或者其他一些轻量级发行版可以使机器启动更快。

底线:您可以而且应该在远程服务器或 virtualbox 中运行数据库和其他基础设施。 我不需要 docker 来实现这些目的。

关于 docker 镜像和分发的一些知识

我已经写过了 文章 我想表达的是,使用 docker 镜像并不能提供任何保证。 仅在创建 Docker 容器时才需要 Docker 映像。 如果您要升级到 docker 映像,那么您将升级为使用 docker 容器,并且您将只使用它们。

您是否见过软件开发人员仅在 docker 镜像中移植其产品的地方?
大多数产品的结果是针对特定平台的二进制文件;它们只是添加到从所需平台继承的 docker 映像中。 你有没有想过为什么 dockerhub 上有这么多类似的镜像? 以nginx为例,你会看到100500张来自不同人的图像。 这些人本身并没有开发 nginx,他们只是将官方 nginx 添加到他们的 docker 镜像中,并使用自己的配置对其进行调味,以方便启动容器。

一般来说,你可以简单地将它存储在 tgz 中,如果有人需要在 docker 中运行它,那么让他们将 tgz 添加到 Dockerfile,从所需的环境继承并创建额外的包,这些包不会改变 tgz 中的应用程序本身。 任何将创建 docker 镜像的人都会知道 tgz 是什么以及他需要做什么。 这就是我使用docker的方式 这里

底线:我不需要 docker 注册表,我将使用某种 S3 或仅使用文件存储,例如 google Drive/dropbox

CI 中的 Docker

我工作过的所有公司都是类似的。 他们通常是杂货店。 也就是说,他们有一个应用程序、一个技术堆栈(好吧,可能是一两种或三种编程语言)。

这些公司在运行 CI 流程的服务器上使用 docker。 问题:为什么需要在服务器上的 docker 容器中构建项目? 为什么不直接为构建准备一个环境,例如,编写一个 Ansible playbook 来安装必要版本的 nodejs、php、jdk,将 ssh 密钥等复制到将进行构建的服务器?

现在我明白这是搬起石头砸自己的脚,因为docker的隔离并不能带来任何利润。 我在docker中使用CI遇到的问题:

  • 同样,您需要一个 docker 映像来构建。 您需要查找图像或编写自己的 dockerfile。
  • 90% 你需要转发一些 ssh 密钥,以及你不想写入 docker 镜像的秘密数据。
  • 容器创建并消亡,所有缓存都随之丢失。 下次构建时会重新下载所有项目依赖,既费时又无效,时间就是金钱。

开发人员不会在 docker 容器中构建项目(我曾经是这样的粉丝,真的,我为过去的自己感到难过 xD)。 在java中,可以有多个版本,并用一个命令将它们更改为您现在需要的版本。 在nodejs中也是一样,有nvm。

结论

我相信docker是一个非常强大和灵活的工具,这是它的缺点(听起来很奇怪,是的)。 在它的帮助下,公司可以轻松地迷上它,并在需要和不需要的地方使用它。 开发人员启动他们的容器和一些环境,然后一切顺利地流入 CI 和生产。 DevOps 团队正在编写某种代码来运行这些容器。

仅使用 docker 最近的 工作流程中的阶段,不要一开始就把它拖到项目中。 它不会解决您的业务问题。 他只会把问题转移到另一个层面并提供他自己的解决方案,你会做双重工作。

当需要docker时:我得出的结论是,docker 非常擅长优化给定的进程,但不擅长构建基本功能

如果您仍然决定使用 docker,那么:

  • 要非常小心
  • 不要强迫开发者使用docker
  • 将其使用本地化在一处,不要将其分散到所有 Dockefile 和 docker-compose 存储库中

PS:

感谢您的阅读,祝您在事务中做出透明的决定并度过富有成效的工作日!

来源: habr.com

添加评论