docker swarm快速部署redis分布式集群( 二 )


部署在swarm集群的Manager节点中创建
mkdir /root/redis-swarmcd /root/redis-swarmvi docker-compose.ymldocker compose.yml说明:

  1. 前6个服务为redis节点 , 最后一个redis-start是用于创建集群 , 利用redis-cli客户端搭建集群 , 该服务搭建完redis集群后会自动停止运行 。
  2. redis-start需要等待前6个redis节点的执行完毕才能创建集群 , 因此需要用到脚本wait-for-it.sh
  3. 由于redis-cli --cluster create不支持网络别名 , 所以另写脚本redis-start.sh
使用这套脚本同样可以单机部署集群 , 只需要在启动时不使用swarm启动就可以了 , 然后把docker-compose.yml中的网络模式driver: overlay给注释掉即可
version: '3.7'services:redis-node1:image: redishostname: redis-node1ports:- 6379:6379networks:- redis-swarmvolumes:- "node1:/data"command: redis-server --cluster-enabled yes --cluster-config-file nodes-node-1.confdeploy:mode: replicatedreplicas: 1resources:limits:# cpus: '0.001'memory: 5120Mreservations:# cpus: '0.001'memory: 512Mplacement:constraints:- node.role==managerredis-node2:image: redishostname: redis-node2ports:- 6380:6379networks:- redis-swarmvolumes:- "node2:/data"command: redis-server --cluster-enabled yes --cluster-config-file nodes-node-2.confdeploy:mode: replicatedreplicas: 1resources:limits:# cpus: '0.001'memory: 5120Mreservations:# cpus: '0.001'memory: 512Mplacement:constraints:- node.role==managerredis-node3:image: redishostname: redis-node3ports:- 6381:6379networks:- redis-swarmvolumes:- "node3:/data"command: redis-server --cluster-enabled yes --cluster-config-file nodes-node-3.confdeploy:mode: replicatedresources:limits:# cpus: '0.001'memory: 5120Mreservations:# cpus: '0.001'memory: 512Mreplicas: 1placement:constraints:- node.role==managerredis-node4:image: redishostname: redis-node4ports:- 6382:6379networks:- redis-swarmvolumes:- "node4:/data"command: redis-server --cluster-enabled yes --cluster-config-file nodes-node-4.confdeploy:mode: replicatedreplicas: 1resources:limits:# cpus: '0.001'memory: 5120Mreservations:# cpus: '0.001'memory: 512Mplacement:constraints:- node.labels.redis2==trueredis-node5:image: redishostname: redis-node5ports:- 6383:6379networks:- redis-swarmvolumes:- "node5:/data"command: redis-server --cluster-enabled yes --cluster-config-file nodes-node-5.confdeploy:mode: replicatedreplicas: 1resources:limits:# cpus: '0.001'memory: 5120Mreservations:# cpus: '0.001'memory: 512Mplacement:constraints:- node.labels.redis3==trueredis-node6:image: redishostname: redis-node6ports:- 6384:6379networks:- redis-swarmvolumes:- "node6:/data"command: redis-server --cluster-enabled yes --cluster-config-file nodes-node-6.confdeploy:mode: replicatedreplicas: 1resources:limits:# cpus: '0.001'memory: 5120Mreservations:# cpus: '0.001'memory: 512Mplacement:constraints:- node.labels.redis4==trueredis-start:image: redishostname: redis-startnetworks:- redis-swarmvolumes:- "$PWD/start:/redis-start"depends_on:- redis-node1- redis-node2- redis-node3- redis-node4- redis-node5- redis-node6command: /bin/bash -c "chmod 777 /redis-start/redis-start.sh && chmod 777 /redis-start/wait-for-it.sh && /redis-start/redis-start.sh"deploy:restart_policy:condition: on-failuredelay: 5smax_attempts: 5placement:constraints:- node.role==managernetworks:redis-swarm:driver: overlayvolumes:node1:node2:node3:node4:node5:node6:wait-for-it.shmkdir /root/redis-swarm/startvi wait-for-it.shvi redis-start.sh#!/usr/bin/env bash#Use this script to test if a given TCP host/port are availablecmdname=$(basename $0)echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }usage(){cat << USAGE >&2Usage:$cmdname host:port [-s] [-t timeout] [-- command args]-h HOST | --host=HOSTHost or IP under test-p PORT | --port=PORTTCP port under testAlternatively, you specify the host and port as host:port-s | --strictOnly execute subcommand if the test succeeds-q | --quietDon't output any status messages-t TIMEOUT | --timeout=TIMEOUTTimeout in seconds, zero for no timeout-- COMMAND ARGSExecute command with args after the test finishesUSAGEexit 1}wait_for(){if [[ $TIMEOUT -gt 0 ]]; thenechoerr "$cmdname: waiting $TIMEOUT seconds for $HOST:$PORT"elseechoerr "$cmdname: waiting for $HOST:$PORT without a timeout"fistart_ts=$(date +%s)while :do(echo > /dev/tcp/$HOST/$PORT) >/dev/null 2>&1result=$?if [[ $result -eq 0 ]]; thenend_ts=$(date +%s)echoerr "$cmdname: $HOST:$PORT is available after $((end_ts - start_ts)) seconds"breakfisleep 1donereturn $result}wait_for_wrapper(){# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692if [[ $QUIET -eq 1 ]]; thentimeout $TIMEOUT $0 --quiet --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &elsetimeout $TIMEOUT $0 --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &fiPID=$!trap "kill -INT -$PID" INTwait $PIDRESULT=$?if [[ $RESULT -ne 0 ]]; thenechoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $HOST:$PORT"fireturn $RESULT}# process argumentswhile [[ $# -gt 0 ]]docase "$1" in*:* )hostport=(${1//:/ })HOST=${hostport[0]}PORT=${hostport[1]}shift 1;;--child)CHILD=1shift 1;;-q | --quiet)QUIET=1shift 1;;-s | --strict)STRICT=1shift 1;;-h)HOST="$2"if [[ $HOST == "" ]]; then break; fishift 2;;--host=*)HOST="${1#*=}"shift 1;;-p)PORT="$2"if [[ $PORT == "" ]]; then break; fishift 2;;--port=*)PORT="${1#*=}"shift 1;;-t)TIMEOUT="$2"if [[ $TIMEOUT == "" ]]; then break; fishift 2;;--timeout=*)TIMEOUT="${1#*=}"shift 1;;--)shiftCLI="$@"break;;--help)usage;;*)echoerr "Unknown argument: $1"usage;;esacdoneif [[ "$HOST" == "" || "$PORT" == "" ]]; thenechoerr "Error: you need to provide a host and port to test."usagefiTIMEOUT=${TIMEOUT:-15}STRICT=${STRICT:-0}CHILD=${CHILD:-0}QUIET=${QUIET:-0}if [[ $CHILD -gt 0 ]]; thenwait_forRESULT=$?exit $RESULTelseif [[ $TIMEOUT -gt 0 ]]; thenwait_for_wrapperRESULT=$?elsewait_forRESULT=$?fifiif [[ $CLI != "" ]]; thenif [[ $RESULT -ne 0 && $STRICT -eq 1 ]]; thenechoerr "$cmdname: strict mode, refusing to execute subprocess"exit $RESULTfiexec $CLIelseexit $RESULTfi

经验总结扩展阅读