如何向docker-compose多副本服务的所有容器广播执行shell命令
docker-compose 副本模式下广播执行命令的方法
问题场景
我正在使用docker运行spark worker节点,通过docker-compose配置副本模式部署,配置如下:
version: '2' services: spark-worker: image: bitnami/spark:latest environment: - SPARK_MODE=worker - SPARK_MASTER_URL=spark://1.1.1.1:7077 deploy: mode: replicated replicas: 4
执行docker-compose exec spark-worker ls时,命令默认只会在第一个副本容器内运行,需要实现命令在所有副本容器中广播执行的效果。
当前运行环境版本:
- docker-compose: 1.29.2, build 5becea4c
- Docker: 20.10.7, build f0df350
实现方法
docker-compose 原生没有提供一键广播exec到所有副本的参数,可以通过以下方式实现:
1. 遍历容器ID批量执行
通过docker-compose ps -q <服务名>获取服务下所有副本的容器ID,循环调用docker exec在每个容器执行命令即可,示例:
for cid in $(docker-compose ps -q spark-worker); do echo "===== 容器 $cid 执行结果 =====" docker exec $cid ls done
将命令中的ls替换为你需要执行的任意命令即可,该方法兼容1.29.2版本docker-compose。
2. 指定单个副本执行
如果不需要全量广播,仅需要在指定序号的副本上执行命令,可以添加--index参数指定副本序号(序号从1开始),例如在第2个spark-worker副本执行ls:
docker-compose exec --index=2 spark-worker ls
3. 封装复用函数
如果需要频繁对多副本服务广播命令,可以将批量执行逻辑封装为shell函数,添加到~/.bashrc(bash用户)或~/.zshrc(zsh用户)配置文件中:
dexec_all() { local service=$1 shift for cid in $(docker-compose ps -q $service); do echo "===== 服务 $service 容器 $cid 输出 =====" docker exec $cid "$@" echo -e "\n" done }
保存后执行source ~/.bashrc(或对应配置文件)生效,后续调用方式如下:
# 格式:dexec_all <服务名> <执行命令> dexec_all spark-worker ls
内容的提问来源于stack exchange,提问作者Tahir Mustafa
相关产品推荐
相关产品推荐

