(五)纵散、用 highstate 復合主機狀態(tài)

一、用top.sls文件管理拆分過的狀態(tài)控制文件

  1. 為了解決模塊的復用問題和使模塊結(jié)構(gòu)化人芽,現(xiàn)在以nginx安裝配置為例望几,把一個大的nginx.sls文件,拆分成盡可能小的可復用單元萤厅。


    目錄結(jié)構(gòu)
  2. 創(chuàng)建init文件來包含其他文件

# cat nginx/init.sls (點號一定不能去掉)
include:
    - .install_nginx
    - .running_nginx
    - .nginx_conf
    - .vhost_conf
  1. 創(chuàng)建nginx的各個子配置模塊
# cat nginx/install_nginx.sls (安裝nginx)
install_nginx:
    pkg.installed:
        - name: nginx

# cat nginx/running_nginx.sls(啟動nginx)
running_nginx:
    service.running:
        - name: nginx
        - enable: True
        - require:
            - pkg: install_nginx
        - watch:
            - file: nginx_conf
            - file: vhost_conf

# cat nginx/nginx_conf.sls (下發(fā) nginx.conf 配置文件)
nginx_conf:
    file.managed:
        - name: /etc/nginx/nginx.conf
        - source: salt://nginx/templates/nginx.j2
        - user: root
        - group: root
        - mode: 644
        - template: jinja

# cat nginx/vhost_conf.sls (下發(fā)虛擬主機配置文件)
vhost_conf:
    file.managed:
        - name: /etc/nginx/conf.d/default.conf
        - source: salt://nginx/templates/vhost.j2
        - user: root
        - group: root
        - mode: 644
        - template: jinja
  1. 創(chuàng)建top.sls文件(nginx文件夾下有init.sls文件橄抹,salt默認會加載init.sls文件靴迫,所以不需要寫成nginx.init這種形式)
    沒有top.sls文件時,可以執(zhí)行 salt node1 state.sls nginx
# cat top.sls 
base:
    'node1':
        - nginx
執(zhí)行結(jié)果

二楼誓、拆分lamp.sls文件為httpd玉锌、mysqld和php模塊

目錄結(jié)構(gòu)
  1. httpd 模塊
# cat init.sls # 入口文件
include:
    - .install_httpd
    - .running_httpd
    - .httpd_conf

# cat install_httpd.sls # httpd 軟件安裝
install_httpd:
    pkg.installed:
        - name: httpd

# cat running_httpd.sls # httpd 服務管理
running_httpd:
    service.running:
        - name: httpd
        - enable: True
        - require:
            - pkg: install_httpd
        - watch:
            - file: httpd_conf
            - file: php_conf

# cat httpd_conf.sls # httpd 配置文件管理
httpd_conf:
    file.managed:
        - name: /etc/httpd/conf/httpd.conf
        - source: salt://httpd/templates/httpd.j2
        - user: root
        - group: root
        - mode: 644
        - template: jinja
  1. mysqld 模塊
# cat init.sls  # 入口文件
include:
    - .install_mysqld
    - .running_mysqld
    - .mysqld_conf

# cat install_mysqld.sls  # mysqld 軟件安裝
install_mysqld:
    pkg.installed:
        - pkgs:
            - mysql-server
            - mysql-devel
            - mysql

# cat running_mysqld.sls  # mysqld 服務管理
running_mysqld:
    service.running:
        - name: mysqld
        - enable: True
        - require:
            - pkg: install_mysqld
        - watch:
            - file: mysqld_conf

# cat mysqld_conf.sls  # mysqld 配置文件管理
mysqld_conf:
    file.managed:
        - name: /etc/my.cnf
        - source: salt://mysqld/templates/my.j2
        - user: root
        - group: root
        - mode: 644
        - template: jinja
  1. php 模塊
# cat init.sls # 入口文件
include:
    - .install_php
    - .php_conf

$ cat install_php.sls # PHP 服務安裝
install_php:
    pkg.installed:
        - pkgs:
            - php
            - php-common
            - php-gd
            - php-mbstring
            - php-mcrypt
            - php-devel
            - php-xml
            - php-soap
        - require:
            - pkg: install_httpd

# cat php_conf.sls  # PHP 配置文件管理
php_conf:
    file.managed:
        - name: /etc/php.ini
        - source: salt://php/templates/php.ini
        - user: root
        - group: root
        - mode: 644
        - require:
            - pkg: install_php
  1. top.sls 文件內(nèi)容
# cat top.sls 
base:
    'node1':
        - httpd
        - php
        - mysqld
執(zhí)行結(jié)果

三、使用highstate實現(xiàn)keepalived + redis 的高可用

設計思路:

  • 主服務器redis掛掉疟羹,嘗試重啟主服務器的redis主守,重啟失敗的話關掉主服務器的keepalived,使VIP發(fā)生漂移
  • 從服務器變成主阁猜,使用腳本斷掉主從同步丸逸,改變redis角色為主
  • 主服務器正常時,使用腳本開啟redis主從同步剃袍,改變redis角色為從(VIP不發(fā)生漂移黄刚,只有當從服務器出問題的時候才發(fā)生VIP漂移,以此循環(huán)往復)
  1. 拓撲結(jié)構(gòu)
    主服務器:192.168.1.14(node1)
    從服務器:192.168.1.15(node2)
    VIP:192.168.1.100

  2. 編寫設置redis主從服務器的pillar數(shù)據(jù)

