通过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

相关推荐
对象存储与RustFS13 小时前
网盘限速逼你开会员?用 RustFS 自己搭一个不限速的“私人网盘
服务器·后端·docker
程序员老赵16 小时前
Docker 部署 Filestash:轻松搭建浏览器文件管理平台
前端·docker·开源
艾伦_耶格宇16 小时前
【DOCKER容器实战】-5 Docker容器镜像的构建
运维·docker·容器
imDwAaY17 小时前
操作系统如何管理程序运行?从线程、进程到内存隔离与用户态切换:CS162 Note2
android·java·redis
码途行者18 小时前
处理超时未支付订单:两套轻量化方案,附 PHP 极简实现
开发语言·redis·php
程序员小孔.19 小时前
基于 SpringBoot + UniApp + Vue 的家政服务系统设计与实现
前端·数据库·spring boot·python·docker·微信小程序
草莓熊Lotso1 天前
【C++ 基于微服务的即时通讯系统】etcd + brpc 从安装到服务注册发现全链路实战
网络·数据库·c++·redis·微服务·etcd
我不会起名字3221 天前
Redis 突然只能读不能写:MISCONF 报错的 3 类触发条件与 4 步恢复
运维·redis·持久化·排查·misconf
我不会起名字3221 天前
Redis 从 0 到 1(九):主库宕机 30 秒自动切主——1 主 2 从 3 哨兵 + Go 客户端
redis·docker·sentinel·高可用·哨兵
姜鱼问生1 天前
每次开机手动检查 6 样东西?我写了个 2 秒自检脚本
运维·网络·nginx·docker·容器