前言
容器化,这个完全由 Linux 的优秀设计而诞生的功能,已经逐渐成为软件运维部署的主流选择。时至今日,它不光是作为传统的运维工具,同时它也在解决软件依赖和项目部署难度。今天已经有非常多的开源项目支持容器化部署,使得软件的使用者无需关注软件依赖,从而降低使用者的认知成本和学习难度。
而今天我将给大家介绍一下 devcontainer 技术,它把容器化的优势代入到了我们的开发流程,从而弱化我们的开发环境依赖,使得远程开发、云开发技术有更大的发挥空间。
在写下此篇文章的今天,我已经使用远程开发配合容器化技术超过三年,几乎所有我参与的项目都是用容器化远程开发,期间一直拥有非常良好的开发体验;越来越多的开源项目也在支持 devcontainer 技术,我想它需要让更多的人了解到。
什么是devcontainer
devcontainer 是一个开放的标准和规范,我们可以通过一些声明式的配置来对项目配置开发环境,在容器内集成软件依赖,甚至通过容器编排技术可以集成数据库等服务,把软件依赖集成到项目管理内,而不是散落到文档以及开发人员的共识上。它支持 VS Code、Jetbrians IDEA 等常见的 IDE 软件。
devcontainer 技术是对运维即代码的 devops 理念的又一次实践,我们通过声明式配置方式使得机器能够自动化部署我们所需要的开发环境,提高了我们的软件开发效率,同时它也能够在软件依赖上保持与生产环境的一致性,从而降低由于环境的不确定性所带来的软件开发风险。
早在几年前我就看到了容器化开发环境的优势,不过当时我都是自己手动的针对项目构建所需要的容器环境,在接触到 devcontainer 之后我就迅速迁移过来了,从此走上了自动化的康庄大道。
为什么要使用devcontainer
假如你是一个 java 开发人员,你刚进入公司从事开发工作,那么你上班的第一件事一定是拿到新的开发机器并根据公司项目需求安装合适的 jdk、maven、配置 maven 镜像代理、甚至要在本地安装 Mysql 等数据库软件,然后再去公司的 git 仓库 拉取最新的代码并使用 IDE 工具打开项目再进行后续的正式工作内容。
这个过程你需要安装和配置一大堆东西,有的工具可能又有其它依赖,如果中间某个过程出现了问题,你又需要排查错误,修复环境,等环境配置好了之后,你的项目有可能还是启动不起来,它可能还有一些其他的外部依赖你的老大忘了告诉你。等你一切准备就绪终于把项目跑起来了,ok,要下班了,不知不觉就摸了一天鱼,新公司真好啊😂。未完待续~
假设我们公司使用 devcontianer 技术呢?
你进入公司,拿到开发机,安装 docker ,拉取项目代码,然后使用 IDE 打开,你就获得了完整的开发环境,可以直接一键运行,ok,十分钟开发环境配置完毕,还有 7 小时零 50 分钟可以干活,真是充实的一天😏
对于一个刚接触项目的开发人员,给他提供一个开箱即用的开发环境和让他自己配置一些列开发所需要的软件依赖之后再进行项目开发,孰优孰劣显而易见。这点对于开源软件也是很重要的,复杂的开发环境配置会让一些想要参与项目协作的人员望而却步。
现代操作系统是复杂的,尤其是涉及到桌面环境,windows 复杂的注册表,linux 复杂的软件依赖管理,以及不断膨胀的开发环境都在不断影响着我们开发环境的稳定性。一旦我们的开发环境遭受破坏,那么我们就需要付出很多精力去修复它,甚至无法修复时我们只能无奈重新安装操作系统,从而直接阻断了我们的开发工作。
而使用 devcontainer 技术,如果开发环境遭受破坏,我们可以非常轻松的重新构建一个全新的开发环境,使得我们的开发环境和桌面办公环境进行了解耦,甚至你可以直接在服务器上进行开发,从而从根本上避免桌面环境的不稳定对开发环境带来的影响。
使用 devcontainer 要牺牲什么
从我长期实践的经验来看,它的优势是非常必要的,但是也有一些问题需要注意。
容器化带来的一定的性能损失和磁盘冗余,在算力和存储能力充足的今天并不重要,不过容器化的环境在打开时相比于传统的裸机开发会稍慢,或者稍麻烦一些。
对于开发工具强依赖,比如我自己就重度使用 VS Code 进行开发工作。
容器化导致的网络通讯问题,由于开发环境跑在容器内部,从而导致了在项目之间通讯会比较麻烦,比如你的前端项目容器需要访问后端项目容器时,如果前端和后端分别处于不同的容器内部,就需要考虑通信问题,个人推荐给相关容器配置相同的虚拟网卡 (docker network create ... 使用 bridge 模式即可) ,这样就可以在容器之间使用 服务名 进行访问,从而避免了动态 ip 带来的问题。还有本地访问容器环境的问题,有些时候可能本地环境和容器隔着好几个网段和机器,这样就导致你在本地可能无法访问到容器,这点在使用 VS Code 的 Remote Development 插件时能够自动对容器和本地之间做端口映射,从而让你可以直接从 localhost+端口 的方式访问容器内部的服务。
还有就是对于客户端开发的不友好,比如 electron 开发、安卓开发等,这些软件的开发强依赖于本地的显示设备以及图形驱动,使用容器化开发会有诸多不便,也不是一定不行,但是可能会比较麻烦,如果确有需求可能需要深入了解和配置,我想有人能够在容器内部跑 osx,那跑其他客户端软件应该也不再话下😜
最后
everything is container ! 容器化是每个现代化程序员的必修课,我想在不久的将来我们将有更多的算力迁移至云端,远程开发也应该是现代开发工具应该专注的核心功能之一。
考虑到篇幅长度,本文仅涉及 devcontainer 的理论介绍部分,我会在再补充一篇 devcontainer 的实践演示文章。感兴趣的小伙伴可以继续关注。