fyang 的博客

首页 文章

Devops实践——容器化开发环境

前言

本文我将介绍使用容器化技术来构建我们的开发环境,并且提供一个具体的项目构建例子来演示如何构建容器化开发环境。

为什么要容器化开发环境

先回顾一下我们的软件开发流程:

  1. 创建项目并确认版本依赖(编译工具版本和依赖库版本)
  2. 编写项目代码
  3. 提交项目代码到远程仓库。

协作人员则需要进行一下步骤:

  1. 从远程仓库拉取项目代码
  2. 手动安装编译工具以及必要的项目依赖和开发工具
  3. 编写项目代码
  4. 提交到远程仓库

这会带来哪些问题呢?

  1. 对于项目运行环境缺乏强约束(这通常不会有问题,但谁能保证呢)
  2. 协作人员需要手动安装各种依赖,增加了进入项目的难度(对于一个大型项目通常会需要详细的文档说明去阐述如何运行项目和注意事项,但是无法保证参与者能够准确无误的按照文档执行)
  3. 一旦开发环境遭到破坏,就需要手动清理环境并重新执行上步骤

那容器化开发环境的优势呢:

  • 一致性开发环境

    保证开发人员拥有相同的开发环境,降低项目开发风险。必要时还可以对开发、测试、生产的所有运行环境进行统一,而这在非虚拟化环境上通常是无法实现的(比如开发人员使用 windows ,而生产环境则运行的 Linux

  • 声明式环境依赖

    所有的环境都是可解释、可记录的,随时可以调整和更新并且随项目进行版本管理

  • 自动化环境构建

    开发人员无需手动搭建开发环境,且在开发环境遭受破坏时能够迅速的重建

  • 轻量级

    容器化的开销通常是可接受的。

容器化开发环境可能面临的问题:

  • 由于容器化的隔离而导致项目之间的通讯受阻,比如多个微服项目之间的相互调用。
  • 强依赖于开发工具,比如本文中的例子就强依赖于VS Code
  • 对于客户端软件开发不友好,比如 electron应用安卓应用
  • 有一定的学习门槛,需要掌握容器化的相关知识。

项目实践

环境依赖

  • VS Code

    依赖于 VS CodeRemote Development 插件, devcontainer 是开放标准,对于其他编辑器的支持需要大家自行查阅。

  • Git

    项目协作使用

  • Docker

    其余的容器运行时理论上也支持,本文暂以 Docker 为例

构建容器化项目

接下来我将通过一个 rust 项目来演示如何去构建容器化开发环境

我本地没有安装rust工具链,所有对于项目的操作都将在容器中进行。

我们先创建项目:

docker run --rm --workdir=/app --user=$UID -v.:/app rust cargo new devcontainer-demo-rs

使用上述命令我们可以在容器中初始化 rust 项目,本地无需安装 rust

然后我们在项目根目录创建.devcontainer文件夹并添加文件devcontainer.json文件,内容如下:

{
  "name": "rust devcontainer",
  "forwardPorts": [
    8080
  ],
  "image": "mcr.microsoft.com/devcontainers/rust:1",
  "customizations": {
    "vscode": {
      "extensions": ["swellaby.rust-pack"]
    }
  },
  "onCreateCommand": "cargo check"
}

内容详解:

name: 声明容器环境的名称,无意义,仅做标识

forwardPorts: 声明容器要暴露的端口,VScode 会自动把端口映射到本地 localhost 方便调试

image: 想要使用的镜像名称,本例中使用的为Vscode提前打包好的Rust容器镜像,包括了一些开发所必要的工具,比如ssh、git等

customization: devcontainer规范保留的扩展字段,可以给下游集成使用,比如本例中就声明了 VS Code 中的 rust 插件包,这样在容器启动时 VS Code 会自动安装相应的依赖插件。

onCreateCommand: 容器启动回调,在本例中我们在回调中执行了cargo check命令,则在容器启动后会自动安装项目依赖和检查代码

更多用法请参考 devcontainer 文档

然后在 VS Code 中打开项目(项目根目录执行code .或者在 VS Code 中手动选择目录)

安装 Remote Development 插件之后,应该会自动提示我们在容器中打开该项目,也可以手动选择命令Dev containers: open folder in container: open folder in container

等待初始化完毕之后,我们的项目应该就能够在容器中进行调试和开发了。

总结

实际上,我们这个项目的容器化构建还是非常容易的,在提交了.devcontainer/container.json 文件之后,所有的开发人员都可以通过这个文件来构建我们项目的开发环境,而无需其余的本地依赖。

我认为容器化开发环境进一步完善了我们项目的 Devops 流程,尽管声明式配置增加了我们项目初始化的配置工作,但对于后续的开发和维护我想是非常值得的。

本例中使用了 devcontainer 社区预构建的容器运行时,在实际开发中,我们可以根据自己的需求去针对项目定制更复杂的容器环境和相关配置。

参考文档