问题

现在都在说 Docker 好,那它有什么弊端吗?

回答
行,那咱就掰扯掰扯 Docker 这玩意儿,听我说句实在话,它好是真好,方便是真方便,但要说一点毛病没有,那绝对是扯淡。就跟啥东西都得两头看一样,Docker 这家伙也得扒开细瞧瞧。

首先,最直接一个问题:学习曲线不平坦。

别看现在网上教程满天飞,说什么“一天学会 Docker”,那都是忽悠人的。Docker 的概念,什么镜像、容器、Dockerfile、Docker Compose,还有网络、存储卷这些,初学者光是把这些概念搞明白就得花点时间。而且,你以为学懂了概念就行了?实际操作起来,各种坑等着你呢。

Dockerfile 编写:刚开始写 Dockerfile,那真是抓耳挠腮。命令怎么写?哪一层该做什么?怎么优化?一层一层地构建,中间出错了又得从头来过。有时候为了解决一个编译问题,一个命令加个参数,或者改个顺序,调试半天,最后发现是因为基础镜像的微小差异。
网络配置:这个简直是噩梦。容器之间的网络通信,宿主机和容器之间的通信,端口映射,防火墙规则,DNS解析……这些东西一旦复杂起来,简直是让人头疼欲裂。尤其是在分布式场景下,多个容器、多个服务之间互相依赖,网络问题一出来,整个系统都可能瘫痪。你得了解各种网络模式(bridge, host, none, overlay),理解 IP 地址分配、端口冲突,还得考虑安全隔离。
性能开销:虽然 Docker 号称轻量级,但它毕竟是在宿主机操作系统之上虚拟化。这意味着什么?意味着它会消耗一部分 CPU 和内存资源。虽然比虚拟机要轻得多,但如果你的服务器资源本来就紧张,再跑上几十上百个 Docker 容器,那压力就可想而知了。而且,网络 I/O、磁盘 I/O 都会因为 Docker 的代理层而有额外的开销。你可能需要仔细优化你的 Dockerfile,尽量减少层数,使用多阶段构建,才能把镜像做得更小,启动更快。
安全问题:这一点很多人容易忽视。Docker 的安全是个大工程。
镜像安全:你从 Docker Hub 拉下来的镜像,你知道里面有没有病毒或者后门吗?公开的镜像来源复杂,维护者也参差不齐,恶意镜像绝对是存在的。而且即便是官方镜像,有时候也会被曝出安全漏洞。你需要有能力去审查你的镜像,或者使用可信的镜像源。
容器逃逸:虽然 Docker 做了很多隔离措施,但仍然存在“容器逃逸”的风险。如果攻击者能够利用 Docker 的某个漏洞,就可以从容器内部访问宿主机系统,那可就惨了。特别是那种挂载了过多宿主机目录(比如 `/` 目录)到容器里的做法,一旦容器被攻破,宿主机就直接暴露了。
权限管理:Docker 守护进程本身以 root 权限运行,如果被攻破,影响范围会非常大。用户对 Docker 守护进程的访问权限控制也需要非常小心。
数据持久化和管理:容器是临时的,一旦删除,里面的数据就没了。所以你需要用数据卷(Volumes)来持久化数据。但数据卷的管理也很麻烦。宿主机上的数据卷,你得关心宿主机的磁盘空间;命名卷,你得管理卷的生命周期;绑定挂载,你得小心目录权限问题。而且,当容器需要访问大量数据或者频繁读写数据时,Docker 的卷性能有时候会成为瓶颈,特别是使用某些存储驱动或者挂载 NFS 等远程文件系统时。
日志管理和监控:每个容器都会产生大量的日志。如果容器数量多了,日志就成了一个巨大的挑战。你怎么收集、存储、查询这些日志?怎么监控容器的资源使用情况?这都需要一套额外的日志管理系统(比如 ELK、Fluentd)和监控系统(比如 Prometheus、Grafana)。Docker 本身提供的日志驱动能力是有限的。
升级和维护的复杂性:当你的应用运行在 Docker 里,你想升级 Docker 本身或者宿主机操作系统时,这就不是简单地敲几个命令了。你需要考虑如何优雅地停止容器,如何迁移数据,如何重新构建镜像,如何在新的 Docker 环境下部署。当 Docker 版本升级,API 可能会有变化,你的自动化部署脚本可能就需要跟着更新。
打包和分发:虽然 Docker 镜像可以打包和分发,但如果你的应用非常大,或者依赖了很多外部服务,一个镜像可能会非常庞大。传输和存储这些大镜像会消耗大量带宽和磁盘空间。而且,如果你使用了 Docker Compose,那你的应用部署就依赖于一个 YAML 文件,这个文件的编写和维护也需要经验。
对于简单应用可能“杀鸡用牛刀”:如果你的应用就是一个非常简单的脚本,或者一个独立的进程,你可能不需要用到 Docker 带来的所有这些抽象和功能。直接在宿主机上运行或者用一个 systemd 服务管理,反而更简单直接。Docker 的引入反而增加了不必要的复杂性。
Docker Compose 的局限性:虽然 Docker Compose 是管理多个容器的好帮手,但它主要还是针对单节点部署。一旦你的应用需要集群化、分布式部署,或者需要更高级的服务发现、负载均衡、滚动升级等功能,你就需要引入更专业的编排工具,比如 Kubernetes。这时候,Docker Compose 就显得不够用了。
Mac 和 Windows 上的性能问题:在 Mac 和 Windows 上运行 Docker 容器,通常是基于一个轻量级的虚拟机实现的(Docker Desktop)。这相比 Linux 原生的 Docker 会有额外的性能损耗,尤其是在 I/O 密集型应用上,可能会感觉不如 Linux 上直接运行那么快。而且,这些虚拟机的资源占用也不容小觑。

