CSDN|如何在容器内高效编程?


【CSDN|如何在容器内高效编程?】CSDN|如何在容器内高效编程?
本文插图
作者 | Daniel Lemire 译者 | 苏本如 , 责编 | 郭芮 出品 | CSDN(ID:CSDNnews) 我个人的编程环境中包括了一些服务器、笔记本电脑和台式电脑 。 我的服务器是在不同的时间购买和配置的 , 根据需求不同 , 它们有不同的硬件和软件配置 。 这些硬件的处理器不同 , AMD、英特尔、Ampere和Rockchip的处理器都有 。 同时这些机器上安装有各种各样的Linux发行版 , 包括各种旧版本和新版本 。 在实验室技术人员帮助我做好初始设置后 , 基本上这些电脑所有的管理工作都是由我一人负责 。所以 , 最终我时常面对这样的情形:有时候我会遇到一些非常有趣的系统 , 这些系统都带有旧的Linux发行版 , 而重新安装新Linux发行版并保证它的安全并非易事 。 而且 , 即使我费尽心力地更新了我的Linux发行版 , 我最终也可能会得到一个与我的合作者不同的Linux发行版 , 使用不同的编译器等等 。 更不用说在同一个Linux发行版上安装多个不同的编译器是一件非常耗费时间的事 。那么 , 应对这种问题 , 你能做些什么呢? 你可以运行虚拟机 。 使用VirtualBox之类的工具 , 你可以在Windows和 macOS中运行Linux 。 这种方式很简单 。 然而 , 它速度很慢 , 而且计算的代价高昂 。你可以切换到容器 , 特别是Docker容器 , 它们的开销要少得多 。 Docker现在已经是云计算中无处不在的工具 。 作为一个简单的描述 , 你可以把Docker看作一个允许你在Linux中运行Linux的容器 。 Docker实际上是一个沙箱 , 但它是一个几乎可以直接在主机上运行的沙箱 。 与虚拟机不同 , 我的测试显示 , 在计算密集型任务中 , Docker容器可以以“原生速度”(裸机速度)运行 。 有报道称Docker的交互速度较慢 , 网络连接和磁盘访问速度也较慢 。 但就我的用途而言 , Decker能很好地满足我的要求 。当然 , 如果必须的话 , 你也可以在macOS和Windows下运行Docker容器 , 不过我想这样做会需要更多的开销 。容器方法的思想始终是基于系统的起始状态 。 比如说 , 你定义了你的数据库服务器需要的配置 , 并且每次都以这种精确的状态(配置)来启动它 。 这样就使得你的基础架构具有可预测性 。这听起来不是那么完美 。 你仍然必须依赖于你的容器的起始配置 。 如果两个具有不同要求的应用程序需要在同一个映像中一起运行 , 那么你可能需要进行各种配置操作 。话虽如此 , 容器仍然工作得很好 , 它们基本上成了维系我们当令技术文明的基础:许多基于云的应用程序都是以某种方式基于容器的 。容器的目是将软件部署到生产环境中去 。 在容器内编程是不被直接支持的:你将找不到关于容器编程的很多文档 , 而且围绕着容器编程也根本没有什么业务模型 。 那么这里我提到的“在容器内编程”是什么意思呢?我的意思是:我要启动一个C编程项目 , 决定使用Linux Ubuntu16.10发行版 , 并在Linux Ubuntu16.10下编译和运行我的代码 , 即使我的服务器可能运行完全不同的Linux发行版(或者可能在macOS下) 。第一个问题是 , 你的磁盘和从容器构建来的映像的磁盘是不同的 。 正在运行的映像无法自由访问底层服务器(主机) 。 记住容器本质上是一个沙箱 。因此 , 你只可以在映像里面做所有的工作 。 但是 , 请记住 , 容器技术的重点是始终从原始状态开始 。 如果你加载了一个图像 , 做了一些工作 , 然后离开……你的工作就不见了 。 映像被设计成是不可变的 。 这是一件很好的事情 , 因为这保证了你不会因为一不小心就把映像弄乱 。在映像中完成一些工作后 , 可以为新状态拍摄快照 , 提交它并创建一个新映像 , 再从中重新开始 。 这个过程既复杂又不实用 。那么你能做什么呢?你可以做的是保持映像的无状态 , 就像一个映像本来就应该是无状态的那样 。 这样的话 , 映像中将只能包含编译器和构建工具 。 因为没有理由频繁地更换这些工具 。 同时你将所有的代码都放在一个目录中 , 就像你通常所做的那样 。 要运行和编译代码 , 你可以进入映像中并运行命令 。 你可以在进入代码存储库时将其从主机磁盘绑定到映像 。这种方式效果更好 。 但是如果直接执行Docker命令行 , 则会出现以下问题: 1)根据你机器上的Docker配置 , 你可能会发现无法从映像读取或写入绑定到该映像的磁盘 。 对这个问题的一个快速修复方法是以特权访问方式来运行映像 , 但这种方法通常不受欢迎(而且不必要) 。2)从Docker映像中创建或修改的文件显示在主机磁盘上时 , 通常带有奇怪的文件权限 。 比如说 , 可能所有文件都属于根用户 。 我的一个研究助理有一个很好的变通解决办法:他一直以根用户的身份运行Linux 。 但是 , 我不推荐这样的方法 。这些小问题根源在于Docker以一种奇怪的方式来处理权限和安全性 。 可能与你了解的相反 , 设置用户和组标识符并不是一件简单的事情:在某些系统上可能足够简单 , 但在一些需要额外注意的支持增强的安全性的Linux系统上就不那么简单了 。最后 , 你需要记住很多复杂的命令 。 如果你和我一样 , 想把所有的注意力都集中在代码上 , 而不愿意在Docker上面浪费太多的时间 。 怎么办? 解决方法是使用一个小小的脚本 。 以我为例 , 我使用一个bash脚本 。 你可以在GitHub上找到它 。 它可以帮助你理清零乱的命令和文件权限 。尽管多年来 , 我一直试图避免依赖脚本 , 但是为了高效的工作 , 这是无可避免的 。基本上 , 我的做法是向我工作的目录的根目录中复制两个文件(Dockerfile和run文件) , 然后键入命令:


推荐阅读