在京东云 ECS 上跑 Docker + MySQL,看似简单,实则坑不少。很多新手直接 docker run 一把梭,结果要么连不上,要么数据丢了,要么慢得怀疑人生。
作为在云原生领域摸爬滚打多年的“老鸟”,我把核心注意事项拆解为 网络、存储、性能、安全 四个维度,全是干货,不整虚的。
一、 网络配置:别被“防火墙”和“端口映射”搞死
这是最常见的问题:本地能连,网络连不上。
-
京东云安全组(Security Group)必须放行
- Docker 容器内部监听的 3306 端口,只是容器内的虚拟网络。
- 你必须在京东云控制台的 ECS 实例 -> 安全组 中,添加入方向规则:允许 TCP 协议的 3306 端口访问(源 IP 建议限制为你的固定 IP 或内网 CIDR,不要直接
0.0.0.0/0,除非你是做公开测试)。 - 注意:很多人只开了 Docker 的
-p 3306:3306,却忘了开安全组,导致白忙活。
-
绑定地址问题(bind-address)
- MySQL 默认可能只监听
127.0.0.1。 - 在 Docker 中运行 MySQL 时,确保你的
my.cnf或者启动参数中没有强制绑定到127.0.0.1。 - 推荐做法:使用
--network host模式(如果安全性要求不高且追求极致性能),或者确保 MySQL 配置为0.0.0.0或注释掉bind-address。
- MySQL 默认可能只监听
-
Docker 网络模式选择
- bridge(默认):需要端口映射
-p,适合单机多实例隔离。 - host:性能最好,无 NAT 损耗,但端口冲突风险高。如果你只用一个 MySQL,推荐这个,尤其是高并发场景。
- 自定义 bridge:更灵活,适合微服务架构,通过服务名解析连接。
- bridge(默认):需要端口映射
二、 数据存储:持久化是底线
绝对不要把数据库文件存在容器的可写层里!一旦容器重启、更新或崩溃,数据直接清零。
-
挂载宿主机目录或云盘
docker run -d --name mysql-prod -v /data/mysql:/var/lib/mysql .../data/mysql建议在京东云 ECS 上挂载一块 高效云盘 或 SSD 云盘,而不是直接用宿主机的系统盘/var/lib/docker。因为系统盘 IOPS 有限,且系统升级可能误删数据。- 权限问题:首次挂载时,MySQL 进程以非 root 用户(通常是 999 或 mysql)运行,你可能需要先
chown -R 999:999 /data/mysql或chmod 777(临时调试用,生产环境请精细控制权限)。
-
备份策略
- 即使有持久化,也要定期备份。可以使用
mysqldump脚本定时执行,并推送到京东云 OSS 或其他对象存储。 - 考虑使用 Percona XtraBackup 进行热备,对业务影响更小。
- 即使有持久化,也要定期备份。可以使用
三、 性能调优:别让 MySQL 成为瓶颈
Docker 不是魔法,它增加了轻微的开销。在 ECS 上跑 MySQL,你需要针对容器环境微调。
-
内存限制(cgroups)
- MySQL 非常吃内存。不要给它设太低的
--memory限制,否则 OOM Killer 会随时杀掉它。 - 建议:如果 ECS 有 8G 内存,给 MySQL 容器分配至少 4-6G,并设置
--memory-swap相同值,防止 swap 导致性能暴跌。
- MySQL 非常吃内存。不要给它设太低的
-
关键参数调整
- innodb_buffer_pool_size:设为物理内存的 50%-70%。在 Docker 中,可以通过
docker inspect获取容器可用内存,动态计算。 - character-set-server & collation-server:务必显式指定为
utf8mb4和utf8mb4_unicode_ci,避免表情符号报错和排序问题。 - max_connections:Docker 环境下,由于连接复用机制不同,可适当调高,但不要超过操作系统文件描述符限制。
- innodb_buffer_pool_size:设为物理内存的 50%-70%。在 Docker 中,可以通过
-
I/O 优化
- 如果使用 SSD 云盘,确保挂载选项正确。
- 在
my.cnf中启用innodb_flush_method=O_DIRECT,减少双重缓冲,提升写入性能。 - 关闭不必要的日志:如
general_log,生产环境开启slow_query_log即可。
-
CPU 亲和性(可选高级技巧)
- 对于超高并发场景,可以使用
--cpuset-cpus将 MySQL 绑定到特定 CPU 核心,减少上下文切换。但这需要你对硬件架构有深入了解。
- 对于超高并发场景,可以使用
四、 安全与运维:别留后门
-
初始密码与安全
- 启动时必须设置
MYSQL_ROOT_PASSWORD。 - 严禁使用 root 账户连接应用!创建专用数据库用户,赋予最小权限。
- 示例:
CREATE USER 'app_user'@'%' IDENTIFIED BY 'StrongPassword123!'; GRANT ALL PRIVILEGES ON mydb.* TO 'app_user'@'%'; FLUSH PRIVILEGES;
- 启动时必须设置
-
日志管理
- Docker 默认会将 stdout/stderr 输出到 json-file 驱动。如果 MySQL 产生大量错误日志,会导致宿主机磁盘爆满。
- 解决方案:
- 在
docker run中使用--log-driver=json-file --log-opt max-size=10m --log-opt max-file=3限制日志大小。 - 或者将 MySQL 的错误日志重定向到文件,并通过
docker logs查看时忽略。
- 在
-
健康检查(Healthcheck)
- 不要让 Kubernetes 或编排工具认为 MySQL 活着,实际上它已经卡死。
- 添加健康检查:
healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s timeout: 5s retries: 3
-
版本一致性
- 明确指定镜像标签,如
mysql:8.0.33,不要用latest。生产环境最怕“今天正常,明天升级后崩盘”。
- 明确指定镜像标签,如
五、 京东云特有建议
-
利用 VPC 内网
- 如果你的应用也在京东云 ECS 上,务必使用 VPC 内网 IP 连接 MySQL,不要走公网。内网延迟低、带宽大、免费。
- 在 Docker 中,通过
--network连接到同一个 VPC 下的自定义网络,或使用 Service Mesh。
-
监控告警
- 京东云提供云监控服务。记得将 MySQL 的关键指标(QPS、TPS、连接数、磁盘使用率)接入监控。
- 设置阈值告警,比如磁盘使用率超过 80% 立即通知。
-
快照备份
- 除了数据库逻辑备份,定期对挂载的云盘创建快照。这是最后的救命稻草,防止误删表或勒索病毒。
总结 Checklist
| 项目 | 关键点 |
|---|---|
| 网络 | 京东云安全组放行 3306;MySQL bind-address 不为 127.0.0.1 |
| 存储 | 数据卷挂载到独立云盘;权限正确;定期备份到 OSS |
| 性能 | innodb_buffer_pool_size 合理设置;禁用 swap;O_DIRECT |
| 安全 | 非 root 用户访问;强密码;限制最大连接数;日志轮转 |
| 运维 | 固定镜像版本;添加健康检查;VPC 内网通信 |
按这个清单配置,你的 MySQL 在京东云 ECS 上的 Docker 容器就能稳定、高效地运行了。有问题再问,别客气。
云知道CLOUD