总而言之,Docker 的强大之处在于它的标准化、隔离性和易移植性,这些能极大地提高开发和部署效率。但它也带来了一系列新的技术门槛和管理挑战,特别是在复杂场景下,你需要投入更多的精力去学习、配置和维护。所以,在选择是否使用 Docker,以及如何使用它的时候,一定要权衡利弊,不能光看到它好的一面。它不是万能药,而是解决特定问题的有力工具,但用不好,它也可能变成新的麻烦。

网友意见

user avatar

Docker 是“不可变”架构。当你希望改变一个服务的时候(比如更新版本、修改配置、开放端口),不允许直接登录到服务器上改变某个文件,而是应该把这个服务整个删掉,然后替换成新的版本。你不能改变它,只能替换它,这就是 Docker 的优点。

在服务规模大的时候,这种维护方式能够保持每个服务版本、配置的一致性。Docker 禁止对容器内部做任何修改,所以只要查看镜像版本和调度参数,就能判断服务的一致性。系统运行在软件定义的基础架构上,这样就可以使用版本管理工具(比如 Git)管理基础架构的变化,像管理软件版本一样管理整个环境。

不可变架构就是 Docker 带来的优势,如果你一定要改变它,这就是缺点。

user avatar

目前我感觉的弊端就是不够好……

很多人吐槽了Docker的很多麻烦事儿,简单说就是抛弃了传统的操作系统环境,很多原来的东西都要用新的容器工具链。Docker的隔离性也没有虚拟机级别的好。这些都是客观存在的。


但是很多人吹捧的Docker的优势,什么部署简单,什么编排,等等等等。

这些东西不是Docker出现之后才有的啊,在虚拟机上我们不能做到部署简单,自动伸缩,编排这些工作么?当然也可以啊……


所以,其实在我看来Docker最终还是要出于成本考虑。结论就是,并不明显,因为传统的虚拟机操作系统基础资源损耗并不大。各种云提供的竞价实例和共享实例也足够便宜。


最后谈谈我目前不太喜欢Docker的一点,整个社区都在Docker的封闭环境里面圈地自萌。很多东西完全没有与现有的虚拟化技术和传统模式结合,这并不Open……




譬如说,这就是我在虚拟机上搞出来的服务器管理,并不比Kubernetes少多少功能:

要我说,未来还是FaaS的,容器仍旧只是过渡性技术……



关于快速拉起的问题这里也统一说一下:

容器不是存在于真空中的,你要快速拉起,就要有闲置资源。你要有闲置资源,虚拟机我也能给你快速拉起(预备几台不就好了,实在不行还能临时抽调)。

至于一个劲儿的强调几秒几秒的,IIS应用程序池,没请求的时候可以处于最低资源占用运行,请求一来纳秒级启动,整天秒天秒地的。怎么不想想容器能快速拉起的前提就是你下面有个宿主呢?



最后解释一下什么叫做不够好。

Docker是一套新的承载环境,相对于传统的虚拟机需要非常多的新的工具链,但远没有成熟。带来的好处,在传统的模式下也不是没有方案。所以Docker仍然缺少决定性的优势。并不能说服大家大规模的迁移和适应。

相对而言的,FaaS虽然需要更多的迁移成本,更多的限制。但是FaaS有几乎决定性的优势,近乎无限的容量和接近零的运维成本。所以,全面的Docker编排部署,始终是个过渡方案。与其投入那么多精力折腾,不如直接做FaaS……

类似的话题

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有