SaltStack實例:Keepalived+Redis高可用架構

    Keepalived+Redis是一種比較成熟的Redis高可用解決方案,經過keepalived實現虛擬ip(vip)的切換以及Reids進程監控,並控制Redis的主從同步狀態。如下是架構圖:node

image.png

環境介紹:web

Saltstack-master: 192.168.39.185
redis

Master:192.168.39.100vim

Slave:192.168.39.101centos

VIP:192.168.39.23bash

高可用狀態狀況:架構

1)當Master端與Slave端都運行正常時,Master負責服務,Slave做爲備用。app

2)當Master端運行不正常時,slave接管服務,同時關閉主從複製功能。less

3)當Master端恢復正常時,則從slave同步數據,做爲Slave的從,不切換成主。運維

4)當slave端掛掉,master端恢復成主。

如下經過saltstack完成keepalived+redis的高可用架構部署:

首先,修改master配置文件指定top file文件路徑:

[root@centos7 ~]# vim /etc/salt/master
file_roots:
  base:
    - /srv/salt

修改salt配置文件須要重啓服務。

整個狀態文件目錄結構以下:

image.png

設置主從模式的Grains(Grains爲模版文件設置變量,一般也能夠用Pillar設置):

設置master端和slave端的Grains,指定role、vip和redis的master_ip:

[root@centos7 ~]# salt "centos7-1" grains.setvals "{'role':'master','vip':'192.168.39.23','master_ip':'192.168.39.101'}"
[root@centos7 ~]# salt "centos7-2" grains.setvals "{'role':'slave','vip':'192.168.39.23','master_ip':'192.168.39.100'}"

能夠查看到Grains已經設置成功:

image.png

設置入口文件top.sls:

以list匹配方式對兩臺主機應用對應模塊:

[root@centos7 salt]# cat top.sls 
base:
  'centos7-1,centos7-2':
    - match: list
    - redis
    - keepalived

1、部署Redis

安裝redis並根據角色下發配置模版文件。

Redis安裝入口文件:

[root@centos7 redis]# cat init.sls 
include:
  - .install_redis
  - .redis_running
  - .redis_conf

Redis安裝:

[root@centos7 redis]# cat install_redis.sls 
{% for s in ["jemalloc-3.6.0-1.el7.x86_64.rpm","redis-3.2.12-1.el7.x86_64.rpm",] %}
copy_{{ s }}:
  file.managed:
    - name: /usr/local/src/{{ s }}
    - source: salt://redis/file/{{ s }}
    - user: root
    - group: root
    - template: jinja
    - mode: 755
{% endfor %}
install_redis:
  cmd.run:
    - name: cd /usr/local/src/ && yum install -y redis-3.2.12-1.el7.x86_64.rpm jemalloc-3.6.0-1.el7.x86_64.rpm
    - require:
      - file: copy_redis-3.2.12-1.el7.x86_64.rpm

這裏經過require指定依賴關係,將rpm都下發到節點下以後,進行安裝redis。

Redis配置洗髮以及建立目錄:

[root@centos7 redis]# cat redis_conf.sls 
redis_conf:
  file.managed:
    - name: /etc/redis.conf
    - source: salt://redis/templates/redis.j2
    - user: root
    - group: root
    - template: jinja
    - mode: 644
    - require:
      - cmd: install_redis
redis_dir:
  cmd.run:
    - name: mkdir -pv /data/redis && chown redis.redis /data/redis
    - unless: test -d /data/redis

unless指定經過test命令判斷目錄是否存在,若是不存在則執行name。

Redis服務啓動控制:

[root@centos7 redis]# cat redis_running.sls 
redis_running:
  service.running:
    - name: redis
    - enable: True
    - require:
      - cmd: install_redis
    - watch:
      - file: redis_conf

經過watch狀態監控,若是就重啓服務。

Redis配置文件模版:

[root@centos7 templates]# grep -v "#" redis.j2 
bind 0.0.0.0
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis/redis.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data/redis/
{% if grains['role'] == "slave" %}
slaveof {{grains['master_ip']}} 6379
{% endif %}
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes

2、部署keepalived

keepalived入口文件:

[root@centos7 keepalived]# cat init.sls 
include:
  - .install_keepalived
  - .keepalived_running
  - .keepalived_conf

keepalived安裝文件:

[root@centos7 keepalived]# cat install_keepalived.sls 
install_keepalived:
  pkg.installed:
    - name: keepalived

pkg指定經過yum源進行安裝。

keepalived配置下發以及建立目錄:

[root@centos7 keepalived]# cat keepalived_conf.sls 
keepalived_conf:
  file.managed:
    - name: /etc/keepalived/keepalived.conf
    - source: salt://keepalived/templates/keepalived.conf
    - user: root
    - group: root
    - template: jinja
    - mode: 644
    - require:
      - pkg: install_keepalived
      - cmd: scripts_dir
scripts_dir:
  cmd.run:
    - name: mkdir -pv /etc/keepalived/scripts/
    - unless: test -d /etc/keepalived/scripts/
  
{% for s in ["redis_backup.sh","redis_check.sh","redis_fault.sh","redis_master.sh","redis_stop.sh"] %}
keepalived_{{s}}:
  file.managed:
    - name: /etc/keepalived/scripts/{{s}}
    - source: salt://keepalived/templates/scripts/{{s}}
    - user: root
    - group: root
    - template: jinja
    - mode: 755
    - require:
      - pkg: install_keepalived
{% endfor %}

keepalived服務啓動文件:

[root@centos7 keepalived]# cat keepalived_running.sls 
keepalived_running:
  service.running:
    - name: keepalived
    - enable: True
    - require:
      - pkg: install_keepalived
    - watch:
      - file: keepalived_conf

keepalived模板文件和腳本文件:

keepalived.conf主配置文件根據role值動態下發配置文件:

[root@centos7 templates]# cat keepalived.conf 
! Configuration File for keepalived

vrrp_script chk_redis {
    script "/etc/keepalived/scripts/redis_check.sh"
    interval 2
}

vrrp_instance VI_1 {
{% if grains['role'] == 'master' %}
    state MASTER
{% else %}
    state BACKUP
{% endif %}
    interface eth0
    virtual_router_id 51
{% if grains['role'] == "master" %}
    priority 101
{% else %}
    priority 100
{% endif %}
#    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass redis
    }
    track_script {
        chk_redis
    }
    virtual_ipaddress {
        {{ grains['vip'] }}
    }
    notify_master /etc/keepalived/scripts/redis_master.sh
    notify_backup /etc/keepalived/scripts/redis_backup.sh
    notify_fault /etc/keepalived/scripts/redis_fault.sh
    notify_stop /etc/keepalived/scripts/redis_stop.sh
}

keepalived配置的幾個腳本,當keeplaived在轉換狀態時會按照狀態來呼叫:

當進入master狀態時會呼叫notify_master;

當進入backup狀態時會呼叫notify_backup;

當發現異常狀況時進入fault狀態呼叫notify_fault;

當keepalived程序終止時則呼叫notify_stop。

redis_backup.sh-Redis健康檢測腳本:

[root@centos7 scripts]# cat redis_check.sh 
#!/bin/bash
#
ALIVE=`/usr/bin/redis-cli PING`
if [ "$ALIVE" == "PONG" ];then
    echo $ALIVE 
    exit 0
else
    echo $ALIVE
    exit 1
fi

redis_master.sh-切換master觸發執行腳本:

[root@centos7 scripts]# cat redis_master.sh 
#!/bin/bash
#
REDISCLI="/usr/bin/redis-cli"
LOGFILE="/var/log/keepalived-redis-state.log"
echo "[master]" >> $LOGFILE
date >> $LOGFILE
echo "Being master..." >> $LOGFILE 2>&1
echo "run slaveof no one cmd..." >> $LOGFILE
$RESISCLI SLAVEOF {{ grains['master_ip']  }} 6479>> $LOGFILE 2>&1
$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1

redis_backup.sh-切換成backup角色執行腳本:

[root@centos7 scripts]# cat redis_backup.sh 
#!/bin/bash
#
REDISCLI="/usr/bin/redis-cli"
LOGFILE="/var/log/keepalived-redis-state.log"
echo "[backup]" >> $LOGFILE
date >> $LOGFILE
echo "being salve..." >> $LOGFILE 2>&1
#sleep 25
echo "run slaveof cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF {{ grains['master_ip'] }} 6379 $LOGFILE 2>&1

redis_fault.sh-進入fault狀態執行腳本:

[root@centos7 scripts]# cat redis_fault.sh 
#!/bin/bash
#
$LOGFILE=/var/log/keepalived-redis-state.log
echo "[fault]" >> $LOGFILE
date >> $LOGFILE

redis_stop.sh-當keepalived服務終止時執行此腳本:

[root@centos7 scripts]# cat redis_stop.sh 
#!/bin/bash
#
LOGFILE=/var/log/keepalived-redis-state.log
echo "[stop]" >> $LOGFILE
date >> $LOGFILE

全部狀態配置文件和腳本設置完成執行:

在執行時咱們能夠經過指定參數,模擬執行:

[root@centos7 salt]# salt 'centos7-[1-2]' state.highstate test=True

測試執行沒有其餘問題,執行安裝:

[root@centos7 salt]# salt 'centos7-[1-2]' state.highstate

執行結構以下:

image.png

會看到centos7-1節點,執行完成以後的狀態:

image.png

測試keepalived+redis高可用:

登錄centos7-1查看vip狀況:image.png

在saltstack服務端經過鏈接vip測試登錄狀況:

image.png

關閉centos7-1下的redis服務:

[root@centos7-1:/usr/local/src]
# service redis stop
Redirecting to /bin/systemctl stop  redis.service

[root@centos7-1:/usr/local/src]
# service redis status
Redirecting to /bin/systemctl status  redis.service
● redis.service - Redis persistent key-value database
   Loaded: loaded (/usr/lib/systemd/system/redis.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/redis.service.d
           └─limit.conf
   Active: inactive (dead) since Fri 2018-08-31 11:41:44 CST; 5s ago
  Process: 6414 ExecStop=/usr/libexec/redis-shutdown (code=exited, status=0/SUCCESS)
  Process: 6147 ExecStart=/usr/bin/redis-server /etc/redis.conf --supervised systemd (code=exited, status=0/SUCCESS)
 Main PID: 6147 (code=exited, status=0/SUCCESS)
Aug 31 11:40:17 centos7-1 systemd[1]: Starting Redis persistent key-value database...
Aug 31 11:40:17 centos7-1 systemd[1]: Started Redis persistent key-value database.
Aug 31 11:41:44 centos7-1 systemd[1]: Stopping Redis persistent key-value database...
Aug 31 11:41:44 centos7-1 systemd[1]: Stopped Redis persistent key-value database.

從新鏈接vip登錄redis查看設置name值:

image.png

登錄centos7-2下查看vip切換狀況:image.png


參考文獻:《saltstack運維實戰》

相關文章
相關標籤/搜索