通过ansible+docker-compose快速安装一主两从redis+三sentinel

目录

示例主机列表

架构参考

文件内容

安装脚本

ansible变量,需修改

ansible配置文件和主机清单,需修改

运行方式

验证故障转移master

涉及redis镜像和完整的脚本文件

示例主机列表

架构参考

文件内容

安装脚本

复制代码
#!/bin/bash

set -e
export path=`pwd`
export capath="/opt/.certs"
export docker_data=$(awk -F': ' '/docker_data_dir:/ {print $2}' group_vars/all.yml)
export ansible_log_dir="$path/log"
ssh_pass="sulibao"

os_arch=$(uname -m)

if [[ "$os_arch" == "x86_64" ]]; then
    ARCH="x86"
    echo -e "Detected Operating System: $OS, Architecture:X86"
    mkdir -p $ansible_log_dir
elif [[ "$os_arch" == "aarch64" ]]; then
    ARCH="arm64"
    echo -e "Detected Operating System: $OS, Architecture: ARM64"
    mkdir -p $ansible_log_dir
else
    echo -e "Unsupported architecture detected: $os_arch"
    exit 1
fi

function check_arch() {
  if [ -f /etc/redhat-release ]; then
    OS="RedHat"
  elif [ -f /etc/kylin-release ]; then
    OS="kylin"
  else
    echo "Unknow linux distribution."
  fi
  OS_ARCH=$(uname -a)
  if [[ "$OS_ARCH" =~ "x86" ]]
  then
    ARCH="x86"
    echo -e  "The operating system is $OS,the architecture is X86."
  elif [[ "$OS_ARCH" =~ "aarch" ]]
  then
    ARCH="arm64"
    echo -e  "The operating system is $OS,the architecture is Arm."
  fi
}

function check_docker() {
  echo "Make sure docker is installed and running."
  if ! [ -x "$(command -v docker)" ]; then
    echo "docker not find."
    create_docker_group_and_user
    install_docker
  else
    echo "docker exists."
  fi
  if ! systemctl is-active --quiet docker; then
    echo "docker is not running."
    create_docker_group_and_user
    install_docker
  else
    echo "docker is running."
  fi
}

function check_docker_compose() {
  if ! [ -x "$(command -v docker-compose)" ]; then
    echo "docker-compose not find."
    install_docker_compose   
  else
    echo "docker-compose exist."
  fi
}

function create_docker_group_and_user() {
  if ! getent group docker >/dev/null 2>&1; then
    groupadd docker
    echo "docker group created successfully."
  else
    echo "docker group already exists."
  fi
  if ! id -u docker >/dev/null 2>&1; then
    useradd -m -s /bin/bash -g docker docker
    echo "docker user has been created and added to docker group."
  else
    echo "docker user already exists."
  fi
}

function install_docker() {
  echo "Installing docker."
  if [[ "$ARCH" == "x86" ]]
  then
    export DOCKER_OFFLINE_PACKAGE=$path/packages/docker/x86/docker-27.2.0.tgz
  else
    export DOCKER_OFFLINE_PACKAGE=$path/packages/docker/arm64/docker-27.2.0.tgz
  fi
  tar axvf $DOCKER_OFFLINE_PACKAGE -C /usr/bin/ --strip-components=1
  cp -v -f $path/packages/docker/docker.service /usr/lib/systemd/system/
  test -d /etc/docker || mkdir -p /etc/docker
  envsubst '$docker_data' < $path/packages/docker/daemon.json > /etc/docker/daemon.json
  systemctl stop firewalld
  systemctl disable firewalld
  systemctl daemon-reload
  systemctl enable docker.service --now
  systemctl restart docker || :
  maxSecond=60
  for i in $(seq 1 $maxSecond); do
    if systemctl is-active --quiet docker; then
      break
    fi
    sleep 1
  done
  if ((i == maxSecond)); then
    echo "Failed to start the docker server, please check the docker start log."
    exit 1
  fi
  echo "Docker has started successfully and the installation is complete."
}

