技术文档收录
ASCII
Tcpdump
IPV4保留地址段
深入理解以太网网线原理 - 三帛的世界
Linux
WireGuard 一键安装脚本 | 秋水逸冰
SSH Config 那些你所知道和不知道的事 | Deepzz's Blog
Linux 让终端走代理的几种方法
ubuntu 20.04 server 版设置静态 IP 地址 - 链滴
Linux 挂载 Windows 共享磁盘的方法 - 技术学堂
将 SMB/CIFS 网络硬盘永久的挂载到 Ubuntu 上 - 简书
linux 获取当前脚本的绝对路径 | aimuke
[Linux] Linux 使用 / dev/urandom 生成随机数 - piaohua's blog
Linux 生成随机数的多种方法 | Just Do It
Linux 的 Centos7 版本下忘记 root 或者普通用户密码怎么办?
Git 强制拉取覆盖本地
SSH 安全加固指南 - FreeBuf 网络安全行业门户
Linux 系统安全强化指南 - FreeBuf 网络安全行业门户
Linux 入侵排查 - FreeBuf 网络安全行业门户
sshd_config 配置详解 - 简书
SSH 权限详解 - SegmentFault 思否
CentOS 安装 node.js 环境 - SegmentFault 思否
如何在 CentOS 7 上安装 Node.js 和 npm | myfreax
几款 ping tcping 工具总结
OpenVpn 搭建教程 | Jesse's home
openvpn 一键安装脚本 - 那片云
OpenVPN 解决 每小时断线一次 - 爱开源
OpenVPN 路由设置 – 凤曦的小窝
OpenVPN 设置非全局代理 - 镜子的记录簿
TinyProxy 使用帮助 - 简书
Ubuntu 下使用 TinyProxy 搭建代理 HTTP 服务器_Linux_运维开发网_运维开发技术经验分享
Linux 软件包管理工具 Snap 常用命令 - 简书
linux systemd 参数详解
Systemd 入门教程:命令篇 - 阮一峰的网络日志
记一次 Linux 木马清除过程
rtty:在任何地方通过 Web 访问您的终端
02 . Ansible 高级用法 (运维开发篇)
终于搞懂了服务器为啥产生大量的 TIME_WAIT!
巧妙的 Linux 命令,再来 6 个!
77% 的 Linux 运维都不懂的内核问题,这篇全告诉你了
运维工程师必备:请收好 Linux 网络命令集锦
一份阿里员工的 Java 问题排查工具单
肝了 15000 字性能调优系列专题(JVM、MySQL、Nginx and Tomcat),看不完先收
作业调度算法(FCFS,SJF,优先级调度,时间片轮转,多级反馈队列) | The Blog Of WaiterXiaoYY
看了这篇还不会 Linux 性能分析和优化,你来打我
2019 运维技能风向标
更安全的 rm 命令,保护重要数据
求你了,别再纠结线程池大小了!
Linux sudo 详解 | 失落的乐章
重启大法好!线上常见问题排查手册
sudo 使用 - 笨鸟教程的博客 | BY BenderFly
shell 在手分析服务器日志不愁? - SegmentFault 思否
sudo 与 visudo 的超细用法说明_陈发哥 007 的技术博客_51CTO 博客
ESXI 下无损扩展 Linux 硬盘空间 | Naonao Blog
Linux 学习记录:su 和 sudo | Juntao Tan 的个人博客
使用者身份切换 | Linux 系统教程(笔记)
你会使用 Linux 编辑器 vim 吗?
在 Windows、Linux 和 Mac 上查看 Wi-Fi 密码
linux 隐藏你的 crontab 后门 - 简书
Linux 定时任务详解 - Tr0y's Blog
linux 的 TCP 连接数量最大不能超过 65535 个吗,那服务器是如何应对百万千万的并发的?_一口 Linux 的博客 - CSDN 博客_tcp 连接数多少正常
万字长文 + 28 张图,一次性说清楚 TCP,运维必藏
为什么 p2p 模式的 tunnel 底层通常用 udp 而不是 tcp?
记一次服务器被入侵挖矿 - tlanyan
shell 判断一个变量是否为空方法总结 - 腾讯云开发者社区 - 腾讯云
系统安装包管理工具 | Escape
编译代码时动态地链接库 - 51CTO.COM
甲骨文 Oracle Cloud 添加新端口开放的方法 - WirelessLink 社区
腾讯云 Ubuntu 添加 swap 分区的方法_弓弧名家_玄真君的博客 - CSDN 博客
Oracle 开放全部端口并关闭防火墙 - 清~ 幽殇
谁再说不熟悉 Linux 命令, 就把这个给他扔过去!
即插即用,运维工程师必会正则表达式大全
Shell脚本编写及常见面试题
Samba 文件共享服务器
到底一台服务器上最多能创建多少个 TCP 连接 | plantegg
SSH 密钥登录 - SSH 教程 - 网道
在 Bash 中进行 encodeURIComponent/decodeURIComponent | Harttle Land
使用 Shell 脚本来处理 JSON - Tom CzHen's Blog
Docker
「Docker」 - 保存镜像 - 知乎
终于可以像使用 Docker 一样丝滑地使用 Containerd 了!
私有镜像仓库选型:Harbor VS Quay - 乐金明的博客 | Robin Blog
exec 与 entrypoint 使用脚本 | Mr.Cheng
Dockerfile 中的 CMD 与 ENTRYPOINT
使用 Docker 配置 MySQL 主从数据库 - 墨天轮
Alpine vs Distroless vs Busybox – 云原生实验室 - Kubernetes|Docker|Istio|Envoy|Hugo|Golang | 云原生
再见,Docker!
docker save 与 docker export 的区别 - jingsam
如何优雅的关闭容器
docker 储存之 tmpfs 、bind-mounts、volume | 陌小路的个人博客
Dockerfile 中 VOLUME 与 docker -v 的区别是什么 - 开发技术 - 亿速云
理解 docker 容器的退出码 | Vermouth | 博客 | docker | k8s | python | go | 开发
【Docker 那些事儿】容器监控系统,来自 Docker 的暴击_飞向星的客机的博客 - CSDN 博客
【云原生】Docker 镜像详细讲解_微枫 Micromaple 的博客 - CSDN 博客_registry-mirrors
【云原生】Helm 架构和基础语法详解
CMD 和 Entrypoint 命令使用变量的用法
实时查看容器日志 - 苏洋博客
Traefik 2 使用指南,愉悦的开发体验 - 苏洋博客
为你的 Python 应用选择一个最好的 Docker 映像 | 亚马逊 AWS 官方博客
【云原生】镜像构建实战操作(Dockerfile)
Docker Compose 中的 links 和 depends_on 的区别 - 编程知识 - 白鹭情
Python
Pipenv:新一代Python项目环境与依赖管理工具 - 知乎
Python list 列表实现栈和队列
Python 各种排序 | Lesley's blog
Python 中使用 dateutil 模块解析时间 - SegmentFault 思否
一个小破网站,居然比 Python 官网还牛逼
Python 打包 exe 的王炸 - Nuitka
Django - - 基础 - - Django ORM 常用查询语法及进阶
[Python] 小知識:== 和 is 的差異 - Clay-Technology World
Window
批处理中分割字符串 | 网络进行时
Windows 批处理基础命令学习 - 简书
在Windows上设置WireGuard
Windows LTSC、LTSB、Server 安装 Windows Store 应用商店
windows 重启 rdpclip.exe 的脚本
中间件
Nginx 中的 Rewrite 的重定向配置与实践
RabbitMQ 的监控
RabbitMq 最全的性能调优笔记 - SegmentFault 思否
为什么不建议生产用 Redis 主从模式?
高性能消息中间件——NATS
详解:Nginx 反代实现 Kibana 登录认证功能
分布式系统关注点:仅需这一篇,吃透 “负载均衡” 妥妥的
仅需这一篇,妥妥的吃透” 负载均衡”
基于 nginx 实现上游服务器动态自动上下线——不需 reload
Nginx 学习书单整理
最常见的日志收集架构(ELK Stack)
分布式之 elk 日志架构的演进
CAT 3.0 开源发布,支持多语言客户端及多项性能提升
Kafka 如何做到 1 秒处理 1500 万条消息?
Grafana 与 Kibana
ELK 日志系统之通用应用程序日志接入方案
ELK 简易 Nginx 日志系统搭建: ElasticSearch+Kibana+Filebeat
记一次 Redis 连接池问题引发的 RST
把 Redis 当作队列来用,你好大的胆子……
Redis 最佳实践:业务层面和运维层面优化
Redis 为什么变慢了?常见延迟问题定位与分析
好饭不怕晚,扒一下 Redis 配置文件的底 Ku
rabbitmq 集群搭建以及万级并发下的性能调优
别再问我 Redis 内存满了该怎么办了
Nginx 状态监控及日志分析
uWSGI 的安装及配置详解
uwsgi 异常服务器内存 cpu 爆满优化思路
Uwsgi 内存占用过多 - 简书
Nginx 的 limit 模块
Nginx 内置模块简介
Redis 忽然变慢了如何排查并解决?_redis_码哥字节_InfoQ 写作社区
领导:谁再用 redis 过期监听实现关闭订单,立马滚蛋!
Nginx 限制 IP 访问频率以及白名单配置_问轩博客
Nginx $remote_addr 和 $proxy_add_x_forwarded_for 变量详解
Caddy 部署实践
一文搞定 Nginx 限流
数据库
SqlServer 将数据库中的表复制到另一个数据库_MsSql_脚本之家
SQL Server 数据库同步,订阅、发布、复制、跨服务器
sql server 无法删除本地发布 | 辉克's Blog
SQLite全文检索
SQL 重复记录查询的几种方法 - 简书
SQL SERVER 使用订阅发布同步数据库(转)
Mysql 查看用户连接数配置及每个 IP 的请求情况 - 墨天轮
优化 SQL 的 21 条方案
SQL Server 连接时好时坏的奇怪问题
MS SQL 执行大脚本文件时,提示 “内存不足” 的解决办法 - 阿里云开发者社区
防火墙-iptables
iptables 常用规则:屏蔽 IP 地址、禁用 ping、协议设置、NAT 与转发、负载平衡、自定义链
防火墙 iptables 企业防火墙之 iptables
Linux 防火墙 ufw 简介
在 Ubuntu 中用 UFW 配置防火墙
在 Ubuntu20.04 上怎样使用 UFW 配置防火墙 - 技术库存网
监控类
开箱即用的 Prometheus 告警规则集
prometheus☞搭建 | zyh
docker 部署 Prometheus 监控服务器及容器并发送告警 | chris'wang
PromQL 常用命令 | LRF 成长记
prometheus 中使用 python 手写 webhook 完成告警
持续集成CI/CD
GitHub Actions 的应用场景 | 记录干杯
GithubActions · Mr.li's Blog
工具类
GitHub 中的开源网络广告杀手,十分钟快速提升网络性能
SSH-Auditor:一款 SHH 弱密码探测工具
别再找了,Github 热门开源富文本编辑器,最实用的都在这里了 - srcmini
我最喜欢的 CLI 工具
推荐几款 Redis 可视化工具
内网代理工具与检测方法研究
环境篇:数据同步工具 DataX
全能系统监控工具 dstat
常用 Web 安全扫描工具合集
给你一款利器!轻松生成 Nginx 配置文件
教程类
Centos7 搭建神器 openvpn | 运维随笔
搭建 umami 收集个人网站统计数据 | Reorx’s Forge
openvpn安装教程
基于 gitea+drone 完成小团队的 CI/CD - 德国粗茶淡饭
将颜色应用于交替行或列
VMware Workstation 全系列合集 精简安装注册版 支持 SLIC2.6、MSDM、OSX 更新 16.2.3_虚拟机讨论区_安全区 卡饭论坛 - 互助分享 - 大气谦和!
在 OpenVPN 上启用 AD+Google Authenticator 认证 | 运维烂笔头
Github 进行 fork 后如何与原仓库同步:重新 fork 很省事,但不如反复练习版本合并 · Issue #67 · selfteaching/the-craft-of-selfteaching
卧槽,VPN 又断开了!!- 阿里云开发者社区
Grafana Loki 学习之踩坑记
zerotier 的 planet 服务器(根服务器)的搭建踩坑记。无需 zerotier 官网账号。
阿里云 qcow2 镜像转 vmdk,导入 ESXi - 唐际忠的博客
Caddy 入门 – 又见杜梨树
【Caddy2】最新 Caddy2 配置文件解析 - Billyme 的博客
Web 服务器 Caddy 2 | Haven200
手把手教你打造高效的 Kubernetes 命令行终端
Keras 作者:给软件开发者的 33 条黄金法则
超详细的网络抓包神器 Tcpdump 使用指南
使用 fail2ban 和 FirewallD 黑名单保护你的系统
linux 下 mysql 数据库单向同步配置方法分享 (Mysql)
MySQL 快速删除大量数据(千万级别)的几种实践方案
GitHub 上的优质 Linux 开源项目,真滴牛逼!
WireGuard 教程:使用 Netmaker 来管理 WireGuard 的配置 – 云原生实验室 - Kubernetes|Docker|Istio|Envoy|Hugo|Golang | 云原生
Tailscale 基础教程:Headscale 的部署方法和使用教程 – 云原生实验室 - Kubernetes|Docker|Istio|Envoy|Hugo|Golang | 云原生
Nebula Graph 的 Ansible 实践
改进你的 Ansible 剧本的 4 行代码
Caddy 2 快速简单安装配置教程 – 高玩梁的博客
切换至 Caddy2 | 某不科学的博客
Caddy2 简明教程 - bleem
树莓派安装 OpenWrt 突破校园网限制 | Asttear's Blog
OpenVPN 路由设置 – 凤曦的小窝
个性化编译 LEDE 固件
盘点各种 Windows/Office 激活工具
[VirtualBox] 1、NAT 模式下端口映射
VirtualBox 虚拟机安装 openwrt 供本机使用
NUC 折腾笔记 - 安装 ESXi 7 - 苏洋博客
锐捷、赛尔认证 MentoHUST - Ubuntu 中文
How Do I Use A Client Certificate And Private Key From The IOS Keychain? | OpenVPN
比特记事簿: 笔记: 使用电信 TR069 内网架设 WireGuard 隧道异地组网
利用 GitHub API 获取最新 Releases 的版本号 | 这是只兔子
docsify - 生成文档网站简单使用教程 - SegmentFault 思否
【干货】Chrome 插件 (扩展) 开发全攻略 - 好记的博客
一看就会的 GitHub 骚操作,让你看上去像一位开源大佬
【计算机网络】了解内网、外网、宽带、带宽、流量、网速_墩墩分墩 - CSDN 博客
mac-ssh 配置 | Sail
如何科学管理你的密码
VirtualBox NAT 端口映射实现宿主机与虚拟机相互通信 | Shao Guoliang 的博客
CentOS7 配置网卡为静态 IP,如果你还学不会那真的没有办法了!
laisky-blog: 近期折腾 tailscale 的一些心得
使用 acme.sh 给 Nginx 安装 Let’ s Encrypt 提供的免费 SSL 证书 · Ruby China
acme 申请 Let’s Encrypt 泛域名 SSL 证书
从 nginx 迁移到 caddy
使用 Caddy 替代 Nginx,全站升级 https,配置更加简单 - Diamond-Blog
http.proxy - Caddy 中文文档
动手撸个 Caddy(二)| Caddy 命令行参数最全教程 | 飞雪无情的总结
Caddy | 学习笔记 - ijayer
Caddy 代理 SpringBoot Fatjar 应用上传静态资源
使用 graylog3.0 收集 open××× 日志进行审计_年轻人,少吐槽,多搬砖的技术博客_51CTO 博客
提高国内访问 github 速度的 9 种方法! - SegmentFault 思否
VM16 安装 macOS 全网最详细
2022 目前三种有效加速国内 Github
How to install MariaDB on Alpine Linux | LibreByte
局域网内电脑 - ipad 文件共享的三种方法 | 岚
多机共享键鼠软件横向测评 - 尚弟的小笔记
VLOG | ESXI 如何升级到最新版,无论是 6.5 还是 6.7 版本都可以顺滑升级。 – Vedio Talk - VLOG、科技、生活、乐分享
远程修改 ESXi 6.7 管理 IP 地址 - 腾讯云开发者社区 - 腾讯云
几乎不要钱自制远程 PLC 路由器方案
traefik 简易入门 | 个人服务器运维指南 | 山月行
更完善的 Docker + Traefik 使用方案 - 苏洋博客
MicroSD·TF 卡终极探秘 ·MLC 颗粒之谜 1 三星篇_microSD 存储卡_什么值得买
macOS 绕过公证和应用签名方法 - 走客
MiscSecNotes / 内网端口转发及穿透. md at master · JnuSimba/MiscSecNotes
我有特别的 DNS 配置和使用技巧 | Sukka's Blog
SEO:初学者完整指南
通过 OpenVPN 实现流量审计
OpenVPN-HOWTO
OpenVPN Server · Devops Roadmap
Linux 运维必备的 13 款实用工具, 拿好了~
linux 平台下 Tomcat 的安装与优化
Linux 运维跳槽必备的 40 道面试精华题
Bash 脚本进阶,经典用法及其案例 - alonghub - 博客园
推荐几个非常不错的富文本编辑器 - 走看看
在 JS 文件中加载 JS 文件的方法 - 月光博客
#JavaScript 根据需要动态加载脚本并设置自定义参数
笔记本电脑 BIOS 修改及刷写教程
跨平台加密 DNS 和广告过滤 personalDNSfilter · LinuxTOY
AdGuard Home 安装及使用指北
通过 Amazon S3 协议挂载 OSS
记一次云主机如何挂载对象存储
本文档发布于https://mrdoc.fun
-
+
首页
为你的 Python 应用选择一个最好的 Docker 映像 | 亚马逊 AWS 官方博客
> 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码, 原文地址 [aws.amazon.com](https://aws.amazon.com/cn/blogs/china/choose-the-best-docker-image-for-your-python-application/) 为你的 Python 应用选择一个最好的 Docker 映像 ============================== by [AWS Team](https://aws.amazon.com/cn/blogs/china/author/qqfang/ "Posts by AWS Team") | on 05 3 月 2020 | in [Programing Language](https://aws.amazon.com/cn/blogs/china/category/programing-language/ "View all posts in Programing Language") | [Permalink](https://aws.amazon.com/cn/blogs/china/choose-the-best-docker-image-for-your-python-application/) | [ Share](#) * 前言 -- 在使用 Python 的早些年,为了解决 Python 包的隔离与管理 virtualenvwrapper 就成为我的工具箱中重要的一员。后来,随着 Python 3 的普及,virtualenvwrapper 逐渐被 venv 所替换。毕竟 venv 是 Python 3 的标配,优点是显而易见的。而这几年,应用场景的的复杂性越来与高,无论是开发还是部署都需要设置复杂的环境。例如使用 redis 实现消息队列,用 Psycopg 完成对于 PostgreSQL 数据库的存取等等。随之而来 Docker 就变成了程序员必不可少的常备工具。为了掌握如何将我的 Python 应用与 Docker 结合起来,就要学习他人的经验分享。于是一次又一次地看到了下面这样的 Dockerfile 例子 – [![](https://s3.cn-north-1.amazonaws.com.cn/awschinablog/choose-the-best-docker-image-for-your-python-application1.png)](https://s3.cn-north-1.amazonaws.com.cn/awschinablog/choose-the-best-docker-image-for-your-python-application1.jpg) 相比起来,我不熟悉 Alpine 这个 Linux 发行版本。 我很困惑这个版本难道比其它哪些老字号的 Linux 发行版更适合 Docker 的环境吗?至于我的 Python 应用,究竟选择哪一个 Docker 基础映像更好呢? 对于 Docker 基础映像的要求 ----------------- 为我的 Python 应用构建一个 Docker 映像并不是要从零开始,而是从现有的 Linux 基础映像开始构建。这些基础映像除了提到过的 Alpine 以外 还有我更熟悉的 Ubuntu、Centos 、Debian 等等。在决定选择哪一个之前,我们需要回答的一个问题就是 – 我们究竟对于这个 Docker 基础映像有哪些要求?这些要求既要满足通常意义上我们对操作系统的要求,也要满足对于 Python 应用的特殊的需求。归纳起来,我们的需求应当包括这几点 – * **稳定性:**要求今天的构建与以后的构建有相同的基本库、目录结构和基础结构。否则我们的 Python 应用程序将将有可能存在不确定的隐患。 * **安全更新:**需要基础映像得到良好维护,以便及时获取基本操作系统的安全更新 * **最新的依赖关系:**除非我们的应用仅仅是一个简单的 Python 程序,否则就不得不依赖操作系统所提供 的库和应用程序(例如:GCC 编译器、OpenSSL 库等)。我们需要这些应用和库要足够新,否则就会有各种安全性的问题或者功能性的不足。 * **丰富的库资源:**对于某些应用,可能需要安装一些不太流行的库(例如 lxml 等)。这就需要我们选择的基本映像提供丰富的库资源。 * **最新的** **Python** **版本:**虽然可以通过自行安装 Python 来解决,但是拥有最新的 Python 的版本无疑可以节省我们的时间、精力。 * **小型的** **Docker** **映像:**在所有条件都相同的情况下,拥有尺寸较小的 Docker 映像无疑更胜一筹。无论是映像的构建还是占用存储空间的开销,更小的尺寸一定更有优势。 考虑到应用部署在产环境的需要,我们所选择的 Docker 映像还应当具备长期支持 (Long-term support, LTS) 的承诺。 _长期支持 (英语:Long-term support,缩写:LTS)是一种软件的产品生命周期政策,特别是开源软件,它增加了软件开发过程及软件版本周期的可靠度。长期支持延长了软件维护的周期;它也改变了软件更新(补丁)的类型及频率以降低风险、费用及软件部署的中断时间,同时提升了软件的可靠性。但这并不必然包含技术支持。_ _– 维基百科_ Linux 镜像版本的选择 ------------- 围绕着上述的需求,我们很容易就会找到一批候选的版本。乍看起来,这些基础映像应该能够满足我们的需要。接下来我们需要仔细甄别其具体的差异,以找出最适合我们的版本,尤其是适合我们的 Python 应用。 ### 选项一:传统的 Linux 分发版本 – Ubuntu TLS、CentOS 以及 Debian 这三个 Linux 分发版本历史久远 (Debian 早在 1993 年就已出现),名气很大,在 Linux 服务器市场上拥有广泛的用户。 * Ubuntu 18.04(Docker 映像的名字 ubuntu:18.04)发布于 2018 年 4 月,由于这是 [Canonical](https://www.google.com/search?client=firefox-b-e&sxsrf=ALeKk03hK3AduNjxhmgCxUjJtEC3u5f0cQ:1583243920174&q=Canonical&stick=H4sIAAAAAAAAAOPgE-LUz9U3MK4wLcxVAjNNTIstjbRUMsqt9JPzc3JSk0sy8_P0i_PTSsoTi1KtUlLLUnPyC1JTFJIqF7FyOifm5edlJifm7GBlBABqbZQ8TQAAAA&sa=X&ved=2ahUKEwiditGbu_7nAhWEKqYKHeQiB4UQmxMoATAlegQICRAD) 公司的长期支持版本(LTS),意味着该版本的用户在 2023 年之前都将获得安全更新。 * CentOS 8( Docker 映像的名字 centos:8 )于 2019 年发布,将在 2024 年前进行全面更新,并在 2029 年前提供维护更新。 * Debian 10(Docker 映像的名字 debian:buster)发布于 2019 年 7 月,承诺支持到 2024 年。 需要注意的是这些映像预安装的 Python 有可能不是最新的版本。例如 Ubuntu 18.04 预安装的是 Python 3.6.7,而 Python 3 的最新稳定版本已经升级为 Python 3.8.1。因此我们必须在构建 Docker 映像的时候去完成 Python 的安装或者升级。在一些特定的 Linux 分发版本中,我们甚至需要自行通过编译 Python 源码的方式来获得最新版本的 Python。例如在 CentOS 8 中,就需要用这个办法来安装 Python3.8。至于具体的办法,可以参考在 “Python 3.8 已经来了,你准备好了吗?”([https://amazonaws-china.com/cn/blogs/china/python-3-8-is-here-are-you-ready/](https://amazonaws-china.com/cn/blogs/china/python-3-8-is-here-are-you-ready/))一文中的介绍。 ### 选项二:Docker 官方的 Python 映像 这个 Docker 映像由 Docker 官方提供。该版本的最大特点就是预装了 Python,并且提供多个不同 Python 版本的选项,例如 Python 3.7、Python 3.8 甚至是目前还没有正式发布的 Python 3.9-rc。需要注意的是,这个版本提供了多个不同的变体,如果搞不清楚这一点很容易在使用中遇到难以预料的问题。这些差异很大的变体包括了: * Alpine Linux, 关于这个版本,后面会有专门的讨论 * Debian Buster, 这是基于 Debian 的一个分支版本,是基于 Debian 的标准映像的 Layer 来构建的。特点是基础库很完整,缺点是尺寸较大,磁盘的利用率较低。 * Debian Buster slim,这个版本是针对 Debian Buster 的 “瘦身” 后的版本。尺寸小,磁盘利用率高是其优点。但是,它缺少通用的包,可能会导致对部分的应用支持不好。 ### 选项三:云计算上的 Linux 镜像 – Amazon Linux 2 今天当我们谈到 Docker 在生产环境中的部署的时候,不能缺少的一个话题就是云计算。相比较起来,云计算上 Linux 以及 Docker 的使用与部署与我们熟悉的传统方式有一些区别。例如安全性的要求、与云计算平台的集成以及管理工具等。于是云计算的平台 Linux 分发版本以及 Docker 镜像也就应需而生。AWS 就提供了 Amazon Linux 的两个版本: Amazon Linux 2 和 Amazon Linux。 其中,Amazon Linux 2 是 Amazon Linux 的新一代的 Linux 服务器操作系统版本,这也是 AWS 官方推荐使用的版本。至于选择 Amazon Linux 2 的的理由,简单来说这是一个由 Amazon 提供长期支持的(LTS)、进行了针对性性能优化的、强调安全的、免费的 Linux 分发版本以及 Docker 的镜像。 ### 选项四:Alpine 映像 很难想象,Alpine 这个 Linux 发行版已经有了 14 年的历史。但广为大家所熟知还是要拜 Docker 的流行所赐。最初,Alpine Linux 是 LEAF 项目(Linux Embedded Appliance Framework Project)的一个分支。LEAF 项目的设计的目标是开发出一个可以放在单个软盘上的 Linux 发行版,而后继的 Alpine 在此基础之上附加了一些更常用的软件包例如 Squid、Samba 等等。因此,Alpine 的典型特征就是 “**尺寸小**”!当然为达成这个目标就要做出妥协。为减少尺寸就不得不放弃我们熟悉的 Linux 环境中最常见的 [GNU C Library](https://en.wikipedia.org/wiki/GNU_C_Library) (glibc),取而代之的是一个迷你版的 C 标准库 musl([musl.libc.org](http://musl.libc.org/))。此外, 我们常用的 Linux 工具(例如 grep、ls、cp 等等)则采用了 BusyBox 以求进一步压缩空间。 这种努力的结果是非常有成效的,alpine:latest 镜像的尺寸只有区区的 **5.59MB**,而与之相对的 ubuntu:18.04 的镜像的尺寸却高达 64.2MB。简单计算下来,Alpine 的磁盘空间的需求只是 Ubuntu 18.04 的 **8.7%**!! 对比 – Docker 基础镜像的尺寸 ------------------- 想象一下,在真实的生产环境中我们部署的 Docker 实例的数量可能成百、上千。考虑到数量的因素,Docker 镜像的尺寸就应当是我们考量的一个重要依据。此外启动一个 Docker 实例我们往往需要在尽可能短的时间内完成,Docker 镜像的尺寸无疑也是一个关键因素。那么,我们就将上面列举的 Docker 镜像在尺寸方面做一个对比 : ##### 测试日期:2020 年 2 月 28 日 <table border="2" width="0"><tbody><tr><td width="130">Linux 分发版本</td><td width="144">镜像名称</td><td width="227">拉取命令</td><td width="142">尺寸</td></tr><tr><td width="130"><strong>Ubuntu</strong></td><td width="144">ubuntu:18.04</td><td width="227">docker pull ubuntu:18.04</td><td width="142">64.2MB</td></tr><tr><td width="130"><strong>Alphine</strong></td><td width="144">alpine:latest</td><td width="227">docker pull alpine:latest</td><td width="142"><strong>5.59MB</strong></td></tr><tr><td width="130"><strong>Debian</strong></td><td width="144">debian:buster</td><td width="227">docker pull amd64/debian:buster</td><td width="142">114MB</td></tr><tr><td width="130"><strong>CentOS</strong></td><td width="144">centos:8</td><td width="227">docker pull centos:8</td><td width="142">237MB</td></tr><tr><td width="130"><strong>Amazon Linux 2</strong></td><td width="144">amazonlinux:latest</td><td width="227">docker pull amazonlinux:latest</td><td width="142">163MB</td></tr><tr><td width="130"><strong>Debian</strong></td><td width="144">python:3.7</td><td width="227">docker pull python:3.7</td><td width="142">919MB</td></tr><tr><td width="130"><strong>Alphine</strong></td><td width="144">python:3.7-slim</td><td width="227">docker pull python:3.7-slim</td><td width="142">179MB</td></tr></tbody></table> 好了,在这一项的测试中名次如下 : python:3.7 > centos:8 > python:3.7-slim > amazonlinux:latest > debian:buster > ubuntu:18.04 > alpine:latest 如果从这个排名来看 centos 8 无疑表现的差强人意,故被淘汰。从数字来看似乎 alpine 是最好的选择。且慢,我们再来进行下一项测试 - 构建时间。 对比 – Docker 镜像的构建时间 ------------------- 在大多数的时间里,我们所使用的 Docker 映像都需要从基础映像开始构建。例如下面的这个 Dockerfile 就用来构建一个 Flask 的应用 ``` # Dockerfile-flask # Simply inherit the Python 3 image. FROM python:3 # Set an environment variable ENV APP /app # Create the directory RUN mkdir $APP WORKDIR $APP # Expose the port uWSGI will listen on EXPOSE 5000 # Copy the requirements file in order to install # Python dependencies COPY requirements.txt . # Install Python dependencies RUN pip install -r requirements.txt # We copy the rest of the codebase into the image COPY . . # Finally, we run uWSGI with the ini file ``` Python 这种模式带来的问题就是我们不得不考虑构建带来的额外的开销。尤其在一个复杂的项目中,我们需要构建的则不仅仅上面这样简单的场景,复杂的应用往往需要一个较长的构建时间。如果构建时间的开销比较大或者比较复杂,则必然增加了额外的管理、部署以及监控的成本。我的这个测试场景比较简单,只是安装 Python3,以及比较常见的 python 包 numpy、matplotlib 和 pandas。看看每一种 Docker 基础镜像的构建所需的时间是多少。 1、**ubuntu:18** , 构建时间 1 分 31.044 秒 ``` FROM ubuntu:18.04 RUN apt-get update -y && \ apt-get install -y python3.7 python3-pip python3.7-dev RUN pip3 install --upgrade pip RUN pip3 install --no-cache-dir numpy matplotlib pandas ``` Python 2、**amazonlinux:2** , 构建时间 30.898 秒 ``` FROM amazonlinux:latest RUN yum update -y && \ yum install -y python3 python3-devel RUN pip3 install --no-cache-dir numpy matplotlib pandas ``` Python 3、**debian:latest** , 构建时间 52.237 秒 ``` FROM debian:buster RUN apt-get update -y && \ apt-get install -y python3 python3-pip python3-dev RUN pip3 install --no-cache-dir numpy matplotlib pandas ``` Python 4、**python:latest**,构建时间 35.752 秒 ``` FROM python:3.7 RUN apt-get update -y && \ apt-get install -y python3-pip RUN pip3 install pip --upgrade RUN pip3 install --no-cache-dir numpy matplotlib pandas ``` Python 5、**python:3.7-slim**, 构建时间 53.475 秒 ``` FROM python:3.7 RUN apt-get update -y && \ apt-get install -y python3-pip RUN pip3 install pip --upgrade RUN pip3 install --no-cache-dir numpy matplotlib pandas ``` Python 6、alpine:latest ,构建时间 **24** **分 43.122** **秒** ``` FROM alpine:latest RUN apk update && \ apk add --no-cache --update \ gcc make automake gcc g++ python3 python3-dev cython freetype-dev RUN pip3 install --upgrade pip RUN pip3 install --no-cache-dir numpy matplotlib pandas ``` Python 测试的结果出来了: alpine:latest > ubuntu:18.04 > > python:3.7-slim > debian:buster > python:last > amazonlinux:latest 确实没有看错,被我们寄予厚望的 Alpine 映像的构建时间居然是 **24 分钟**以上。与构建速度最快的 Amazon Linux 2 比较起来足足慢了有 **24 倍**的时间!! 如果细心一些,你会发现这个 Dockerfile 与上面的几个不同,多出了 gcc、make、automake、g++ 这些与编译工具和几个库。事实上,在我第一次构建的时候遇到了这样的错误信息 : [![](https://s3.cn-north-1.amazonaws.com.cn/awschinablog/choose-the-best-docker-image-for-your-python-application2.png)](https://s3.cn-north-1.amazonaws.com.cn/awschinablog/choose-the-best-docker-image-for-your-python-application2.jpg) 这真是未曾预料的问题啊!深究之下终于发现在 Appine 使用 pip 安装 matplotlib 以及 pandas 的时候,并不是从 PyPi 的仓库中下载 whl 包,而是需要下载源代码然后编译再进行安装的。标准的预编译的 Python 包居然无法直接安装,这究竟是为什么? 答案原来出在 Alpine 使用的 musl 库上。原来几乎全部 Linux 发行版都使用 GNU 版本的 C 标准库 (glibc)。 但是 Alpine Linux 为了减小存储空间而使用了 musl 库。而我们通过 pip 安装的这些二进制 Python 包是基于 glibc 编译而成的。因此 Alpine 无法安装这些 python 库,只能通过源码编译的方式来进行安装。这也就是为什么 Alpine 的 Docker file 会与其它的不同,以及花费如此之多的时间进行构建的秘密。 我相信熟悉 Alpine 的用户会与我争论,Alpine 的 Edge 版本会解决这个问题。不幸的是,Edge 版本目前还不是稳定版本。如果用于生产环境,我们还是不要自寻烦恼为好。 [![](https://s3.cn-north-1.amazonaws.com.cn/awschinablog/choose-the-best-docker-image-for-your-python-application3.png)](https://s3.cn-north-1.amazonaws.com.cn/awschinablog/choose-the-best-docker-image-for-your-python-application3.jpg) 结论 -- 这个测试也许不能覆盖我们需要的各个角度,但至少给我们提供了一个选择的参考。而我在这个测试之后也得到了自己需要的结果, * Alpine 显然不适合作为 Python 应用的基础映像。尽管它提供了惊人存储的空间上效率,但它对于 Python 包支持的不足的缺陷是难以弥补的。也许 Alpine 更适合于一些对于映像尺寸敏感的场合,还可以考虑将它用于你的 Go 应用。 * 在 AWS 云计算的环境中,Amazon Linux 2 的性能表现是有目共睹的。如果你希望得到一个稳定、安全以及高性能的 Python 基础映像,那就不要忘记 Amazon Linux 2 这个选择。 * Ubuntu 18.04 以及 Debian 10 表现的中规中矩,完全在我的意料之中。考虑到 Debian 10(Buster)较 Ubuntu 更新一些。这应该是一个好选择。不过随着 Ubuntu 20.04 LTS 即将发布,在我的候选清单上也许要多出一个。 * 至于 Docker 官方的 Python 映像,并没有看出明显的优点。考虑到安全性与维护性的问题,我不认为这是个好的选择。 * 关于 Docker 基础映像的选择,还需要考虑的一点就是 Linux 一致性的问题。杂乱的、多样化的 Linux 版本会在大规模应用的时候带来不可预估的风险,不可掉以轻心。 本篇作者 ---- ![](https://s3.cn-north-1.amazonaws.com.cn/awschinablog/Author/lianghon.jpg) ### [ 费良宏](https://aws.amazon.com/cn/blogs/china/tag/<br>%E8%B4%B9%E8%89%AF%E5%AE%8F/) 费良宏,AWS Principal Developer Advocate。在过去的 20 多年一直从事软件架构、程序开发以及技术推广等领域的工作。他经常在各类技术会议上发表演讲进行分享,他还是多个技术社区的热心参与者。他擅长 Web 领域应用、移动应用以及机器学习等的开发,也从事过多个大型软件项目的设计、开发与项目管理。目前他专注与云计算以及互联网等技术领域,致力于帮助中国的 开发者构建基于云计算的新一代的互联网应用。 TAGS: [Python](https://aws.amazon.com/cn/blogs/china/tag/python/)
Jonny
2022年10月22日 09:32
148
0 条评论
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
如遇文档失效,可评论告知,便后续更新!
【腾讯云】2核2G云服务器新老同享 99元/年,续费同价
【阿里云】2核2G云服务器新老同享 99元/年,续费同价(不要✓自动续费)
【腾讯云】2核2G云服务器新老同享 99元/年,续费同价
【阿里云】2核2G云服务器新老同享 99元/年,续费同价(不要✓自动续费)
Markdown文件
Word文件
PDF文档
PDF文档(打印)
分享
链接
类型
密码
更新密码
有效期