最近在鼓捣自己的sideproject时,对如何选择Docker镜像犹豫了半天,这里找到了一片如何选择镜像的文章,翻译记录,仅供参考。

原文作者:Itamar Turner-Trauring

原文地址:https://pythonspeed.com/articles/base-image-python-docker-images/

当你为Python应用程序构建Docker镜像时,一般是构建在现有镜像之上。这个“现有镜像”,我们往往叫它为基础镜像。这里我们有很多种选择,有像UbuntuCentOS这样的操作系统映像,也有许多不同的python基本镜像。

你应该使用哪一个?哪一个更好?你有很多选择,但并不能够很好的确认那种镜像更适合你的业务场景。

因此,为了帮助你做出符合你需求的选择,在本文中,将介绍一些相关标准,和一些适用于大多数人的建议。

你想从基础镜像中得到什么?

选择基础镜像这里有些常用标准,你可根据特定情况有所侧重:

  • 稳定性:你希望今天的构建能够为你提供与明天构建相同的基本库,目录结构和基础结构,否则你的应用程序将可能随时崩溃。
  • 安全更新:你希望基础映像得到良好维护,以便及时获得基本操作系统的安全更新。
  • 最新的依赖关系:除非你构建一个非常简单的应用程序,否则你可能依赖于操作系统安装的库和应用程序(例如编译器),希望他们版本不要太老。
  • 广泛的依赖关系:对于某些应用程序,可能需要不太流行的依赖关系 - 包含大量库的基本映像更适合该条原则。
  • 最新的Python:虽然可以通过自己安装Python来解决这个问题,但拥有最新的Python可以节省你的工作量。
  • 小镜像:在所有条件相同的情况下,拥有较小的Docker镜像比使用更大的Docker镜像更好。

对稳定性的需求表明不使用支持生命周期有限的操作系统,如Fedora或非LTS Ubuntu版本。

选项#1:Ubuntu LTS,CentOS,Debian

有三种主要操作系统大致符合上述标准(日期和发布版本在撰写时是准确的;时间的流逝可能需要稍微不同的选择)。

  • Ubuntu 18.04(ubuntu:18.04镜像)于2018年4月发布,由于它是长期支持版本,它将在2023年之前获得安全更新。
  • CentOS 7.6(centos:7.6.1810)于2018年10月发布,将在2020年第四季度完成更新,维护更新至2024年。目前正在开发 CentOS 8 ,基于2019年5月发布的RHEL 8。
  • Debian 9(又名“Stretch”)于2017年发布,到2020年更新,LTS支持到2022年。你可以通过backport获得更新的软件包,但backports 无法保证安全更新。Debian 10(“Buster”)应该会在2019年7月发布。

所有这些图像的一个问题是,如果你想要最新版本的Python,你必须自己安装它。

选项#2:Python Docker镜像

另一个替代方案是Docker python镜像,它预先安装了特定版本的Python,并且有多种变体。复合以上标准的有:

  • Alpine Linux,最初是为小型设备设计的操作系统,因此往往有小包装。
  • Debian Stretch,安装了许多常见软件包。镜像本身很大,但理论上这些软件包是通过其他Docker镜像将使用的公共镜像层安装的,因此整体磁盘使用率会很低。
  • Debian Stretch slim 版。这缺少了通用软件包的层,因此镜像本身要小得多,但如果你使用Stretch以外的许多其他Docker镜像,整体磁盘使用量会更高一些。

一旦Debian 10(“Buster”)于2019年7月发布,新的python镜像将从Buster重建。

为什么你不应该使用Alpine Linux

对于想要小镜像的人来说,一个常见的建议是使用Alpine Linux,但使用它会产生一些问题。首先,Alpine的库比我上面提到的其他Linux发行版少得多,因此你可能会缺少库。

Alpine和其他Linux发行版之间也存在重大差异:Alpine使用不同的C库,而不是更常见的glibc。 理论上,musl和glibc 大多是兼容的,但这些差异可能会导致奇怪的问题。

一些例子:

  • Alpine具有较小的线程默认堆栈大小,这可能导致Python崩溃。
  • 一位Alpine用户发现他们的Python应用程序因为musl分配内存与glibc的方式而慢得多。
  • 在使用WeWork共享空间的WiFi时,我曾经无法在minikube(VM中的Kubernetes)上运行的Alpine镜像中进行DNS查找。原因是WeWork的糟糕DNS设置,Kubernetes和minikube做DNS的方式,以及musl对这个边缘案例的处理与glibc的处理。musl没有错(它与RFC相匹配),但我不得不浪费时间找出问题,然后切换到基于glibc的镜像。
  • 另一位用户发现了时间格式化和解析的问题。

大多数这些问题已经得到解决,但可能发现更多问题。为了减少镜像体积,而导致可能发生的不确定性问题,这是不值得的。因此,我建议不要使用Alpine。

那你应该怎么用?

直接使用Debian Stretch毫无意义,因为最新Python的基本映像就是基于此。

截至2019年6月:

  • python:3.7-slim-stretch或者python:3.7-stretch(或者你使用的任何Python版本而不是3.7)是一个比较好的基础镜像,slim变体版本可能会有更小的体积。
  • 如果你需要比Debian Stretch提供的更新的库或编译器,你可能想要使用ubuntu:18.04,它比CentOS更新。
  • 一旦发布了Debian Buster,这个python镜像可能会有是一个更好的选择:它将预装新版本的Python和与ubuntu:18.04等效或更新的软件包。
  • 当2020年4月到来时,ubuntu:20.04将率先拥有最新的软件包。