function install_docker_compose {
  echo "Installing docker-compose."
  if [[ "$ARCH" == "x86" ]]
  then
    export DOCKER_COMPOSE_OFFLINE_PACKAGE=$path/packages/docker-compose/x86/docker-compose-linux-x86_64
    cp -v -f $DOCKER_COMPOSE_OFFLINE_PACKAGE /usr/local/bin/docker-compose
  else
    export DOCKER_COMPOSE_OFFLINE_PACKAGE=$path/packages/docker-compose/arm64/docker-compose-linux-aarch64
    cp -v -f $DOCKER_COMPOSE_OFFLINE_PACKAGE /usr/local/bin/docker-compose
  fi
}

function load_ansible_image() {
  if [[ "$ARCH" == "x86" ]]
  then
    docker load -i $path/packages/ansible/x86/ansible_images.tgz
  else
    docker load -i $path/packages/ansible/arm64/ansible_images.tgz
  fi
  echo -e "Loaded ansible image."
}

function ensure_ansible() {
  echo -e "Checking the status of the ansible."
  if test -z "$(docker ps -a | grep ansible_sulibao)"; then
    echo -e "Ansible is not running, will run."
    run_ansible
  else
    echo -e "Ansible is running, will restart."
    docker restart ansible_sulibao
  fi
}

function run_ansible() {
  echo -e "Installing Ansible container."
  if [[ "$ARCH" == "x86" ]]
  then
    docker run --name ansible_sulibao --network="host" --workdir=$path -d -e LANG=C.UTF-8 -e ssh_password=$ssh_pass --restart=always -v /etc/localtime:/etc/localtime:ro -v ~/.ssh:/root/.ssh -v $path:$path -v "$capath":"$capath" ansible:latest sleep 31536000
  else
    docker run --name ansible_sulibao --network="host" --workdir=$path -d -e LANG=C.UTF-8 -e ssh_password=$ssh_pass --restart=always -v /etc/localtime:/etc/localtime:ro -v ~/.ssh:/root/.ssh -v $path:$path -v "$capath":"$capath" ansible-arm:latest sleep 31536000
  fi
  echo -e "Installed Ansible container."
}

function  create_ssh_key(){
  echo -e "Creating sshkey."
  docker exec -i ansible_sulibao /bin/sh -c 'echo -e "y\n"|ssh-keygen -t rsa -N "" -C "deploy@redis_sentinel" -f ~/.ssh/id_rsa_ansible_redis -q'  echo -e "\nCreated sshkey."

}

function copy_ssh_key() {
  echo -e "Copying sshkey."
  docker exec -i ansible_sulibao /bin/sh -c "cd $path && ansible-playbook  ssh-access.yml -e ansible_ssh_pass=$ssh_pass"  
  echo -e "\nCopied sshkey."
}

function install_docker_slave() {
  echo -e "Installing docker for slave nodes."
  docker exec -i ansible_sulibao /bin/sh -c "cd $path && ansible-playbook  ./docker.yml"
  echo -e "\nInstalled docker for slave nodes."
}

function install_redis() {
  echo -e "Install redis."
  docker exec -i ansible_sulibao /bin/sh -c "cd $path && ansible-playbook  ./redis.yml"
  echo -e "\nInstalled redis."
}

check_arch
check_docker
check_docker_compose
load_ansible_image
ensure_ansible
create_ssh_key
copy_ssh_key
install_docker_slave
install_redis

ansible变量,需修改

复制代码
vim group_vars/all.yml

docker_data_dir: /app/docker_data   #安装的docker数据目录
data_dir: /app     #存放redis文件的数据目录
redis_sentinel_port: 26379    #sentinel端口
redis_pass: "sulibao"     #redis认证密码
image_redis: "registry.cn-chengdu.aliyuncs.com/su03/redis:7.2.7"   #redis和sentinel使用的镜像

ansible配置文件和主机清单,需修改

