首页 > 系统相关 >docker-compose+nginx实现服务不中断更新

docker-compose+nginx实现服务不中断更新

时间:2024-05-06 20:26:16浏览次数:18  
标签:compose service replicas -- echo nginx docker port

思路是写一个脚本,docker-compose scale扩容,然后重写nginx配置文件,刷新负载均衡

nginx重写的配置文件,文件名service,里面只有upstream,例如:

upstream e-chatbot-server-dev {
 server 0.0.0.0:8080;
 server 0.0.0.0:8081;
}

脚本使用方法:

./rollupdate.sh --service=test-server --port=8080
需要注意的是docker-compose.yaml的服务test-server端口范围要比实例数多一个,yaml示例如下:
version: '3'
services:
  test-server:
    image: e-chatbot-server:dev
    restart: always
    networks:
      - dev
    ports:
      - "8080-8082:8080"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
    deploy:
      resources:
        limits:
          cpus: 2
          memory: 1g
      replicas: 2
      update_config:
        parallelism: 1
        delay: 10s
      restart_policy:
        condition: on-failure
networks:
  dev:
    external: true
    driver: bridge

rollupdate.sh脚本如下:
service=
port=
# 循环处理所有命令行参数
for arg in "$@"
do
    case $arg in
        --service=*) # 如果参数以--service=开头
            service="${arg#*=}" # 截取等号后的部分作为服务名称
            ;;
        --port=*) # 如果参数以--port=开头
            port="${arg#*=}" # 截取等号后的部分作为端口号
            ;;
        *) # 如果参数不是以--service=或--port=开头,则跳过
            ;;
    esac
done

if [ -z "$service" ]; then
  echo "--service=?"
fi
if [ -z "$port" ]; then
  echo "--port=?"
fi
if [ -z "$service" ] || [ -z "$port" ]; then
  exit 1
fi

docker-compose port $service $port > /etc/null
if [ "$?" != "0" ]; then
  exit 1
fi
old_names=$(docker-compose ps --format "{{.Names}}" | grep $service)
replicas=$(docker-compose config $service --format="json" | jq ".services.\"$service\".deploy.replicas // 1")
if [ -z "$replicas" ]; then
  echo "未获取到副本数量"
  exit 1
fi
echo "old replicas: $replicas"
let replicas=replicas+1
echo "update replicas: $replicas"
old_names=$(docker-compose ps --format "{{.Names}}" | grep $service)
echo -e "服务$service,老的实例:\n $old_names"
for container_name in $old_names; do
    # 在这里可以添加其他针对每个容器名称的操作
    echo "服务:$service设置副本为$replicas,正在添加一个副本"
    docker-compose scale "$service=$replicas"
    if [ "$?" != "0" ]; then
       exit
    fi
    echo -n "等待新增副本就绪..."
    for i in {1..100}; do
      #服务需要监控检查
      start_count=$(docker-compose ps $service | grep "health: starting" | wc -l)
      if [ $start_count -eq 0 ]; then
        break
      fi
      echo -n "."
      sleep 5
    done
    echo ""
    if [ $start_count -gt 0 ]; then
        echo "超过最大等待时间"
        exit 1
    fi
    new_names=$(docker-compose ps --format "{{.Names}}" | grep $service)
    nx_conf="upstream $service {\n"
    for new_name in $new_names; do
      if [ "$new_name" != "$container_name" ]; then
        hport=$(docker port $new_name $port | head -n 1)
        nx_conf+="  server $hport;\n"
      fi
    done
    nx_conf+="}"
    echo "从nginx负载均衡移除实例$container_name"
    echo -e $nx_conf > /etc/nginx/conf.d/$service.conf
    nginx -s reload
    echo "docker stop $container_name"
    docker stop $container_name
done

 

标签:compose,service,replicas,--,echo,nginx,docker,port
From: https://www.cnblogs.com/zhouquan-1992-04-06/p/18175791

