「容器架构」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。
相关文章:
以上是关于「容器架构」Debian和 Alpine作为基准Docker映像的对比的主要内容,如果未能解决你的问题,请参考以下文章
为啥在 Alpine Linux 上安装 Pandas 需要很长时间