「容器架构」Debian和 Alpine作为基准Docker映像的对比

Posted 超级架构师

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「容器架构」Debian和 Alpine作为基准Docker映像的对比相关的知识,希望对你有一定的参考价值。


大多数官方Docker映像都提供基于Debian和Alpine的映像,但两者之间有一些令人惊讶的性能结果。自从Docker宣布他们开始在正式的Docker镜像中使用Alpine以来,我就跳槽并拥抱Alpine。

我的意思是,什么都不爱。它是Linux的最小发行版,攻击面非常小。将其作为容器中的基础映像运行似乎是完美的选择。

我写了一篇关于Alpine一年多以前的文章,并且一直以来一直在使用Alpine,而没有出现任何停止演出的问题。

为什么现在要比较这两个基本镜像?

我今天绝对没有醒来,想着“老兄,我想知道Debian在2018年如何成为Alpine作为基础Docker映像”。

真正发生的是,我整理了一篇文章,介绍了一个月前的一些Docker最佳实践,并将其引入了Reddit。

令我惊讶的是,它在Reddit社区获得了150多个投票,99%的投票评分和大量参与。

老实说,这就是我写这篇文章的原因。我使用Docker已经很长时间了,多年来,我选择了一些我认为很好的模式,但是我真的很想看看其他人在做什么,以便我可以改进。我一直在向别人学习。

发现关于Alpine的2种负面趋势

如果您通过Reddit评论,就会发现很多人评论DNS在Alpine中是如何随机失败的,而其他人则评论了某些类型的活动(例如连接到数据库的网络应用)的运行时性能不佳。

DNS查找问题:

我不是一个盲目听从一个人的评论的人,但是一旦有几个人开始提及同一件事,它就会变得很有趣。但是,如果没有某种类型的科学证据,我仍然无法相信一些评论。

幸运的是,有人链接到与Alpine相关的GitHub问题,其中包含更多信息。也许该错误会在适当的时候得到修复,但是在Alpine内部进行DNS查找似乎确实有些奇怪。

也可能与BusyBox中的9年错误有关(Alpine在后台使用此操作系统)。

我没有亲身经历过,但是我也没有运行过使用大规模Kubernetes集群的rofl规模的任何事情,因此也许我不受此问题的影响。

对我们来说幸运的是,Alpine拥有有关DNS查找为何可能失败的文档,并且还解释了为什么我从未遇到过此问题。很高兴知道。

常见的Web应用程序案例会降低运行时性能:

另一位Reddit用户提到,与Debian相比,使用Alpine作为基本映像时,其Node应用的运行速度降低了15%。他还提到自己的Python应用程序也较慢。

这位Reddit评论员甚至表示,他们每天运行500-700个单元测试的真实测试套件的速度差异为35%。那真的引起了我的注意。

当然,我回答了他,要求提供更具体的信息,因为像“慢15%”这样的词在不了解具体情况的情况下并不能说太多。

我们来回了几次,他提供了一些困难的数字,他让一个Python应用程序运行在一个容器中,该应用程序在另一个容器中运行的PostgreSQL中执行10,000个数据库选择。


# postgres:9.6.3 and python 2.7 Total test time 15.3489780426 seconds Total test time 13.5786788464 seconds Total test time 14.2057600021 seconds # postgres:9.6.3-alpine and python 2.7 Total test time 14.262032032 seconds Total test time 13.7757499218 seconds Total test time 14.1344659328 seconds # postgres 9.6.3 and python:2.7-alpine Total test time 18.1418809891 seconds Total test time 16.0904250145 seconds Total test time 17.1380209923 seconds

这说明Postgres映像在Alpine和Debian中的运行速度都一样快,但是当基于Alpine的Python映像尝试连接时,速度会明显下降。

这立刻让我认为,也许某些系统级软件包是这里的罪魁祸首。例如,使用Python和Ruby(和其他语言)的大多数流行的PostgreSQL连接库都需要在Debian上安装libpq-dev,在Alpine中安装postgresql-dev。

该软件包需要安装在映像中才能使用Python中的psycopg2和Ruby中的pg之类的软件包。它们使您可以从Web应用程序连接到PostgreSQL。

我们到了。现在我们有一些要测试的东西,并且是比较这两个基本镜像的真实原因。

测试两个基本镜像

在进入基准测试之前,需要指出的是,我不喜欢人为设计的微基准测试。当然,它们对于在语言/框架级别上测试回归非常有用,但是对于测试现实世界场景却毫无用处。

当人们感到“ flim flam Web框架每秒可以处理163,816个请求,而bibity bop仅处理97,471个请求/秒,这真是垃圾!”时,我总是睁大眼睛。

然后,您查看基准测试的功能,它所做的只是返回一个空的200响应。一旦执行序列化JSON或突然从模板返回html之类的操作,这两个框架就会变得越来越慢。

然后,您将诸如单个数据库调用之类的因素考虑在内,嘿,您知道什么,两个框架的速度下降了一个数量级。

对真实世界的Web应用程序进行基准测试

在撰写本文时,我将使用Flask课程的代码库的最新版本和完整版本,该版本运行Flask 1.0.2和所有最新的库版本。

