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

相关推荐
程序员老赵19 小时前
Docker 部署 Redmine:老牌开源项目管理部署实测记录
docker·开源·团队管理
程序员老赵21 小时前
服务器文件不想 SFTP 上传?Docker 跑个 File Browser,浏览器就能管理
服务器·docker·开源
vivo互联网技术1 天前
从 10 分钟到 1 秒:ES 深度分页任意跳页的三轮优化实战
服务器·数据库·redis·elasticsearch·深度分页
lichenyang4533 天前
Docker 学习笔记(五):Docker Compose,用一个 YAML 启动前端、后端和 MongoDB
docker
lichenyang4533 天前
Docker 学习笔记(四):Dockerfile,把项目打成自己的镜像
docker·容器
lichenyang4533 天前
Docker 学习笔记(三):Docker 网络、bridge、子网和容器互通
docker·容器
lichenyang4533 天前
Docker 学习笔记(二):docker run 的参数到底在控制什么?
docker·容器
用户3074596982074 天前
Redis 延时队列详解
redis
烤代码的吐司君4 天前
Redis 数据结构 ZSet, BIT, HyperLogLog,Geo 空间数据
redis·后端