谁说docker-compose不能水平扩展容器、服务多实例?

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 虽说我已经从docker-compose走上了docker swarm的邪门歪道,目前被迫走在k8s这条康庄大道, 但是我还是喜欢docker-compose简洁有效的部署方式。

曾其何时

docker-compose非常适合开发、测试、快速验证原型,这个小工具让单机部署容器变得简洁、高效。正如我在《docker-compose,docker-stack前世今生》里讲,所有人都认为docker-compose是单机部署多容器的瑞士军刀,没有docker stack由deploy配置节体现的生产特性(多实例、滚动部署、故障重启、负载均衡)。


796fb8c717bec17bd952ccbd1b745dac.png


最近我发现我错了:docker-compose还是具备服务多实例的能力的。


在docker-compose -h中发现了一个scale参数,这是个啥?

docker-compose还能水平扩展,实现多容器?

docker-compose定义的容器映射的主机端口不会冲突吗?


号主精心分析,才找到一个完备的理论来支持scale参数的合理性。在此文中,我们将演示一个示例,说明如何使用Docker Compose运行服务的多实例


version: "3"
services:
  webapp:
    image: "luksa/kubia"
    depends_on:
      - db
    ports:
      - "8080:8080"    # 主机Port: 容器暴露Port


在此文件中,我们定义了一个webapp服务(nodejs程序在8080端口监听

为webapp容器定义了端口映射:从容器8080端口映射到主机的8080端口,这样我们可以在主机上使用http://localhost:8080URL访问服务器。


Docker Compose --scale flag


当我们运行docker-compose up -h命令时, 其中--scale选项显示为服务指定多实例


--scale SERVICE=NUM        Scale SERVICE to NUM instances. Overrides the
                               `scale` setting in the Compose file if present.


很显然,使用目前的DockerCompose配置运行docker-compose up --scale webapp=3

将导致failed: port is already allocated错误


问题在于,我们试图运行webapp服务的三个实例,并将它们全部映射到主机同一端口,而「主机的8080端口只能绑定给一个容器」


解决错误的一种方法是将Docker Compose文件中的端口映射更改为- "8080", 这会将容器的端口8080暴露给主机上的临时未分配端口。


625c5bc5ede31fbaa062c5cade57915b.png


这个操作延伸出另一个问题:在启动容器之前,我们将不知道用于访问服务的端口。


要列出端口映射,请在运行docker-compose up --scale webapp=3之后运行docker-compose ps来查看容器:


Name          Command     State            Ports
-------------------------------------------------------------
test_webapp_1   node app.js   Up      0.0.0.0:32828->8080/tcp
test_webapp_2   node app.js   Up      0.0.0.0:32830->8080/tcp
test_webapp_3   node app.js   Up      0.0.0.0:32829->8080/tcp


添加负载均衡器


为了能够在不知道特定容器的端口的情况下访问webapp服务,并使用负载均衡机制将请求分发到容器,我们需要在容器堆栈中添加负载均衡器。


在此示例中,将使用nginx作为负载均衡器:来完成对外接收、对内转发。


a8953301dcc7f7cb5a1cf0e9e5c942ea.png


在与docker-compose.yml文件相同的目录中创建以下nginx.conf文件,代理&转发请求


user  nginx;
events {
    worker_connections   1000;
}
http {
        server {
              listen 80;
              location / {
                proxy_pass http://webapp:8080;
              }
        }
}


这将配置nginx将请求从主机端口80转发到 http://webapp:8080。然后将由Docker’s embedded DNS解决寻址:该DNS服务器使用轮询实现来根据服务名称解析DNS请求,并将其分发给Docker容器。


由于nginx服务负责对外接收请求、对内转发,因此webapp服务可不直接对外暴露。实际上我们可以从Docker Compose文件中删除webapp端口映射配置,而仅将端口8080通知给链接的nginx服务。


version: "3"
services:
  webapp:
    image: "luksa/kubia"
  nginx:
    image: nginx:latest
    volumes:
      - type: bind
        source: /home/root/test/nginx.conf
        target: /etc/nginx/nginx.conf
    depends_on:
      - webapp
    ports:
      - "80:80"


通过此配置,我们现在可以利用Docker Compose工具的scale水平扩展、实现服务多实例。docker-compose up  -d --scale  webapp=3


CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS                 PORTS                     NAMES
05b024964274        luksa/kubia                    "node app.js"            15 minutes ago      Up 15 minutes                                    test_webapp_1
2fb56a22810a        luksa/kubia                    "node app.js"            15 minutes ago      Up 15 minutes                                    test_webapp_3
84041c727b6e        luksa/kubia                    "node app.js"            15 minutes ago      Up 15 minutes                                    test_webapp_2
3882beae8b56        nginx:latest                   "nginx -g 'daemon of…"   15 minutes ago      Up 15 minutes          0.0.0.0:80->80/tcp      test_nginx_1


总结输出


  • docker-compose利用Docker引擎内嵌DNS,提炼出水平扩展容器、服务多实例的能力 (用一个代理就能应用这个能力)
  • Docker引擎内嵌DNS也是docker-compose利用服务名发现其他容器的关键


在需要测试具备水平扩展能力的web服务时,docker-compose up -d --scale 提供了一种快速、简便的途径。


以后谁再说docker-compose没有水平扩展容器、服务多实例的时候,就把这篇文章丢给他。


相关文章
|
4天前
|
存储 安全 数据安全/隐私保护
【Docker 专栏】Docker 容器化应用的备份与恢复策略
【5月更文挑战第9天】本文探讨了Docker容器化应用的备份与恢复策略,强调了备份在数据保护、业务连续性和合规要求中的关键作用。内容涵盖备份的重要性、内容及方法,推荐了Docker自带工具和第三方工具如Portainer、Velero。制定了备份策略,包括频率、存储位置和保留期限,并详细阐述了恢复流程及注意事项。文章还提及案例分析和未来发展趋势,强调了随着技术发展,备份与恢复策略将持续演进,以应对数字化时代的挑战。
【Docker 专栏】Docker 容器化应用的备份与恢复策略
|
4天前
|
监控 Kubernetes Docker
【Docker 专栏】Docker 容器内应用的健康检查与自动恢复
【5月更文挑战第9天】本文探讨了Docker容器中应用的健康检查与自动恢复,强调其对应用稳定性和系统性能的重要性。健康检查包括进程、端口和应用特定检查,而自动恢复则涉及重启容器和重新部署。Docker原生及第三方工具(如Kubernetes)提供了相关功能。配置检查需考虑检查频率、应用特性和监控告警。案例分析展示了实际操作,未来发展趋势将趋向更智能和高效的检查恢复机制。
【Docker 专栏】Docker 容器内应用的健康检查与自动恢复
|
2天前
|
Java 虚拟化 Docker
Docker简介及用途,为什么要使用Docker?Docker容器和虚拟机的区别
Docker简介及用途,为什么要使用Docker?Docker容器和虚拟机的区别
|
2天前
|
存储 Linux Docker
CentOS7修改Docker容器和镜像默认存储位置
CentOS7修改Docker容器和镜像默认存储位置
|
2天前
|
Linux Docker 容器
更改docker容器中的时间而不影响宿主机
更改docker容器中的时间而不影响宿主机
|
2天前
|
Ubuntu Linux Go
docker容器启动报错
docker容器启动报错解决
|
4天前
|
Ubuntu Docker 容器
docker容器保存和导入
docker容器保存和导入
20 0
|
4天前
|
Ubuntu Docker 容器
清理docker容器
清理docker容器
12 0
|
4天前
|
Prometheus 监控 Cloud Native
构建高效稳定的Docker容器监控体系
【5月更文挑战第14天】 在现代微服务架构中,Docker容器作为应用部署的基本单元,其运行状态的监控对于保障系统稳定性和性能至关重要。本文将探讨如何构建一个高效且稳定的Docker容器监控体系,涵盖监控工具的选择、关键指标的采集、数据可视化以及告警机制的设计。通过对Prometheus和Grafana的整合使用,实现对容器资源利用率、网络IO以及应用健康状态的全方位监控,确保系统的高可用性和故障快速响应。
|
4天前
|
Prometheus 监控 Cloud Native
构建高效稳定的Docker容器监控体系
【5月更文挑战第13天】在微服务架构和容器化部署日益普及的背景下,对Docker容器的监控变得尤为重要。本文将探讨一种构建高效稳定Docker容器监控体系的方法,通过集成Prometheus和cAdvisor工具,实现对容器资源使用情况、性能指标和运行状态的实时监控。同时,结合Grafana进行数据可视化,为运维人员提供直观的分析界面,以便及时发现和解决潜在问题,保障系统的高可用性和稳定性。
30 6