实验准备:server1再添加一个minion
添加方法请参考https://blog.csdn.net/l675655077/article/details/81974353
1.keepalived实现负载均衡
server4:
[root@server4 ~]# vim /etc/yum.repos.d/rhel-source.repo
[rhel-source]
name=Red Hat Enterprise Linux $releasever - $basearch - Source
baseurl=http://172.25.51.250/rhel6.5
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
[salt]
name=saltstack
baseurl=http://172.25.51.250/rhel6
gpgcheck=0
[LoadBalancer]
name=LoadBalancer
baseurl=http://172.25.51.250/rhel6.5/LoadBalancer
gpgcheck=0
[root@server4 ~]# yum install salt-minion -y
[root@server4 ~]# vim /etc/salt/minion
[root@server4 ~]# /etc/init.d/salt-minion start
在server1:
[root@server1 ~]# salt-key -L
[root@server1 ~]# salt-key -A
[root@server1 ~]# salt-key -L
[root@server1 ~]# cd /srv/salt/
[root@server1 salt]# mkdir keepalived
[root@server1 salt]# cd keepalived/
[root@server1 keepalived]# mkdir files
[root@server1 keepalived]# vim install.sls
include:
- pkgs.make
kp-install:
file.managed:
- name: /mnt/keepalived-2.0.6.tar.gz
- source: salt://keepalived/files/keepalived-2.0.6.tar.gz
cmd.run:
- name: cd /mnt && tar zxf keepalived-2.0.6.tar.gz && cd keepalived-2.0.6 && ./configure --prefix=/usr/local/keepalived --with-init=SYSV &> /dev/null && make &> /dev/null && make install &> /dev/null
- creates: /usr/local/keepalived
/etc/sysconfig/keepalived:
file.symlink:
- target: /usr/local/keepalived/etc/sysconfig/keepalived
/sbin/keepalived:
file.symlink:
- target: /usr/local/keepalived/sbin/keepalived
/etc/keepalived:
file.directory:
- mode: 755
[root@server1 keepalived]# cd files
[root@server1 files]# ls
[root@server1 keepalived]# salt '*' state.sls keepalived.install
在server4查看是否安装成功:
[root@server4 keepalived]# ll /etc/sysconfig/keepalived
[root@server4 keepalived]# ll /sbin/keepalived
将server4的脚本和配置文件scp给server1:
[root@server4 init.d]# scp /usr/local/keepalived/etc/rc.d/init.d/keepalived root@172.25.129.1:/srv/salt/keepalived/files
[root@server4 init.d]# scp /usr/local/keepalived/etc/keepalived/keepalived.conf root@172.25.129.1:/srv/salt/keepalived/files
在server1上修改keepalived的配置文件
[root@server1 salt]# cd /srv/salt/keepalived/files/
[root@server1 files]# vim keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from keepalived@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
#vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state {{ STATE }}
interface eth0
virtual_router_id {{ VRID }}
priority {{ PRIORITY }}
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.129.100
}
}
使用jinja模板
[root@server1 files]# cd /srv/pillar
[root@server1 pillar]# mkdir keepalived
[root@server1 pillar]# cd keepalived/
[root@server1 keepalived]# vim install.sls
[root@server1 keepalived]# cd /srv/salt/keepalived/
[root@server1 keepalived]# vim service.sls
include:
- keepalived.install
/etc/keepalived/keepalived.conf:
file.managed:
- source: salt://keepalived/files/keepalived.conf
- template: jinja
- context:
STATE: {{ pillar['state'] }}
VIRD: {{ pillar['vrid'] }}
PRIORITY: {{ pillar['priority'] }}
kp-service:
file.managed:
- name: /etc/init.d/keepalived
- source: salt://keepalived/files/keepalived
- mode: 755
service.running:
- name: keepalived
- reload: True
- watch:
- file: /etc/keepalived/keepalived.conf
修改base文件
[root@server1 keepalived]# cd /srv/pillar/
[root@server1 pillar]# vim top.sls
安装mailx
[root@server1 salt]# cd pkgs/
[root@server1 pkgs]# vim make.sls
[root@server1 srv]# cd salt/
[root@server1 salt]# vim top.sls
base:
'server1':
- haproxy.install
- keepalived.service
'server1':
- haproxy.install
- keepalived.service
'roles:apache':
- match: grain
- httpd.install
'roles:nginx':
- match: grain
- nginx.service
[root@server1 pillar]# salt '*' state.highstate
测试:
在server1上查看:
[root@server1 keepalived]# ip addr
可以看到,虚拟ip在server1上
[root@server1 keepalived]# /etc/init.d/keepalived stop
在server4上查看:
在server1上查看:
可以看到,虚拟ip转移到了server4上
补充的几个问题:
1.在/etc/salt/keepalived/install.sls 里 给/etc/sysconfig/keepalived:做软连接是因为/etc/init.d/keepalived这个脚本调用了它
2.安装mailx的作用是因为当keepalived发生故障时会发送邮件到本机,如果可以连接到外网也可以指定发送邮件到指定地址
3.当vip在server1上时,关闭server1的haproxy,网页将无法访问,因为没有开启keppalived对于haproxy的监控功能,如果需要开启,则需要自己编写脚本才能开启
做法:
[root@server1 /]# cd /opt
[root@server1 opt]# vim check_haproxy.sh
#!/bin/bash
/etc/init.d/haproxy status &> /dev/null || /etc/init.d/haproxy restart &> /dev/null
if [ $? -ne 0 ] ; then
/etc/init.d/keepalived stop &> /dev/null
fi
[root@server1 opt]# chmod +x check_haproxy.sh
[root@server1 /]# cd /srv/salt/keepalived/files
[root@server1 files]# vim keepalived.conf
[root@server1 files]# salt server1 state.sls keepalived.service
[root@server1 files]# salt server4 state.sls keepalived.service
测试:
在server1破坏haproxy
[root@server1 init.d]# chmod -x haproxy
每隔两秒调用一次脚本,发现haproxy状态异常,所以关闭keepalived,切换到server4工作。之后要恢复server1时,给server1的haproxy再次加上权限之后需要手动开启keepalived,因为keepalived已经关闭,无法自动开启
salt的其他用法:
salt server1 service.stop keepalived ##关闭keepalived
salt-cp ‘*’ /etc/passwd /tmp/ ##传输文件
salt server3 state.single pkg.installed httpd ##安装httpd服务
salt server3 cmd.run ‘yum install httpd -y’
2.mysql记录salt操作历史
server1:
[root@server1 init.d]# yum install mysql-server -y
[root@server1 init.d]# yum install MySQL-python.x86_64 0:1.2.3-0.3.c1.1.el6 -y
[root@server1 init.d]# /etc/init.d/mysqld start
[root@server1 init.d]# mysql
mysql> grant all on salt.* to salt@'172.25.129.%' identified by 'westos'; 授权
mysql> grant all on salt.* to salt@localhost identified by 'westos';
[root@server1 init.d]# vim test.sql
CREATE DATABASE `salt`
DEFAULT CHARACTER SET utf8
DEFAULT COLLATE utf8_general_ci;
USE `salt`;
--
-- Table structure for table `jids`
--
DROP TABLE IF EXISTS `jids`;
CREATE TABLE `jids` (
`jid` varchar(255) NOT NULL,
`load` mediumtext NOT NULL,
UNIQUE KEY `jid` (`jid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- CREATE INDEX jid ON jids(jid) USING BTREE;
--
-- Table structure for table `salt_returns`
--
DROP TABLE IF EXISTS `salt_returns`;
CREATE TABLE `salt_returns` (
`fun` varchar(50) NOT NULL,
`jid` varchar(255) NOT NULL,
`return` mediumtext NOT NULL,
`id` varchar(255) NOT NULL,
`success` varchar(10) NOT NULL,
`full_ret` mediumtext NOT NULL,
`alter_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
KEY `id` (`id`),
KEY `jid` (`jid`),
KEY `fun` (`fun`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table structure for table `salt_events`
--
DROP TABLE IF EXISTS `salt_events`;
CREATE TABLE `salt_events` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`tag` varchar(255) NOT NULL,
`data` mediumtext NOT NULL,
`alter_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`master_id` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `tag` (`tag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
[root@server1 init.d]# mysql < test.sql
[root@server1 init.d]# vim /etc/salt/master
[root@server1 init.d]# /etc/init.d/salt-master restart
[root@server1 ~]# reboot
[root@server1 ~]# /etc/init.d/mysqld start
[root@server1 init.d]# salt server3 cmd.run 'df -h'
[root@server1 init.d]# mysql -u salt -p
mysql> select * from salt_returns;
可以看到,刚才的‘df -h’操作被记录在该表中
另一种:在minion端操作(没有上边方案高效),只是进行对比
[root@server2 ~]# vim /etc/salt/minion
[root@server2 ~]# /etc/init.d/salt-minion restart
3.自定义模块
[root@server1 init.d]# mkdir /srv/salt/_modules
[root@server1 init.d]# cd /srv/salt/_modules
[root@server1 _modules]# vim my_disk.py
[root@server1 _modules]# salt '*' saltutil.sync_modules
[root@server1 _modules]# salt '*' my_disk.df
4.横向扩展
server4充当topmaster
配置server4:
[root@server4 opt]# /etc/init.d/salt-minion stop
[root@server4 opt]# chkconfig salt-minion off
[root@server4 opt]# /etc/init.d/haproxy stop
[root@server4 opt]# /etc/init.d/keepalived stop
[root@server4 opt]# yum install salt-master
[root@server4 opt]# /etc/init.d/salt-master start
配置server1:
[root@server1 ~]# salt-key -d server4
[root@server1 ~]# yum install salt-syndic
[root@server1 ~]# vim /etc/salt/master
在server4测试:
[root@server4 ~]# salt '*' test.ping
server4没有minion但以可以探测到server1、server2、server3,因为server4与syndic进行通信,server1执行这个命令,然后将结果交给syndic,syndic再传给server4
5.salt-ssh roster
优点:不需要在远端装minion
ps:普通用户要用sudo激活root用户不用
在server3:
[root@server3 ~]# /etc/init.d/salt-minion stop
在server1:
[root@server1 _modules]# yum install salt-ssh -y
[root@server1 _modules]# vim /etc/salt/roster
[root@server1 _modules]# vim /etc/salt/master
[root@server1 ~]# /etc/init.d/salt-master stop
[root@server1 ~]# /etc/init.d/salt-master start ##重启salt-master
[root@server1 ~]# salt-ssh 'server3' test.ping -i
[root@server1 ~]# salt-ssh 'server3' my_disk.df
6.API的使用
开启server3的minion
[root@server3 ~]# /etc/init.d/salt-minion start
server1安装api
[root@server1 ~]# yum install salt-api -y
[root@server1 ~]# cd /etc/pki/tls/private
[root@server1 private]# ls
[root@server1 private]# openssl genrsa 1024 >localhost.key
[root@server1 private]# cd /etc/pki/tls/certs/
[root@server1 certs]# make testcert
[root@server1 salt]# cd /etc/salt/master.d/
[root@server1 master.d]# vim eauth.conf
[root@server1 master.d]# vim api.conf
[root@server1 master.d]# /etc/init.d/salt-api start
[root@server1 master.d]# useradd saltapi
[root@server1 master.d]# passwd saltapi 密码改为westos
[root@server1 master.d]# /etc/init.d/salt-master stop
Stopping salt-master daemon: [ OK ]
[root@server1 master.d]# /etc/init.d/salt-master status
salt-master is stopped
[root@server1 master.d]# /etc/init.d/salt-master start
Starting salt-master daemon: [ OK ]
[root@server1 ~]# 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.129.1:8000',username='saltapi',password='westos')
sapi.token_id()
print sapi.list_all_key()
#sapi.delete_key('test-01')
#sapi.accept_key('test-01')
#sapi.deploy('*','httpd.apache')
#print sapi.remote_noarg_execution('test-01','grains.items')
if __name__ == '__main__':
main()
[root@server1 ~]# curl -sSk https://localhost:8000/login -H 'Accept: application/x-yaml' -d username=saltapi -d password=westos -d eauth=pam
[root@server1 ~]# curl -sSk https://localhost:8000 -H 'Accept: application/x-yaml' -H 'X-Auth-Token: d0cc1f956b7634cd14b0116435b92cf734f1ca5e' -d client=local -d tgt='*' -d fun=test.ping
[root@server1 ~]# vim saltapi.py
[root@server1 ~]# python saltapi.py
在server3查看效果:nginx服务被开启运行