相关文章

  • docker pytorch离线安装
    先在ubuntu18.0464位环境里,有联网情况下操作:安装dockerpytorch镜像:dockerpullpytorch/pytorch:1.13.0-cuda11.6-cudnn8-runtime下载依赖:bonelee@ubuntu:~/Desktop/pythonProject$sudodockerps-aCONTAINERIDIMAGE......
  • Docker-DevOps-入门手册(全)
    DockerDevOps入门手册(全)原文:zh.annas-archive.org/md5/A074DB026A63DFD63D361454222593A5译者:飞龙协议:CCBY-NC-SA4.0前言Docker与DevOps概述了容器化的强大力量以及这种创新对开发团队和一般运营的影响。我们还将了解DevOps的真正含义,涉及的原则,以及通过实施Dock......
  • Docker安装mysql
    dockerpullmysql:5.7:从DockerHub上拉取MySQL5.7的镜像。dockerimages:列出所有已下载的镜像,确认MySQL5.7是否已经成功下载。mkdir-p/home/service/mysql/data:创建一个用于存放MySQL数据的目录。mkdir-p/home/service/mysql/conf:创建一个用于存放MySQL配置文件的目录......
  • 记录一下docker踩坑 /dev/shm目录
    /dev/shm是Linux系统中的一个特殊目录,用于作为临时文件存储的一种形式,它将数据存储在RAM(随机存取存储器)中,而不是在磁盘上。这意味着在/dev/shm中存储的数据访问速度非常快,但数据在系统重启后不会被保留。/dev/shm是POSIX共享内存(POSIXSharedMemory)的一部分,它允许不同的进程(程序......
  • docker安装
      uname-r查看系统版本号  yuminstall-yyum-utilsdevice-mapper-persistent-datalvm2   这个命令是用来在基于RPM的Linux发行版上安装一些必要的软件包。具体来说,它安装了以下软件包:yum-utils:这是一个命令行工具集合,提供了许多有用的功能,如清理缓存、......
  • 【转】在 Linux 里布署 Docker
    来自:百度Docker可以布署在Linux系统上,也可以布署在你自己的电脑上。在Linux系统上布署Docker:安装Docker:curl-fsSLhttps://get.docker.com-oget-docker.shsudoshget-docker.sh启动Docker服务:sudosystemctlstartdocker使Docker开机自启:sudosyste......
  • 入门学习Docker部署Vue+NetCore+MsSql
    最近vultr的主机经常忘了续租,导致账号被禁用,主机被删掉每次重新部署都忘了之前怎么弄的,要重新查好多资料每个月6美金的主机XShell连接主机IP先安装docker开启docker服务镜像容器tar文件 saveload dockerimagesdockercommitbuildDockerfilepull仓库 查看......
  • Dockerfile.oracle-注释学习
    innovation/Dockerfile.oracle##NOTE:THISDOCKERFILEISGENERATEDVIA"apply-templates.sh"##PLEASEDONOTEDITITDIRECTLY.##使用oraclelinux:8-slim基础镜像FROMoraclelinux:8-slim#set-eux也就是以调试的方式执行shell,只识别定义过的变量,同时脚......
  • 在Linux中,Docker和容器虚拟概念是什么?
    Docker是一种开源的容器化平台,它允许开发者将应用及其依赖打包到一个轻量级、可移植的容器中,然后在任何支持Docker的系统上运行。容器虚拟化是一种与完全虚拟化(如KVM或Xen)不同的虚拟化技术,它提供了操作系统级别的虚拟化。1.容器虚拟化概念容器是一种轻量级、可移植的软件单元......
  • docker 简单使用
    @目录一、docker安装二、docker使用1.dockerpull拉取镜像2.dockerrun后台运行3.dockerps查看容器运行状态4.dockerexec进入容器5.exit退出容器6.dockerrestar重启容器7.dockerstop停止运行容器8.dockerstop启动容器9.dockerstop删除容器10.dockerc......