别让 Docker 毁了你的 MySQL!

后端   2024-03-28 10:00   187   0  

近年来,随着 Docker 容器技术的火热,越来越多的应用开始被"装箱"。我们这些开发者享受着 Docker 带来的便捷和灵活,几乎恨不得把所有东西都塞进容器里。于是,连 MySQL 这样的有状态服务,也开始频频出现在 Docker 的舞台上。

但是,把 MySQL 装进 Docker,真的是个明智的选择吗?是否会给系统稳定性和数据安全带来隐患?这个问题在社区里引发了激烈的讨论。

"Docker 与有状态服务无缘"派

持反对意见的一派认为,所有有状态的服务,都不应该放在 Docker 里跑。他们列举了 MySQL、Redis、Elasticsearch、ActiveMQ 等服务作为例子,理由是这些服务都需要保证高可用和稳定性,而这恰恰是 Docker 难以做到的。

即便是在 Kubernetes 这样的容器编排平台中,他们也不建议把有状态服务放进去。这也是为什么云厂商会专门提供 MySQL、Redis、MQ 等服务的原因。

那么,究竟是什么原因让"Docker 与有状态服务无缘"呢?

首先,传统的高可用方案在容器中难以实现。以 MySQL 为例,传统的 HA 方案通常是两台机器+共享存储+Fence 设备。

但在 Kubernetes 中,这种方案如何配置?Fence 设备又该如何在容器中实现?这些都是没有现成答案的问题。

其次,一些 MySQL 的高可用和集群方案与 Docker 的理念不太兼容。

比如,MySQL 8.0 的 InnoDB Cluster 通常采用 1 主 2 从的模式,这在 Kubernetes 中如何实现?虽然有 MySQL Operator 这样的尝试,但成熟度和可行性还有待验证。

最后,对于 DBA 来说,在虚拟机上部署 MySQL 才是最熟悉和放心的方式。

毕竟数据库最需要的是稳定,调整 CPU、内存、磁盘等参数,再加上定期备份,就可以做到大多数时候"甩手掌柜"。

如果是在公有云上,那就更应该直接用云厂商提供的 MySQL 服务。

在他们看来,Docker 适合运行无状态服务。因为无状态服务挂了就拉起来,不需要做额外的检查,而有状态服务则可能由于数据不一致而带来新的问题。

"MySQL 照样可以容器化"派

但支持在 Docker 中运行 MySQL 的声音也不小。毕竟,所有主流数据库都已经提供了官方镜像,多数也有容器化的集群方案。他们认为,只要在部署时遵循一些最佳实践,就可以充分发挥 Docker 的优势,而不必担心稳定性和性能问题。

首先,在部署 MySQL 容器时,一定要记得挂载数据卷(Data Volume) 。通过数据卷,可以将容器内的数据目录映射到宿主机上,这样不仅可以避免容器删除时数据丢失,还能减少额外的 I/O 开销。例如,如果我们希望将容器内的 /var/lib/mysql 目录(MySQL 默认的数据目录)映射到宿主机的 /my/own/datadir 目录,可以在启动容器时使用 -v 参数:

bash复制代码docker run --name some-mysql -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag


除了手动指定目录,我们也可以使用 Docker 的命名卷(Named Volume)功能。命名卷可以由 Docker 来管理,不需要我们关心具体的存储位置:

bash复制代码docker run --name some-mysql -v mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag


如果要实现 MySQL 的配置文件外挂,也可以通过数据卷来实现:

bash复制代码docker run --name some-mysql -v /my/own/datadir:/var/lib/mysql -v /my/custom/mysql.cnf:/etc/mysql/conf.d/mysql.cnf -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag


其次,使用容器部署 MySQL 有诸多优点。容器可以封装不同版本的 MySQL,而不用担心与宿主机的兼容性问题。同时,由于容器之间是隔离的,可以保证 MySQL 不会与其他服务产生干扰。此外,通过容器还能在单机上部署多个 MySQL 实例,提高资源利用率

至于性能问题,支持者认为在正确使用数据卷的情况下,MySQL 容器的性能损失微乎其微。毕竟容器只是一层轻量级的封装,并不会对 I/O、网络等产生实质影响。

在 Kubernetes 中部署有状态服务,通常需要用到 StatefulSet 和 PersistentVolumeClaim(PVC) 。StatefulSet 用于管理有状态的应用,它为每个 Pod 提供一个唯一且固定的标识符。PVC 则用于申请持久化存储。下面是一个简单的 StatefulSet 示例,用于部署一个单节点的 MySQL:

apiVersion: apps/v1 
kind: StatefulSet 
metadata:
   name: mysql 
spec:   
    serviceName: mysql
    replicas: 1   
    selector:
        matchLabels:
            app: mysql
        template: 
            metadata:
                labels:
                    app: mysql
           spec:       
                   containers:         
                       - name: mysql           
                           image: mysql:5.7           
                           env:             
                               - name: MYSQL_ROOT_PASSWORD               
                                   value: my-secret-pw           
                           volumeMounts:             
                               - name: data               
                                   mountPath: /var/lib/mysql   
        volumeClaimTemplates:     
            - metadata:         
                name: data       
            spec:         
                accessModes: ["ReadWriteOnce"]         
                    resources:           
                        requests:             
                            storage: 10Gi


在这个例子中,StatefulSet 会自动为 MySQL 的 Pod 创建一个专属的 PVC,并将其挂载到容器的 /var/lib/mysql 目录。这样,即使 Pod 重建,它的数据也不会丢失。

当然,这只是一个最简单的示例。在实际使用中,我们可能还需要配置 MySQL 的主从复制、读写分离等,这就需要更复杂的 StatefulSet 和 Service 配置了。

求同存异,因地制宜

对于我这个又做开发又做 DevOps 的过来人觉得,MySQL 是否适合容器化,还是要具体问题具体分析。正如 Stackoverflow 上一位答主所说,

技术只是达成目标的工具,适合自己的才是最好的

对于开发和测试环境,或者对性能和稳定性要求不高的场景,Docker 化的 MySQL 确实能带来不少便利。开发者可以快速搭建数据库,方便地进行各种实验和测试。

对于生产环境尤其是核心系统的数据库,稳定性和数据安全性无疑是第一位的,这时谨慎一些,采用成熟的方案或许更有保障。

同时也要认识到,容器技术正在飞速发展,很多以前难以想象的场景,现在都已逐渐成为可能。比如有了 Kubernetes、Operator 这样的云原生技术,有状态服务在容器中的管理已经比以前简单很多。未来会怎样,现在下定论还为时尚早。

在 Docker 和 Kubernetes 中运行有状态服务,关键是要充分利用数据卷和 PVC,确保数据的持久性和可恢复性。同时,也要根据实际需求,合理配置服务的高可用和负载均衡。

或许,比较理想的方式是在掌握传统运维的基础上,多了解和学习云原生的新技术,根据自己的实际情况分析利弊,然后再决定是否要上容器的"车"。

与其教条地说"必须用"或"绝不用",不如开放一些,拥抱变化


作者:程序员安仔
链接:https://juejin.cn/post/7344571269555060799
来源:稀土掘金

博客评论
还没有人评论,赶紧抢个沙发~
发表评论
说明:请文明发言,共建和谐网络,您的个人信息不会被公开显示。