目录
示例主机列表

架构参考

文件内容
安装脚本
#!/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