自定义模块
[root@server1 ~]# cd /srv/salt/
[root@server1 salt]# mkdir _modules/
[root@server1 salt]# ls
haproxy httpd _modules nginx pkgs top.sls user
[root@server1 salt]# cd _modules/
[root@server1 _modules]# vim my_disk.py
[root@server1 _modules]# cat my_disk.py
#!/usr/bin/env python
def df():
return __salt__['cmd.run']('df -h')
[root@server1 _modules]# salt server2 saltutil.sync_modules
server2:
- modules.my_disk
server2查看:
[root@server2 ~]# cd /var/cache/salt/
[root@server2 salt]# ls
minion
[root@server2 salt]# tree minion/
minion/
|-- accumulator
|-- extmods
| `-- modules
| `-- my_disk.py
|-- files
| `-- base
| |-- httpd
| | |-- apache.sls
| | `-- files
| | `-- httpd.conf
| |-- _modules
| | `-- my_disk.py ###自定义模块
| `-- top.sls
|-- highstate.cache.p
|-- module_refresh
|-- pkg_refresh
|-- proc
`-- sls.p
9 directories, 9 files
server1测试自定义模块:
[root@server1 _modules]# salt server2 my_disk.df
server2:
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root 19G 987M 17G 6% /
tmpfs 499M 16K 499M 1% /dev/shm
/dev/vda1 485M 33M 427M 8% /boot
可以定义多个模块
[root@server1 _modules]# cat my_disk1.py
#!/usr/bin/env python
def hello():
return __salt__['cmd.run']('ls -a')
[root@server1 _modules]# salt server2 saltutil.sync_modules
server2:
- modules.my_disk1
server2查看情况:
[root@server2 salt]# tree minion/
minion/
|-- accumulator
|-- extmods
| `-- modules
| |-- my_disk1.py
| |-- my_disk1.pyc
| `-- my_disk.py
|-- files
| `-- base
| |-- httpd
| | |-- apache.sls
| | `-- files
| | `-- httpd.conf
| |-- _modules
| | |-- my_disk1.py
| | `-- my_disk.py
| `-- top.sls
|-- highstate.cache.p
|-- module_refresh
|-- pkg_refresh
|-- proc
`-- sls.p
9 directories, 12 files
server1执行模块
[root@server1 _modules]# salt server2 my_disk1.hello
server2:
.
..
.bash_history
.bash_logout
.bash_profile
.bashrc
.cshrc
.ssh
.tcshrc
.viminfo
anaconda-ks.cfg
install.log
install.log.syslog
mfs-chunkserver-1.6.26-1.x86_64.rpm
saltstack的工作模式:master发送命令给minion,minion执行后发送给master保存,同时minion也会发送一份数据给数据库进行备份,以下实验进行验证:
[root@server2 salt]# yum install -y MySQL-python.x86_64
[root@server1 _modules]# yum install -y mysql-server
编辑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;
###将编辑的test.sql文件导入数据库###
[root@server1 ~]# mysql -pwestos < test.sql
数据库查看:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| salt |
+--------------------+
3 rows in set (0.00 sec)
mysql> use salt;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+----------------+
| Tables_in_salt |
+----------------+
| jids |
| salt_events |
| salt_returns |
+----------------+
3 rows in set (0.00 sec)
###测试需要minion服务器进行授权###
mysql> grant all on salt.* to salt@'172.25.60.%' identified by 'westos';
Query OK, 0 rows affected (0.00 sec)
server2配置文件编辑:
[root@server2 salt]# vim /etc/salt/minion
815 mysql.host: '172.25.60.1'
816 mysql.user: 'salt'
817 mysql.pass: 'westos'
818 mysql.db: 'salt'
819 mysql.port: 3306
[root@server2 salt]# /etc/init.d/salt-minion restart
Stopping salt-minion:root:server2 daemon: OK
Starting salt-minion:root:server2 daemon: OK
server1测试:
[root@server1 ~]# salt '*' test.ping --return mysql
server2:
True
server1:
True
server3:
True
mysql> show tables;
+----------------+
| Tables_in_salt |
+----------------+
| jids |
| salt_events |
| salt_returns |
+----------------+
3 rows in set (0.00 sec)
###数据库查看,server2将执行的命令结果发送到数据库###
mysql> select * from salt_returns;
+-----------+----------------------+--------+---------+---------+-------------------------------------------------------------------------------------------------------------------------------------+---------------------+
| fun | jid | return | id | success | full_ret | alter_time |
+-----------+----------------------+--------+---------+---------+-------------------------------------------------------------------------------------------------------------------------------------+---------------------+
| test.ping | 20180720103854827006 | true | server2 | 1 | {"fun_args": [], "jid": "20180720103854827006", "return": true, "retcode": 0, "success": true, "fun": "test.ping", "id": "server2"} | 2018-07-20 10:38:55 |
+-----------+----------------------+--------+---------+---------+-------------------------------------------------------------------------------------------------------------------------------------+---------------------+
1 row in set (0.00 sec)
minion在给master发送数据同时还需要给master数据库发送信息,造成minion的压力过大,我们可以设置minion发送给master,master收到结果返回给数据库,减轻minion的压力:
[root@server1 ~]# vim /etc/salt/master
1059 master_job_cache: mysql
1060 mysql.host: '172.25.60.1'
1061 mysql.user: 'salt'
1062 mysql.pass: 'westos'
1063 mysql.db: 'salt'
1064 mysql.port: 3306
[root@server1 ~]# /etc/init.d/salt-master restart
Stopping salt-master daemon: [ OK ]
Starting salt-master daemon: [ OK ]
执行命令测试是否会同步到数据库:
报错:
[root@server1 ~]# salt server2 grains.items
[CRITICAL] Could not deserialize msgpack message.This often happens when trying to read a file not in binary modeTo see message payload, enable debug logging and retry. Exception: unpack(b) received extra data.
[ERROR ] Uncaught exception, closing connection.
解决办法:
[root@server1 ~]# yum install -y MySQL-python
执行命令测试
[root@server1 ~]# salt server2 grains.items
执行完成以后数据存放位置:
[root@server1 jobs]# ls -R *
03:
80945b899da773e4f7d626db0f97da772969ee3b1409adb290cc2af4be4d66
03/80945b899da773e4f7d626db0f97da772969ee3b1409adb290cc2af4be4d66:
jid server2
03/80945b899da773e4f7d626db0f97da772969ee3b1409adb290cc2af4be4d66/server2:
return.p
0f:
eac50fc51ace26c55b6681e3296556284f042777c864cb06056de96334d6eb
0f/eac50fc51ace26c55b6681e3296556284f042777c864cb06056de96334d6eb:
jid server2
0f/eac50fc51ace26c55b6681e3296556284f042777c864cb06056de96334d6eb/server2:
return.p
数据库查看信息:
mysql> select * from salt_returns\G;
*************************** 2. row ***************************
fun: grains.items
jid: 20180720105649579132
saltstack实现主从备份
[root@server1 jobs]# salt-key -L
Accepted Keys:
server1
server2
server3
Denied Keys:
Unaccepted Keys:
Rejected Keys:
[root@server1 jobs]# salt-key -d server1
The following keys are going to be deleted:
Accepted Keys:
server1
Proceed? [N/y] y
Key for minion server1 deleteed.
[root@server1 jobs]# salt-key -d server3
The following keys are going to be deleted:
Accepted Keys:
server3
Proceed? [N/y] y
Key for minion server3 deleteed.
[root@server1 jobs]# salt-key -L
Accepted Keys:
server2
Denied Keys:
Unaccepted Keys:
Rejected Keys:
###停止server1和server3的minion服务
[root@server1 jobs]# /etc/init.d/salt-minion stop
Stopping salt-minion:root:server1 daemon: OK
[root@server1 jobs]# chkconfig salt-minion off
[root@server3 ~]# /etc/init.d/salt-minion stop
Stopping salt-minion:root:server3 daemon: OK
[root@server3 ~]# chkconfig salt-minion off
###server3安装salt-maseter软件###
[root@server3 ~]# yum install -y salt-master.noarch
[root@server3 ~]# cd /etc/salt/
[root@server3 salt]# vim master
857 #order_masters: False
858 order_masters: True
[root@server3 salt]# /etc/init.d/salt-master start
Starting salt-master daemon: [ OK ]
###server1安装salt-syndic软件###
[root@server1 jobs]# yum install -y salt-syndic.noarch
编辑文件配置文件/etc/salt/master
861 #syndic_master: masterofmasters
862 syndic_master: 172.25.60.3
[root@server1 salt]# /etc/init.d/salt-syndic restart
Stopping salt-syndic daemon: [ OK ]
Starting salt-syndic daemon: [ OK ]
[root@server1 salt]# /etc/init.d/salt-master restart
Stopping salt-master daemon: [ OK ]
Starting salt-master daemon: [ OK ]
[root@server3 salt]# salt-key -L
Accepted Keys:
Denied Keys:
Unaccepted Keys:
server1
Rejected Keys:
[root@server3 salt]# salt-key -a server1
The following keys are going to be accepted:
Unaccepted Keys:
server1
Proceed? [n/Y] y
Key for minion server1 accepted.
[root@server3 salt]# salt-key -L
Accepted Keys:
server1
Denied Keys:
Unaccepted Keys:
Rejected Keys:
测试:
[root@server3 salt]# salt '*' test.ping
server2:
True
saltstack实现ssh远程连接执行命令
[root@server1 salt]# yum install -y salt-ssh.noarch
[root@server1 ~]# vim /etc/salt/roster
9 server2:
10 host: 172.25.60.2
11 user: root
12 passwd: westos
[root@server2 ~]# /etc/init.d/salt-minion restart
Service salt-minion:root:server2 is not running
Starting salt-minion:root:server2 daemon: OK
测试:
[root@server1 salt]# salt-ssh server2 test.ping
[ERROR ] MySQL returner could not connect to database: (1045, "Access denied for user 'root'@'server1' (using password: YES)")
Traceback (most recent call last):
File "/usr/lib/python2.6/site-packages/salt/client/ssh/__init__.py", line 609, in run
self.returners['{0}.save_load'.format(self.opts['master_job_cache'])](jid, job_load)
File "/usr/lib/python2.6/site-packages/salt/returners/mysql.py", line 314, in save_load
with _get_serv(commit=True) as cur:
File "/usr/lib64/python2.6/contextlib.py", line 16, in __enter__
return self.gen.next()
File "/usr/lib/python2.6/site-packages/salt/returners/mysql.py", line 251, in _get_serv
raise salt.exceptions.SaltMasterError('MySQL returner could not connect to database: {exc}'.format(exc=exc))
SaltMasterError: MySQL returner could not connect to database: (1045, "Access denied for user 'root'@'server1' (using password: YES)")
[ERROR ] Could not save load with returner mysql: MySQL returner could not connect to database: (1045, "Access denied for user 'root'@'server1' (using password: YES)")
[ERROR ] No matching targets found in roster.
以上测试报错:
注销文件的数据库登陆地方:
[root@server1 salt]# vim master
# Which returner(s) will be used for minion's result:
#return: mysql
#master_job_cache: mysql
#mysql.host: '172.25.60.1'
#mysql.user: 'salt'
#mysql.pass: 'westos'
#mysql.db: 'salt'
#mysql.port: 3306
[root@server1 salt]# /etc/init.d/salt-master restart
Stopping salt-master daemon: [ OK ]
Starting salt-master daemon: [ OK ]
[root@server1 salt]# salt-ssh server2 test.ping -i
server2:
True
saltstack基于API操作
[root@server1 salt]# yum install -y salt-api.noarch
安装时已经依赖软件python-cherrypy.noarch,如果没有安装需要安装该软件
Dependency Installed:
python-cherrypy.noarch 0:3.2.2-4.el6
进行加密设置
[root@server1 private]# pwd
/etc/pki/tls/private
[root@server1 private]# openssl genrsa 1024
Generating RSA private key, 1024 bit long modulus
.....................++++++
...........................................++++++
e is 65537 (0x10001)
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQD6owImTIezQU7Uv86Xd/BVxnG7hxplohgQahazfCdrnonjabbJ
0OkeIyk4KMmFSYYYR6902auZU1jqeo5DIHDiXTmpnvBb/GJt98NGIIehUgBmdii2
IwHQoM6hpscbzKuH6aEp0t/uN3whHMdD7e5dzQ3uO6B74idvOGjn3HlC0QIDAQAB
AoGAMfcXMZ1mHBUz6vPF8qpFbkQeXj0jxQkYdQVBO0zP6wNzB7QGbZtJLeniiMCQ
1BKBOgvobYoLTIiyHCSMgdNQzVq7C6VOSrj8zyHZmOBIs0ZaZ02vD57219eLeb/W
32n0GlYg0sBYr4sqvn0ZR05pX0S+V5NZHMLUafwikDVVwgECQQD+7aKfZjslMf//
GxMHw407hGaygzMDNcJ7TbBglUSfHSFjGN+LwrX6+A2oqcrjoaMi44ojRWVfJU3y
fQrlOjvxAkEA+7DBIzPVksFd1Q82Xw8iJ8/joARSvsvI5HvDiOu6H3o2b7206CbD
pymJjT1YSNnknSme3VgCbb66pZb5SBfU4QJAa9KIsNClfXLrarPB1cvRBXZXlXNG
dTocutg+HGul7YJ9p5NSoaNGIxMde9Ps22B3Rn9k4swsNxTpJgHbRN7fkQJBANAv
n0IAARv36CZxA9dTTDxEIBNfIBaDt7MOkGm0GmspCtgYwgf48INXv1hdsqXn3csF
/0s1HiUqy3Zmz+GLHOECQQCjAsgxQAMa2fh3wl4ZugZp57Z8CIQHrBJWbfjLrs7C
RLTCOIGt5nk/HziDiX64rBhA7LlKIftkey+mm5O/EiRR
-----END RSA PRIVATE KEY-----
[root@server1 private]# openssl genrsa 1024 > localhost.key
Generating RSA private key, 1024 bit long modulus
.....++++++
........++++++
e is 65537 (0x10001)
[root@server1 certs]# pwd
/etc/pki/tls/certs
[root@server1 certs]# make testcert
umask 77 ; \
/usr/bin/openssl req -utf8 -new -key /etc/pki/tls/private/localhost.key -x509 -days 365 -out /etc/pki/tls/certs/localhost.crt -set_serial 0
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Shaanxi
Locality Name (eg, city) [Default City]:xi'an
Organization Name (eg, company) [Default Company Ltd]:westos
Organizational Unit Name (eg, section) []:linux
Common Name (eg, your name or your server's hostname) []:server2
Email Address []:root@localhost
修改配置文件:
[root@server1 certs]# cd /etc/salt/
[root@server1 salt]# vim master
11 # as the main master config file).
12 default_include: master.d/*.conf
[root@server1 salt]# cd master.d/
[root@server1 master.d]# ls
[root@server1 master.d]# vim api.conf
[root@server1 master.d]# cat api.conf
rest_cherrypy:
port: 8000
ssl_crt: /etc/pki/tls/certs/localhost.crt
ssl_key: /etc/pki/tls/private/localhost.key
[root@server1 master.d]# vim auth.conf
[root@server1 master.d]# cat auth.conf
external_auth:
pam:
saltapi:
- .*
- '@wheel'
- '@runner'
- '@jobs'
添加saltapi用户
[root@server1 master.d]# useradd saltapi
[root@server1 master.d]# passwd saltapi ###密码westos
Changing password for user saltapi.
New password:
BAD PASSWORD: it is based on a dictionary word
BAD PASSWORD: is too simple
Retype new password:
passwd: all authentication tokens updated successfully.
[root@server1 master.d]# /etc/init.d/salt-master restart
Stopping salt-master daemon: [ OK ]
Starting salt-master daemon: [ OK ]
[root@server1 master.d]# /etc/init.d/salt-api start
Starting salt-api daemon: [ OK ]
[root@server1 master.d]# curl -sSk https://localhost:8000/login \
> -H 'Accept: application/x-yaml' \
> -d username=saltdev \
> -d password=saltdev \
> -d eauth=auto
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
<title>401 Unauthorized</title>
<style type="text/css">
#powered_by {
margin-top: 20px;
border-top: 2px solid black;
font-style: italic;
}
#traceback {
color: red;
}
</style>
</head>
<body>
<h2>401 Unauthorized</h2>
<p>Could not authenticate using provided credentials</p>
<pre id="traceback"></pre>
<div id="powered_by">
<span>Powered by <a href="http://www.cherrypy.org">CherryPy 3.2.2</a></span>
</div>
</body>
</html>
[root@server1 master.d]# netstat -antplue | grep :8000
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 0 60672 24904/salt-api -d
[root@server1 master.d]# curl -sSk https://localhost:8000/login -H'Accept: application/x-yaml' -d username=saltapi -d password=westos -d eauth=pam
return:
- eauth: pam
expire: 1532111914.3066471
perms:
- .*
- '@wheel'
- '@runner'
- '@jobs'
start: 1532068714.3066461
token: d9450ebc1cb40d8b1c22960236002cea7274c94c
user: saltapi
测试操作:
[root@server1 master.d]# curl -sSk https://localhost:8000 -H'Accept: application/x-yaml' -H 'X-Auth-Token: d9450ebc1cb40d8b1c22960236002cea7274c94c' -d client=local -d tgt='*' -d fun=test.pingreturn:
- server2: true
[root@server1 master.d]# curl -sSk https://localhost:8000 -H'Accept: application/x-yaml' -H 'X-Auth-Token: d9450ebc1cb40d8b1c22960236002cea7274c94c' -d client=local -d tgt='*' -d fun=my_disk.df
return:
- server2: 'Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root 19G 1015M 17G 6% /
tmpfs 499M 64K 499M 1% /dev/shm
/dev/vda1 485M 33M 427M 8% /boot'
[root@server1 ~]# vim saltapi.py
[root@server1 ~]# python saltapi.py
([u'server2'], [])
添加其他用户