# node1的pillar數(shù)據(jù)
# cat /srv/pillar/minion_node1_key.sls 
role: redis_master
vip: '192.168.1.100'
master_ip: '192.168.1.15'

# node2的pillar數(shù)據(jù)
# cat /srv/pillar/minion_node2_key.sls
role: redis_slave
vip: '192.168.1.100'
master_ip: '192.168.1.14'

# cat /srv/pillar/top.sls 
base:
    'node1':
        - minion_node1_key
    'node2':
        - minion_node2_key

執(zhí)行 salt -L 'node1,node2' saltutil.refresh_pillar 刷新pillar數(shù)據(jù)

  1. 編寫redis模塊
# 入口文件
# cat /srv/salt/redis/init.sls 
include:
    - .install_redis
    - .running_redis
    - .redis_conf

# 安裝 redis
# cat /srv/salt/redis/install_redis.sls 
install_redis:
    pkg.installed:
        - name: redis

# 啟動redis
# cat /srv/salt/redis/running_redis.sls 
running_redis:
    service.running:
        - name: redis
        - enable: True
        - require:
            - pkg: install_redis
            - file: make_pidfile_dir
        - watch:
            - file: redis_conf

# 配置redis
# cat /srv/salt/redis/redis_conf.sls 
redis_conf:
    file.managed:
        - name: /etc/redis.conf
        - source: salt://redis/templates/redis.conf
        - user: root
        - group: root
        - mode: 644
        - template: jinja
        - require:
            - pkg: install_redis
# 創(chuàng)建 pid 文件目錄
make_pidfile_dir:
    file.directory:
        - name: /var/run/redis
        - user: root
        - group: root
        - dir_mode: 755
        - make_dirs: True

# /srv/salt/redis/templates/redis.conf
# $ egrep -v "^$|^#" templates/redis.conf
bind 0.0.0.0
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
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 /var/lib/redis
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
requirepass redis_pass
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

# 只有以下位置不同
{% if pillar['role'] == 'redis_slave' %}
slaveof {{ pillar['master_ip'] }} 6379
masterauth redis_pass
{% endif %}
  1. 編寫keepalived模塊
# 入口文件
# cat /srv/salt/keepalived/init.sls 
include:
    - .install_keepalived
    - .running_keepalived
    - .keepalived_conf
    - .keepalived_script

# 安裝keepalived
# cat /srv/salt/keepalived/install_keepalived.sls 
install_keepalived:
    pkg.installed:
        - name: keepalived

# 啟動keepalived
# cat /srv/salt/keepalived/running_keepalived.sls 
running_keepalived:
    service.running:
        - name: keepalived
        - enable: True
        - require:
            - pkg: install_keepalived
        - watch:
            - file: keepalived_conf

# 配置keepalived
# cat /srv/salt/keepalived/keepalived_conf.sls  
keepalived_conf:
    file.managed:
        - name: /etc/keepalived/keepalived.conf
        - source: salt://keepalived/templates/keepalived.conf
        - user: root
        - group: root
        - mode: 644
        - template: jinja

make_log_dir:
    file.directory:
        - name: /etc/keepalived/logs
        - user: root
        - group: root
        - mode: 755
        - makedirs: True

# keepalived使用的腳本文件
# cat /srv/salt/keepalived/keepalived_script.sls 
{% for file in ['notify_backup.sh','notify_master.sh','check_redis.sh'] %}
keepalived_{{ file }}:
    file.managed:
        - name: /etc/keepalived/{{ file }}
        - source: salt://keepalived/templates/{{ file }}
        - mode: 755
        - user: root
        - group: root
        - template: jinja
        - require:
            - pkg: install_keepalived
{% endfor %}

# 配置文件內(nèi)容keepalived.conf
# cat /srv/salt/keepalived/templates/keepalived.conf 
! Configuration File for keepalived
global_defs {
    router_id {{ grains['host'] }}
}
vrrp_script chk_redis {
    script "/etc/keepalived/check_redis.sh" # 監(jiān)測 redis 狀態(tài)的腳本
    interval 5
}

vrrp_instance VI_1 {
    state BACKUP # 主從服務器狀態(tài)都設置為BACKUP民效,依靠priority大小來決定誰是主誰是備(數(shù)值小的自動選舉為主)憔维,
                 # 不這樣設置的主服務器出問題后再正常的話會搶占備服務器的VIP
    {% if pillar['role'] == 'redis_master' %}
    priority 99
    {% else %}
    priority 100
    {% endif %}
    interface eth0
    virtual_router_id 51
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass 1111
    }

    track_script {
        chk_redis
    }
    notify_stop /etc/keepalived/notify_backup.sh         # keepalived 停掉時執(zhí)行的腳本
    notify_backup /etc/keepalived/notify_backup.sh         # keepalived 角色轉(zhuǎn)變?yōu)?backup 時執(zhí)行的腳本
    notify_master /etc/keepalived/notify_master.sh     # keepalived 角色轉(zhuǎn)變?yōu)?master 時執(zhí)行的腳本
    virtual_ipaddress {
        {{ pillar['vip'] }}
    }
    nopreempt #采用VIP不自動搶占的功能
}

