salt实现高可用负载均衡 –一键部署
环境介绍:
Salt-master:172.25.40.1
Salt-minion:172.25.40.2 #部署 keepalived+haproxy
172.25.40.3 #部署 httpd
172.25.40.4 #部署 httpd
172.25.40.5 #部署 keepalived+haproxy
1.首先实现haproxy
yum源实现,提前配置yum源
vim install.sls
haproxy-install:
pkg.installed:
- pkgs:
- haproxy
file.managed:
- name: /etc/haproxy/haproxy.cfg
- source: salt://haproxy/files/haproxy.cfg
service.running:
- name: haproxy
- reload: True
- watch:
- file: haproxy-install
设置负载均衡:(haproxy.cfg)
管理用户组:
vim haproxy.sls
haproxy-group:
group.present:
- name: haproxy
- gid: 200
haproxy-user:
user.present:
- name: haproxy
- uid: 200
- gid: 200
- shell: /sbin/nologin
2.配置keepalived
vim install.sls
include:
- pkgs.keepalived
kp-install:
file.managed:
- name: /mnt/keepalived-1.4.3.tar.gz
- source: salt://keepalived/files/keepalived-1.4.3.tar.gz
cmd.run:
- name: cd /mnt/ && tar zxf keepalived-1.4.3.tar.gz && cd keepalived-1.4.3 && ./configure --prefix=/usr/local/keepalived --with-init=SYSV &> /dev/null && make &>/dev/null && make install &>/dev/null
- creates: /usr/local/keepalived
/etc/keepalived:
file.directory:
- mode: 755
/etc/sysconfig/keepalived:
file.symlink:
- target: /usr/local/keepalived/etc/sysconfig/keepalived
/etc/init.d/keepalived:
file.managed:
- source: salt://keepalived/files/keepalived
- mode: 755
/sbin/keepalived:
file.symlink:
- target: /usr/local/keepalived/sbin/keepalived
vim service.sls
include:
- keepalived.install
/etc/keepalived/keepalived.conf:
file.managed:
- source: salt://keepalived/files/keepalived.conf
- template: jinja
{% if grains['fqdn'] == 'server2' %}
- STATE: MASTER
- VRID: 51
- PRIORITY: 100
{% elif grains['fqdn'] == 'server5' %}
- STATE: BACKUP
- VRID: 51
- PRIORITY: 50
{% endif %}
keepalived:
service.running:
- reload: True
- watch:
- file: /etc/keepalived/keepalived.conf
修改配置文件:
管理依赖性其他包:
vim keepalived.sls
make:
pkg.installed:
- pkgs:
- gcc
- pcre-devel
- openssl-devel
3.配置后端httpd
vim install.sls
apache-install:
pkg.installed:
- pkgs:
- httpd
/etc/httpd/conf/httpd.conf:
file.managed:
- source: salt://httpd/files/httpd.conf
vim service.sls
include:
- httpd.install
apache:
service.running:
- name: httpd
- enable: True
- reload: True
- watch:
- file: /etc/httpd/conf/httpd.conf
4.编写top文件,实现一键部署
/srv/salt/
vim top.sls
base:
'server2':
- haproxy.install
- keepalived.service
'server3':
- httpd.service
'server4':
- httpd.service
'server5':
- haproxy.install
- keepalived.service
salt '*' state.highstate
实现高可用负载均衡
当干掉master后负载均衡继续实现
将salt的信息返回给数据库
编写自己的模块
/srv/salt/
mkdir _modules
vim my_disk.py
#!/usr/bin/env python
def df():
cmd = 'df -h'
return __salt__['cmd.run'](cmd)
同步:
salt server3 saltutil.sync_modules
server3端查看:
使用
salt server3 my_disk.df #文件前缀+定义的模块名
salt命令的其他应用:
脚本
/srv/salt/
vim test.sh
echo 'hello world'
chmod +x test.sh
发送到其他minion
salt-cp '*' '/srv/salt/test.sh' '/tmp/test.sh'
执行脚本
salt '*' cmd.script /tmp/test.sh
本地复制文件到..
salt '*' cp.get_file salt://test.sh /mnt/test.sh
salt的高可用
topmaster–(syndic + master)–minion
安装两台master,一台做topmaster ,一台做master
topmaster: (server3)
/etc/salt/
vim master
order_masters: True
/etc/init.d/salt-master start
master+syndic:(server1)
yum install -y salt-syndic
/etc/salt/
vim master
syndic_master: server3
/etc/init.d/salt-master restart
/etc/init.d/salt-syndic start
topmaster处需要认证:
测试:
topmaster端推送都可以实现
salt-ssh
实现minion端无需开启利用ssh实现连接
首先关闭所有minion端
master端安装salt-ssh
/etc/salt/
vim roster
server2:
host: 172.25.40.2
user: root
passwd: redhat
server3: #不一定为主机名
host: 172.25.40.3 #主机ip
user: root #用户
passwd: redhat #密码
直接即可测试:
salt-ssh '*' test.ping -i #第一次连接 -i
ssh直接进行推送
salt-ssh '*' state.highstate
salt调用api
yum install -y salt-api
设置认证:
/etc/pki/tls/private/
openssl genrsa 2048
openssl genrsa 2048 > localhost.key
/etc/pki/tls/certs/
make testcert
/etc/salt/master.d/
vim api.conf
rest_cherrypy:
port: 8000
ssl_crt: /etc/pki/tls/certs/localhost.crt
ssl_key: /etc/pki/tls/private/localhost.key
vim eauth.conf
external_auth:
pam:
salt-api:
- '.*'
- '@wheel'
- '@runner'
- '@jobs'
开启:
/etc/init.d/salt-api start
创建salt-api用户设置密码
useradd salt-api
passwd salt-api
查找apijiekou:
curl -sSk https://localhost:8000/login -H 'Accept: application/x-yaml' -d username=salt-api -d password=westos -d eauth=pam
简单调用api:
curl -sSk https://localhost:8000 -H 'Accept: application/x-yaml' -H 'X-Auth-Token: 9f95827f9918c04bdb45cef1b13498eafe948617' -d client=local -d tgt='*' -d fun=test.ping
注:关闭syndic,开启所有minion端
利用api实现推送
vim saltapi.py
# -*- coding: utf-8 -*-
import urllib2,urllib
import time
try:
import json
except ImportError:
import simplejson as json
class SaltAPI(object):
__token_id = ''
def __init__(self,url,username,password):
self.__url = url.rstrip('/')
self.__user = username
self.__password = password
def token_id(self):
''' user login and get token id '''
params = {'eauth': 'pam', 'username': self.__user, 'password': self.__password}
encode = urllib.urlencode(params)
obj = urllib.unquote(encode)
content = self.postRequest(obj,prefix='/login')
try:
self.__token_id = content['return'][0]['token']
except KeyError:
raise KeyError
def postRequest(self,obj,prefix='/'):
url = self.__url + prefix
headers = {'X-Auth-Token' : self.__token_id}
req = urllib2.Request(url, obj, headers)
opener = urllib2.urlopen(req)
content = json.loads(opener.read())
return content
def list_all_key(self):
params = {'client': 'wheel', 'fun': 'key.list_all'}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
minions = content['return'][0]['data']['return']['minions']
minions_pre = content['return'][0]['data']['return']['minions_pre']
return minions,minions_pre
def delete_key(self,node_name):
params = {'client': 'wheel', 'fun': 'key.delete', 'match': node_name}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0]['data']['success']
return ret
def accept_key(self,node_name):
params = {'client': 'wheel', 'fun': 'key.accept', 'match': node_name}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0]['data']['success']
return ret
def remote_noarg_execution(self,tgt,fun):
''' Execute commands without parameters '''
params = {'client': 'local', 'tgt': tgt, 'fun': fun}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0][tgt]
return ret
def remote_execution(self,tgt,fun,arg):
''' Command execution with parameters '''
params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0][tgt]
return ret
def target_remote_execution(self,tgt,fun,arg):
''' Use targeting for remote execution '''
params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg, 'expr_form': 'nodegroup'}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
jid = content['return'][0]['jid']
return jid
def deploy(self,tgt,arg):
''' Module deployment '''
params = {'client': 'local', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
return content
def async_deploy(self,tgt,arg):
''' Asynchronously send a command to connected minions '''
params = {'client': 'local_async', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
jid = content['return'][0]['jid']
return jid
def target_deploy(self,tgt,arg):
''' Based on the node group forms deployment '''
params = {'client': 'local_async', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg, 'expr_form': 'nodegroup'}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
jid = content['return'][0]['jid']
return jid
def main():
sapi = SaltAPI(url='https://172.25.40.1:8000',username='salt-api',password='westos')
sapi.token_id()
#print sapi.list_all_key()
#sapi.delete_key('test-01')
#sapi.accept_key('test-01')
print sapi.deploy('server2', 'httpd.service') #
#print sapi.remote_noarg_execution('test-01','grains.items')
if __name__ == '__main__':
main()
执行
python saltapi.py
server2: