将生产Linux服务器转换为Docker镜像或容器的方法

87次阅读
没有评论

问题描述

有一个生产环境的Ubuntu服务器,上面安装了大量的软件和依赖项。他想将这个VPS克隆成一个Docker镜像,以便在不同的服务器上复制相同的环境。用户想知道是否有可能在不进行任何黑客行为的情况下实现这个目标,如果可以,应该遵循哪些大致步骤。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

是的,你可以将生产Linux服务器转换为Docker镜像或容器。虽然Docker通常用于微服务架构的镜像(即每个镜像只包含一个服务),但你完全可以通过构建一个大型镜像,并在其中运行任意多个进程来将旧的单体应用程序转换为Docker。
虽然Docker镜像不是一个独立的虚拟机,但它仍然包含了与等效虚拟机相同的所有内容(不包括内核)。也就是说,所有的操作系统库(libc等)都已经包含在其中。
以下是一般的步骤:
1. 选择一个基础镜像。根据你的需求和安全要求,你可以从Dockerhub上选择你喜欢的发行版。最初,你可以选择任何你喜欢和习惯的Debian、Ubuntu或其他发行版。下面会有更多的考虑事项。
2. 这些基础镜像通常非常小。因此,你的下一步是使用RUN apt install...(或其他基础镜像使用的包管理器)来添加任何你喜欢的标准软件包。
3. 最后,你需要以某种方式安装你自己的软件。如果你按照通常的方法,你会在与Dockerfile相同的目录中准备你需要的任何二进制文件和其他文件,然后使用ADD命令将它们添加进去。
4. 最后一步是(可选地)创建一个ENTRYPOINT,即在启动镜像时运行的命令,以及EXPOSE路由信息,以非root用户运行或设置环境变量。
这些是大致的步骤。如果你只是简单地这样做,你将得到一个非常大的镜像(几个GB),并且每次重新构建时都会创建一个新的大型镜像,这可能会带来严重的问题。因此,下面是一些进一步的步骤:
– 将基础镜像切换为更小的镜像,例如alpine
– 对于每个RUN命令,请确保在命令执行后没有临时/不必要的文件。例如,apt install会在/var中留下很多缓存垃圾(其他包管理器也是如此)。由于Docker使用了类似洋葱式的分层文件系统,你必须在同一个RUN命令中清除垃圾,不能在第二个RUN中清理。如果你搜索一下,你会找到很多示例。
– 你可能使用包管理器拉取了太多的软件包,需要修复这个问题。
– 对于安装你自己的软件,同样适用上述原则。避免在不再需要的情况下留下临时的.tar归档文件。
这些步骤应该能够显著减小镜像的大小。根据你的实际需求,目标是避免在这个阶段过度优化,500MB左右的镜像大小是一个不错的目标。
最后一步是优化一切:
– 确保你不必每次重新构建每个中间镜像,通过适当地排列Dockerfile中的行来实现。如果“大型”发生在前几个镜像层中,并且这些层很少改变,并且可以被许多最终镜像重用,那么你可以使用大型镜像。
– 要使中间镜像能够被重用,它必须与另一个镜像完全相同。因此,请确保尽可能好地修复所有可变信息(如版本号等)。
– 当你掌握了所有这些,并且能够在单个Docker镜像中运行复杂的多部分应用程序时,那么就是将其拆分成多个镜像的时候了(重复上述步骤)。任何通过TCP/IP通信的部分都应该很容易拆分成多个镜像。

方案2

另一种方法是将不同的应用程序和依赖项拆分为单独的Docker容器。这样做是更加合适和灵活的方式。
请注意,对于某些特定的用例,可能有更好的替代方案,例如http://habitat.sh等打包系统。你可以考虑使用其他打包系统,我将OP的问题理解为:是否可以像物理到虚拟的转换一样,使用Docker进行转换,答案是明确的不行,需要重新构建。

总结

将生产Linux服务器转换为Docker镜像或容器是可能的。你可以通过构建一个大型镜像并在其中运行多个进程来实现这一目标。你可以使用Dockerfile来定义构建过程,并根据需要优化镜像大小。另一种方法是将不同的应用程序和依赖项拆分为单独的Docker容器,以获得更好的灵活性和可维护性。

正文完