###############################keepalived使用的腳本###############################

# cat /srv/salt/keepalived/templates/check_redis.sh
#!/bin/sh

###檢查redis可用性:進程和是否能夠掛載
/sbin/service redis status &>/dev/null
if [ $? -ne 0 ];then
    ###如果服務狀態(tài)不正常,先嘗試重啟服務
    /sbin/service redis restart
    /sbin/service redis status &>/dev/null
    if [ $? -ne 0 ];then
        ###若重啟redis服務后畏邢,仍不正常
        /sbin/service keepalived stop
    fi
fi

################################################################
# cat /srv/salt/keepalived/templates/notify_master.sh
#!/bin/bash

time=`date "+%F  %H:%M:%S"`
echo -e "$time    ------notify_{{ pillar['role'] }}------\n" >> /etc/keepalived/logs/notify_master.log
# 取消redis的主從復制业扒,轉(zhuǎn)變redis角色為主
sed -i '/^slaveof/d' /etc/redis.conf
sed -i '/^masterauth/d' /etc/redis.conf
sleep 5
/sbin/service redis restart &>> /etc/keepalived/logs/notify_{{ pillar['role'] }}.log
echo -e "\n" >> /etc/keepalived/logs/notify_{{ pillar['role'] }}.log

################################################################
# cat /srv/salt/keepalived/templates/notify_backup.sh
#!/bin/bash

time=`date "+%F  %H:%M:%S"`
echo -e "$time    ------notify_{{ pillar['role'] }}------\n" >> /etc/keepalived/logs/notify_{{ pillar['role'] }}.log
# 檢查redis狀態(tài)和防止多次寫入主從同步信息(slaveof和masterauth)
/sbin/service redis status && ! grep -q "^slaveof" /etc/redis.conf && ! grep -q "^masterauth" /etc/redis.conf &>/dev/null
# 當keepalived服務停止或者角色轉(zhuǎn)變?yōu)閎ackup時,redis角色轉(zhuǎn)變?yōu)閺?if [[ $? -eq 0 ]];then
    echo "slaveof {{ pillar['master_ip'] }} 6379" >> /etc/redis.conf
    echo "masterauth redis_pass" >> /etc/redis.conf
    sleep 2
    /sbin/service redis restart
fi
echo -e "\n" >> /etc/keepalived/logs/notify_{{ pillar['role'] }}.log
  1. 結(jié)果測試


    執(zhí)行結(jié)果
  2. 高可用性測試
  • 關閉主服務器的keepalived舒萎,VIP成功漂移程储,redis主從狀態(tài)成功切換
    node1:


    reids 為主

    VIP正常

    node2:


    redis 為從

    關掉node1的keepalived后
    node1:
    VIP漂移

    redis 角色轉(zhuǎn)變?yōu)閺?/div>

    node2:


    VIP漂移

    redis 角色轉(zhuǎn)變?yōu)橹?/div>

    重新啟動node1的keepalived:
    VIP不搶占
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市臂寝,隨后出現(xiàn)的幾起案子章鲤,更是在濱河造成了極大的恐慌,老刑警劉巖咆贬,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件败徊,死亡現(xiàn)場離奇詭異,居然都是意外死亡掏缎,警方通過查閱死者的電腦和手機皱蹦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來眷蜈,“玉大人沪哺,你說我怎么就攤上這事∽萌澹” “怎么了辜妓?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我嫌拣,道長,這世上最難降的妖魔是什么呆躲? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任异逐,我火速辦了婚禮,結(jié)果婚禮上插掂,老公的妹妹穿的比我還像新娘灰瞻。我一直安慰自己,他們只是感情好辅甥,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布酝润。 她就那樣靜靜地躺著,像睡著了一般璃弄。 火紅的嫁衣襯著肌膚如雪要销。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天夏块,我揣著相機與錄音疏咐,去河邊找鬼。 笑死脐供,一個胖子當著我的面吹牛浑塞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播政己,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼酌壕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了歇由?” 一聲冷哼從身側(cè)響起卵牍,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎印蓖,沒想到半個月后辽慕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡赦肃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年溅蛉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片他宛。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡船侧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出厅各,到底是詐尸還是另有隱情镜撩,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站袁梗,受9級特大地震影響宜鸯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜遮怜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一淋袖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧锯梁,春花似錦即碗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至合敦,卻和暖如春初橘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背充岛。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工壁却, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人裸准。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓展东,卻偏偏與公主長得像,于是被迫代替她去往敵國和親炒俱。 傳聞我的和親對象是個殘疾皇子盐肃,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容