复制代码
[root@test1 redis_data]# cat ansible.cfg 
[defaults]
inventory=./hosts
remote_user = root
transport= ssh
remote_port = 22
private_key_file= /root/.ssh/id_rsa_ansible_redis
log_path = ./log/ansible.log
stdout_callback=debug
host_key_checking=false
command_warnings=False
fact_caching_connections=/tmp/ansible_facts
fact_caching_timeout=86400
gathering=smart
pipelining=True
deprecation_warnings = False

[ssh_connection]
ssh_args=-o ControlMaster=auto -o ControlPersist=60s
[root@test1 redis_data]# cat hosts 
[redis_master]    #初始master的地址
192.168.2.190
[redis_slave1]    #初始slave1的地址
192.168.2.191 
[redis_slave2]    #初始slave2的地址
192.168.2.192

[redis_slave:children]
redis_slave1
redis_slave2

[redis:children]
redis_master
redis_slave1
redis_slave2

运行方式

复制代码
bash setup.sh

验证故障转移master

复制代码
#初始集群信息,test1为master,test2、test3为slave
docker exec -it redis-master bash
root@test1:/data# redis-cli -a sulibao role
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
1) "master"
2) (integer) 35726
3) 1) 1) "192.168.2.191"
      2) "6379"
      3) "35726"
   2) 1) "192.168.2.192"
      2) "6379"
      3) "35585"
 
 
#模拟master(test1)挂机,出现新master(test2),test3仍为slave
[root@test1 redis_data]# docker stop redis-master
redis-master
[root@test2 ~]# docker exec -it redis-slave1 bash
root@test2:/data# redis-cli -a sulibao role
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
1) "master"
2) (integer) 68953
3) 1) 1) "192.168.2.192"
      2) "6379"
      3) "68953"
 
#旧master(test1)恢复,成为slave角色。此时master为test2,test1、test3为slave
[root@test1 redis_data]# docker start redis-master
redis-master
root@test2:/data# redis-cli -a sulibao role
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
1) "master"
2) (integer) 87291
3) 1) 1) "192.168.2.192"
      2) "6379"
      3) "87291"
   2) 1) "192.168.2.190"
      2) "6379"
      3) "87291"

涉及redis镜像和完整的脚本文件

脚本文件:通过网盘分享的文件:redis_data.tgz

链接: https://pan.baidu.com/s/12Hd22VSxdduktkyr7Lhijg?pwd=abvn 提取码: abvn

镜像文件:通过网盘分享的文件:redis-727-x86.tgz

链接: https://pan.baidu.com/s/1D4xQkrSU4opm-9RVhk6Gmg?pwd=aiw3 提取码: aiw3

相关推荐
cpsvps_net13 分钟前
多主机Docker Swarm集群网络拓扑可视化监控方案的部署规范
运维·docker·容器
东窗西篱梦13 分钟前
Ansible自动化运维:从入门到实战,告别重复劳动!
运维·自动化·ansible
Vahala0623-孔勇17 分钟前
分布式锁巅峰对决:Redis RedLock vs ZooKeeper临时节点——Redission看门狗如何破解续期困局
redis·分布式·zookeeper
gsfl1 小时前
Redis List 类型全解析
数据库·redis·list
宸津-代码粉碎机2 小时前
Redis 进阶:跳出缓存局限!7 大核心场景的原理与工程化实践
java·人工智能·redis·python
ccccczy_2 小时前
Java微服务容器化与 Kubernetes 编排实战:从 Docker 多阶段构建到云原生弹性扩展
java·docker·kubernetes·springboot·microservices·cloudnative·containerization
邂逅星河浪漫7 小时前
【Docker + DockerCompose】安装步骤+演示
docker·容器·docker-compose
智能化咨询8 小时前
开源的容器化平台:Docker高级应用与实战案例
docker
我是苏苏9 小时前
Redis开发07:使用stackexchange.redis库实现简单消息队列
数据库·redis·缓存
Mr.wangh11 小时前
Redis主从复制
java·数据库·redis