这是一个尺寸适中的Flask应用程序,具有4,000多行代码,几个蓝图,并由SQLAlchemy驱动的PostreSQL数据库提供支持,并且还具有许多其他活动部件。

测试环境:

测试用例将是加载一个页面,该页面使用服务器呈现的模板返回HTML,还包括执行1个SELECT语句以按ID在数据库中查找用户。

Flask应用配置了:

  • gunicorn with Flask in production mode (not debug mode)

  • gunicorn running with 8 threads (gthread) and 8 workers

  • Logging level INFO

测试系统(我的开发箱)配置有:

  • i5 3.2GHz CPU with 16GB of RAM and an SSD

  • Docker Compose to launch the project with no app bind volumes

  • Docker for Windows to run the Docker daemon (rebooted between each test)

  • WSL to run the Docker CLI

通用测试策略:

我将运行一个名为wrk的HTTP基准测试工具,以向Flask应用发出请求。对于每个基本映像,我将对其运行5次,并获得最快的结果。

我将使用Debian和Alpine作为基本映像执行此测试,而无需对代码库,应用程序配置,应用程序运行方式或测试机器进行其他更改。

我将在后台运行docker-compose up -d以启动Compose项目,并运行wrk -t8 -c50 -d30 <url to test>以使用8个线程启动wrk,同时保持与该页面的50个HTTP连接。测试将运行30秒。

剧透警报:在这两个测试案例中,我的CPU都达到约65%的最高负荷,因此我们不受CPU限制。

Debian设置

这是我使用的Dockerfile:

FROM python:2.7-slim LABEL maintainer="Nick Janetakis <nick.janetakis@gmail.com>" RUN apt-get update && apt-get install -qq -y \ build-essential libpq-dev --no-install-recommends WORKDIR /app COPY requirements.txt requirements.txt RUN pip install -r requirements.txt COPY . . RUN pip install --editable . CMD gunicorn -c "python:config.gunicorn" "snakeeyes.app:create_app()"

以下是基准测试结果:

nick@workstation:/e/tmp/bsawf$ docker-compose up -d Recreating snakeeyestest_celery_1 ... done Starting snakeeyestest_redis_1 ... done Starting snakeeyestest_postgres_1 ... done Recreating snakeeyestest_website_1 ... done nick@workstation:/e/tmp/bsawf$ wrk -t8 -c50 -d30 localhost:8000/subscription/pricing Running 30s test @ localhost:8000/subscription/pricing 8 threads and 50 connections Thread Stats Avg Stdev Max +/- Stdev Latency 167.45ms 171.80ms 1.99s 87.87% Req/Sec 39.13 29.99 168.00 74.85% 8468 requests in 30.05s, 56.17MB read Socket errors: connect 0, read 0, write 0, timeout 42 Requests/sec: 281.83 Transfer/sec: 1.87MB

Alpine 设置

这是我使用的Dockerfile:

FROM python:2.7-alpine LABEL maintainer="Nick Janetakis <nick.janetakis@gmail.com>" RUN apk update && apk add build-base postgresql-dev WORKDIR /app COPY requirements.txt requirements.txt RUN pip install -r requirements.txt COPY . . RUN pip install --editable . CMD gunicorn -c "python:config.gunicorn" "snakeeyes.app:create_app()"

以下是基准测试结果:

nick@workstation:/e/tmp/bsawf$ docker-compose up -d Recreating snakeeyestest_celery_1 ... done Starting snakeeyestest_redis_1 ... done Starting snakeeyestest_postgres_1 ... done Recreating snakeeyestest_website_1 ... done nick@workstation:/e/tmp/bsawf$ wrk -t8 -c50 -d30 localhost:8000/subscription/pricing Running 30s test @ localhost:8000/subscription/pricing 8 threads and 50 connections Thread Stats Avg Stdev Max +/- Stdev Latency 223.56ms 270.60ms 1.96s 88.41% Req/Sec 39.53 25.02 140.00 65.12% 8667 requests in 30.05s, 57.49MB read Socket errors: connect 0, read 0, write 0, timeout 20 Requests/sec: 288.38 Transfer/sec: 1.91MB

让我们来谈谈结果

有点古怪。我希望Debian能够打破Alpine的大门,然后进行一次远征军,将我使用的一切都更改为Debian。

如果您考虑系统差异,那么我可以说两个发行版的性能大致相同,尽管Alpine的stdev有点高,但是另一方面,Debian的超时时间更多。在如此短暂的测试中,这两者仍可能是差异。

我毫不怀疑这些Reddit评论员的结果,并且如果有任何发现,该测试表明并非所有测试用例都被等同创建。

我要指出的一件事是Reddit用户的测试执行了10,000条SELECT语句,而我的应用程序执行了1条SELECT语句。那是很大的区别。我想知道如果使用15个数据库查询而不是1个数据库查询,在更复杂的页面上会发生什么。

如果您想拿起手电筒,并使用不同的语言或Python版本创建更多的测试用例,请这样做,并告诉我们它的工作方式。

现在,我将继续使用Alpine,但是如果遇到问题或迫切需要切换的原因,那么我将切换到Debian。


相关文章: