我在生产环境中的 AWS 上部署以 Docker 打包的 Elixir。
这曾经是我首选的做事方式,但现在我更倾向于使用 Packer 创建自己的 AMI,并预先安装所有内容。
部署的核心是控制,在某种程度上我觉得在利用 Docker 时已经放弃了控制。
Docker 的主要缺点是它限制了 Erlang/Elixir 的功能,例如通过epmd 的节点间连接。这也意味着remsh 几乎是不可能的,而酷炫的:observer.start 是不行的。如果您出于某种原因需要与生产节点进行交互,那么首先 ssh-ing 进入服务器、进入 Docker 等存在额外的障碍。当它只是检查某些东西时很好,当生产正在燃烧时令人沮丧痛苦地倒下。在一个节点中启动多个容器有点没用,因为 BEAM 可以有效地利用您的所有内核。热升级实际上是不可能的,但这并不是我们个人具有内在业务需求的功能。
已努力让 epmd 在容器设置中工作,例如:https://github.com/Random-Liu/Erlang-In-Docker,但这需要您重新构建 Erlang 以进行自定义 net_kernel 修改。
亚马逊最近发布了 AWS ECS 的一项新功能,AWS VPC Networking 模式,这可能有助于容器间的epmd 通信,从而直接连接到您的节点。我还没有验证过。
除了epmd 通信的问题之外,还有部署时间的问题。使用 Docker 创建你的镜像,即使你的镜像只有 5MB,很快就会占用 300MB,其中 200MB 仅用于创建你的发布的所有各种依赖项。可能有办法减少这种情况,但这需要专业知识和专门的努力。我会将这个额外的空间更多地归类为烦恼而不是破坏交易,但相信我,如果您必须等待 25 分钟才能完成不可变部署,那么您可以节省的任何一分钟都是值得的。
在性能方面,我没有注意到裸机部署和 docker 部署之间存在显着差异。 AWS EB Docker 很好地将容器资源扩展到 EC2 实例的资源。
优势当然是便携性。如果您的前端工程师需要使用 JSON API,那么就本地开发而言,这是一个巨大的胜利,通过一些仔细的设置,他们可以生成在本地运行的最新 api,而无需了解 Erlang/Elixir /Rserve/Postgres。
此外,供应商锁定也大大减少,尤其是自从 AWS 推出对 Kubernetes 的支持以来
这是一个权衡的问题,如果您是需要投入生产的开发人员并且对 Devops 了解很少,那么可能需要进行 Docker 部署。如果您更熟悉基础架构、部署等,那么作为开发人员,我相信创建自己的 AMI 可以让您更好地控制自己的环境。
总而言之,我鼓励至少玩弄Docker 并尝试一下,它可能会打开一个新的可能性领域。