- MySQL,企业级云数据库,数据持久化是其特性,
- Docker,一个随时都可能被停止使用的容器。
你告诉我把数据库MySQL容器化合理吗?合理吗?
蓝队云资深运维工程师告诉你,不算是从性能,还是数据安全等多个方面来看,MySQL都不需要容器化。
数据持久化挑战
假设你正在开发一个电商应用,并决定使用Docker来部署整个应用栈,包括MySQL数据库。如果不恰当地处理数据持久化,一旦docker容器意外停止或重启,你的用户数据(如订单信息、用户账户等)可能会丢失。
所以,不要将数据储存在容器中。Docker容器是临时的,当容器停止或删除后,容器内的数据将会丢失。为了避免数据丢失,用户可以使用数据卷挂载来存储数据。但是容器的 Volumes 设计是围绕 Union FS 镜像层提供持久存储,数据安全缺乏保证。如果容器突然崩溃,数据库未正常关闭,可能会损坏数据。另外,容器里共享数据卷组,对物理机硬件损伤也比较大。即使你要把 Docker 数据放在主机来存储 ,它依然不能保证不丢数据。Docker volumes 的设计围绕 Union FS 镜像层提供持久存储,但它仍然缺乏保证。使用当前的存储驱动程序,Docker 仍然存在不可靠的风险。如果容器崩溃并数据库未正确关闭,则可能会损坏数据。
存在性能瓶颈
大家都知道,MySQL 属于关系型数据库,对IO要求较高。当一台物理机跑多个时,IO就会累加,导致IO瓶颈,大大降低 MySQL 的读写性能。
假设在在高并发的电商大促期间,你的应用需要处理大量的事务和查询。如果MySQL运行在Docker容器中,并且容器的资源分配不当(如CPU和内存限制过低),可能会导致性能瓶颈,影响用户体验。
其实也有相对应的一些策略来解决这个问题,比如:
1)数据库程序与数据分离
如果使用Docker 跑 MySQL,数据库程序与数据需要进行分离,将数据存放到共享存储,程序放到容器里。如果容器有异常或 MySQL 服务异常,自动启动一个全新的容器。另外,建议不要把数据存放到宿主机里,宿主机和容器共享卷组,对宿主机损坏的影响比较大。
2)跑轻量级或分布式数据库
Docker 里部署轻量级或分布式数据库,Docker 本身就推荐服务挂掉,自动启动新容器,而不是继续重启容器服务。
3)合理布局应用
对于IO要求比较高的应用或者服务,将数据库部署在物理机或者KVM中比较合适。
存在安全隐患
默认情况下,Docker容器内的进程以root用户身份运行,这为潜在的安全攻击提供了便利。如果MySQL容器被恶意利用,攻击者可能会获得宿主机上的root权限。
一些优化的策略:
- 使用Docker的User Namespaces功能来限制容器内进程的权限。
- 配置MySQL以使用强密码,并限制远程访问。
- 使用防火墙和网络策略来限制对MySQL端口的访问。
- 定期更新Docker和MySQL的安全补丁。
配置和管理的复杂性
在Docker中部署MySQL意味着你需要处理额外的配置,如环境变量设置、网络配置和存储配置等。此外,你还需要监控和管理多个容器实例。
一些优化的策略:
- 使用Docker Compose或Kubernetes等容器编排工具来简化配置和管理。
- 编写Dockerfile和Docker Compose文件时,尽量保持简单明了,避免过度配置。
- 利用自动化工具(如Ansible、Terraform)来自动化部署和配置过程。
虽然Docker为应用部署带来了诸多便利,但在将MySQL等关键数据库服务部署到Docker容器中时,我们需要仔细权衡其潜在的问题和挑战。
云平台的不适用性
大部分人通过公有云开始项目。云简化了虚拟机操作和替换的复杂性,因此不需要在夜间或周末没有人工作时间来测试新的硬件环境。当我们可以迅速启动一个实例的时候,为什么我们需要担心这个实例运行的环境?
这就是为什么我们找云提供商的意义。当我们为实例放置数据库容器时,上面说的这些便利性就不存在了。因为数据不匹配,新实例不会与现有的实例兼容,如果要限制实例使用单机服务,应该让 DB 使用非容器化环境,我们仅仅需要为计算服务层保留弹性扩展的能力。
综上所述,虽然Docker为应用部署带来了诸多便利,但在将MySQL等关键数据库服务部署到Docker容器中时,我们需要仔细权衡。
当然,在Docker中运行MySQL并不是绝对不可行的,我们可以把数据丢失不敏感的业务(搜索、埋点)就可以数据化,利用数据库分片来来增加实例数,从而增加吞吐量。
蓝队云是提供7*24小时技术运维的云计算服务商,运维工程师经验丰富,整理了一套运维工具包,分享给大家,包含大量Docker,磁盘工具、测速工具、日志查看工具、镜像制作工具等,特别适合运维工程师及后端开发人员学习参考,需要的朋友可以联系自取。