在阿里云 ECS 上同时管理多个 Docker 容器,核心思路其实就两条:编排(Orchestration)和自动化运维。
别被那些复杂的术语吓到,咱们直接说实操。对于大多数中小规模业务或者个人开发者,不需要一上来就搞 K8s,那样成本太高且维护复杂。以下是几种从简单到进阶的可行方案,按推荐程度排序:
方案一:Docker Compose(最推荐,适合单机多服务)
这是目前最主流、最轻量的管理方式。你只需要在一个 docker-compose.yml 文件里定义好所有容器的镜像、端口映射、环境变量、数据卷挂载等,然后通过一条命令就能启动、停止、更新整个应用栈。
为什么选它?
- 配置集中化:所有服务的依赖关系写在一个 YAML 文件里,版本控制方便(Git 管理)。
- 一键启停:
docker-compose up -d启动所有,docker-compose down清理所有。 - 网络隔离:Compose 会自动创建内部网络,容器之间可以通过服务名互相访问,不用手动配 IP。
实操步骤:
-
安装 Docker Compose
阿里云 Ubuntu/CentOS 镜像通常自带 Docker,但可能没带 Compose。# Ubuntu/Debian sudo apt-get install docker-compose-plugin # CentOS/RHEL (需要额外源或单独下载二进制) # 推荐直接下载二进制文件放到 /usr/local/bin/docker-compose sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose -
编写
docker-compose.yml
假设你要跑一个 Nginx + MySQL + PHP-FPM 的项目:version: '3.8' services: nginx: image: nginx:latest ports: - "80:80" volumes: - ./html:/usr/share/nginx/html depends_on: - php networks: - app-network mysql: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: example volumes: - db-data:/var/lib/mysql networks: - app-network php: image: php:fpm volumes: - ./html:/var/www/html depends_on: - mysql networks: - app-network volumes: db-data: networks: app-network: driver: bridge -
运行与管理
# 后台启动所有容器 docker-compose up -d # 查看状态 docker-compose ps # 重启某个服务(比如改了配置) docker-compose restart nginx # 更新镜像并重新部署 docker-compose pull docker-compose up -d --force-recreate
注意事项:
- 持久化数据:务必使用 Volume 挂载数据库数据,否则容器重建数据就丢了。
- 日志管理:Docker 默认日志会无限增长,建议在 Compose 中配置 log-driver 限制大小,或者用
journalctl配合 systemd 管理。
方案二:Portainer(可视化 GUI 管理)
如果你不喜欢敲命令,或者团队里有非开发人员需要偶尔查看容器状态,Portainer 是最佳选择。它是一个轻量级的 Docker 管理界面。
优点:
- Web UI 直观,能看到 CPU/内存占用、日志流。
- 支持模板快速部署常见应用(WordPress, GitLab 等)。
- 支持远程管理多台服务器(包括你的阿里云 ECS)。
部署方式:
# 创建一个 volume 存储 Portainer 数据
docker volume create portainer_data
# 启动 Portainer
docker run -d -p 9000:9000 --name=portainer
--restart=always
-v /var/run/docker.sock:/var/run/docker.sock
-v portainer_data:/data
portainer/portainer-ce:latest
然后浏览器访问 http://<你的ECS公网IP>:9000 即可。记得在阿里云安全组开放 9000 端口,并设置强密码。
缺点:
- 增加了一层依赖,如果 Portainer 挂了,你可能需要通过 SSH 命令行恢复。
- 不适合超大规模集群(几百个容器以上),性能会有瓶颈。
方案三:Kubernetes (K8s) / 阿里云 ACK(适合大规模、高可用)
如果你的业务量很大,需要自动扩缩容、故障自愈、灰度发布,那单台 ECS 已经不够用了,需要考虑分布式架构。
路径选择:
- 自建 K8s:在阿里云 ECS 上自己搭建 Master + Node 节点。技术门槛极高,不推荐新手尝试,踩坑无数。
- 阿里云容器服务 ACK:阿里云托管的 K8s 服务。你只需要关注应用部署,底层基础设施由阿里云维护。
- 优势:无缝集成 VPC、SLB、云盘、监控报警。
- 劣势:费用相对较高,学习曲线陡峭。
何时选这个?
- 微服务架构,服务数量超过 10+。
- 需要跨可用区高可用。
- 有专门的 DevOps 团队负责 CI/CD 流水线。
关键补充:阿里云环境下的特殊优化
不管用哪种方案,在阿里云 ECS 上跑 Docker,有几个“血泪教训”必须注意:
1. 安全组配置
- 不要暴露所有端口:只暴露必要的入口端口(如 80, 443, 22)。Docker 容器内部的端口(如 3306, 6379)绝对不要映射到公网。
- 白名单策略:如果要用 Portainer 或 Redis 等管理工具,尽量通过 SSH 隧道或限制特定 IP 访问。
2. 资源限制与 OOM
- 阿里云 ECS 实例规格是有限的。Docker 默认没有内存限制,一个死循环的容器可能吃光内存导致主机宕机。
- 建议:在 Compose 或 Docker run 时加上资源限制:
deploy: resources: limits: cpus: '0.5' memory: 512M reservations: cpus: '0.25' memory: 256M
3. 日志轮转(Log Rotation)
- Docker 默认将日志输出到 JSON 文件,存放在
/var/lib/docker/containers/。 - 风险:日志文件会无限增长,撑爆系统盘,导致 ECS 无法登录。
- 解决:修改
/etc/docker/daemon.json添加全局日志驱动配置:{ "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }然后重启 Docker 服务:
systemctl restart docker
4. 备份与迁移
- 定期备份 Docker Compose 文件和 Volume 数据。
- 阿里云提供快照功能,可以对系统盘和数据盘做快照,这是最后的救命稻草。
总结建议
- 个人项目/小型网站:直接用 Docker Compose,配合 Nginx Proxy Manager 或简单的 Nginx 反向XX,搞定域名解析和 HTTPS。
- 团队协作/不想记命令:加一个 Portainer,其他不变。
- 企业级生产环境:直接上 阿里云 ACK,虽然贵点,但省心,稳定性有保障。
别再纠结于“怎么手动一个个 start 容器”了,那是 2015 年的做法。现在都用声明式配置(YAML)来管理基础设施即代码(IaC)的思想。
云技术博客