开三台rhel6.5的虚拟机
server1 172.25.66.1 master
server2 172.25.66.2 minion
server3 172.25.66.3 minion
1.安装软件
搭建salt软件仓库(把整个目录放在apache下)
配置repo文件
[salt]
name=salt
baseurl=http://172.25.66.100/rhel6
gpgcheck=0
[root@server1 ~]# yum install salt-master -y
[root@server2 ~]# yum install salt-minion -y
[root@server3 ~]# yum install salt-minion -y
[root@server1 ~]# /etc/init.d/salt-master start
master 开启4505,4506两个端口,进行长连接(速度快的原因)(发布订阅系统)
4505端口负责推送消息给slave
4506端口负责接受slave的报告
server2,server3一样,配置启动
[root@server2 ~]# vim /etc/salt/minion
master: 172.25.66.1 ##设置master
[root@server2 ~]# /etc/init.d/salt-minion start
[root@server2 salt]# cat minion_id
server2
[root@server3 salt]# cat minion_id
server3
关联
[root@server1 ~]# salt-key -L ##查看
Accepted Keys:
Denied Keys:
Unaccepted Keys:
server2
server3
Rejected Keys:
[root@server1 salt]# salt-key -A ##大A全推送
The following keys are going to be accepted:
Unaccepted Keys:
server2
server3
Proceed? [n/Y] y
Key for minion server2 accepted.
Key for minion server3 accepted.
[root@server1 salt]# salt-key -L ##查看,推送成功
Accepted Keys:
server2
server3
Denied Keys:
Unaccepted Keys:
Rejected Keys:
2.配置
事实上,主从做了个公钥相互交换
[root@server1 salt]# cd pki/
[root@server1 pki]# tree . ##查看树形图,先安装tree
.
|-- master
| |-- master.pem
| |-- master.pub
| |-- minions
| | |-- server2
| | `-- server3
| |-- minions_autosign
| |-- minions_denied
| |-- minions_pre
| `-- minions_rejected
`-- minion
[root@server2 salt]# cd pki/
[root@server2 pki]# tree .
.
|-- master
`-- minion
|-- minion_master.pub
|-- minion.pem
`-- minion.pub
[root@server1 pki]# cd master/
[root@server1 master]# md5sum master.pub ##公钥互换,达成连接
1b729cf3b8c946d8ca939ab7b4487c03 master.pub
[root@server2 pki]# cd minion/
[root@server2 minion]# md5sum minion_master.pub
1b729cf3b8c946d8ca939ab7b4487c03 minion_master.pub
[root@server3 pki]# cd minion/
[root@server3 minion]# md5sum minion_master.pub
1b729cf3b8c946d8ca939ab7b4487c03 minion_master.pub
[root@server1 master]# cd minions
[root@server1 minions]# md5sum server2 ##私钥互换,达成连接
7f76209273baa0c44da8279fd676c2b3 server2
[root@server1 minions]# md5sum server3
9c9bc9557cb7b834417314fb2b4c818b server3
[root@server2 minion]# md5sum minion.pub
7f76209273baa0c44da8279fd676c2b3 minion.pub
[root@server3 minion]# md5sum minion.pub
9c9bc9557cb7b834417314fb2b4c818b minion.pub
[root@server1 minions]# lsof -i :4505 ##查看4505端口工作方式,先安装lsof
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
salt-mast 4070 root 16u IPv4 30018 0t0 TCP *:4505 (LISTEN)
salt-mast 4070 root 18u IPv4 41696 0t0 TCP server1:4505->server3:57003 (ESTABLISHED)
salt-mast 4070 root 19u IPv4 41715 0t0 TCP server1:4505->server2:44099 (ESTABLISHED)
[root@server1 minions]# salt '*' test.ping ##调用python模块,查看ping值
server2:
True
server3:
True
[root@server1 minions]# ps aux ##查看进程,没有名字
[root@server1 minions]# yum install python-setproctitle -y ##安装辅助模块
[root@server1 minions]# /etc/init.d/salt-master restart
[root@server1 minions]# ps aux ##查看进程,有名字
3.推送
1.安装httpd,php
[root@server1 minions]# vim /etc/salt/master ##设定文件目录
file_roots:
base:
- /srv/salt
[root@server1 minions]# mkdir /srv/salt ##创建
[root@server1 minions]# /etc/init.d/salt-master restart
[root@server1 minions]# cd /srv/salt/
[root@server1 salt]# mkdir apache
[root@server1 salt]# cd apache/
[root@server1 apache]# vim web.sls ##写推送文件
apache-install: ##尽量别直接写成apache,有可能会冲突
pkg.installed:
- pkgs:
- httpd
- php
[root@server1 apache]# salt server2 state.sls apache.web test=true ##测试
server2:
----------
ID: apache-install
Function: pkg.installed
Result: None
Comment: The following packages would be installed/updated: httpd, php
Started: 10:47:05.057788
Duration: 373.264 ms
Changes:
Summary for server2
------------
Succeeded: 1 (unchanged=1)
Failed: 0
------------
Total states run: 1
Total run time: 373.264 ms
[root@server1 apache]# vim web.sls ##这样写也可以
httpd:
pkg.installed
php:
pkg.installed
[root@server1 apache]# salt server3 state.sls apache.web test=trueserver3: ##推送测试
----------
ID: httpd
Function: pkg.installed
Result: None
Comment: The following packages would be installed/updated: httpd
Started: 10:48:46.400288
Duration: 292.254 ms
Changes:
----------
ID: php
Function: pkg.installed
Result: None
Comment: The following packages would be installed/updated: php
Started: 10:48:46.692701
Duration: 8.044 ms
Changes:
Summary for server3
------------
Succeeded: 2 (unchanged=2)
Failed: 0
------------
Total states run: 2
Total run time: 300.298 ms
[root@server1 apache]# vim web.sls
apache-install:
pkg.installed:
- pkgs:
- httpd
- php
service.running:
- name: httpd
- enable: true
[root@server1 apache]# salt server2 state.sls apache.web ##推送
server2:
----------
ID: apache-install
Function: pkg.installed
Result: True
Comment: The following packages were installed/updated: httpd, php
Started: 10:52:25.444862
Duration: 16011.029 ms
Changes:
----------
apr:
----------
new:
1.3.9-5.el6_2
old:
apr-util:
----------
new:
1.3.9-3.el6_0.1
old:
apr-util-ldap:
----------
new:
1.3.9-3.el6_0.1
old:
httpd:
----------
new:
2.2.15-29.el6_4
old:
httpd-tools:
----------
new:
2.2.15-29.el6_4
old:
mailcap:
----------
new:
2.1.31-2.el6
old:
php:
----------
new:
5.3.3-26.el6
old:
php-cli:
----------
new:
5.3.3-26.el6
old:
php-common:
----------
new:
5.3.3-26.el6
old:
Summary for server2
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
Total run time: 16.011 s
2.开机自启
[root@server1 apache]# vim web.sls ##设置开机自启动
apache-install:
pkg.installed:
- pkgs:
- httpd
- php
service.running:
- name: httpd
- enable: true
[root@server1 apache]# salt server2 state.sls apache.web ##推送
server3:
----------
ID: apache-install
Function: pkg.installed
Result: True
Comment: All specified packages are already installed
Started: 10:55:28.729848
Duration: 278.117 ms
Changes:
----------
ID: apache-install
Function: service.running
Name: httpd
Result: True
Comment: The service httpd is already running
Started: 10:55:29.008589
Duration: 24.241 ms
Changes:
Summary for server2
------------
Succeeded: 2
Failed: 0
------------
Total states run: 2
Total run time: 302.358 ms
3.reload
[root@server1 apache]# mkdir files
[root@server2 minion]# scp /etc/httpd/conf/httpd.conf server1:/srv/salt/apache/files/ ##发一份配置文件模板
root@server1's password:
httpd.conf 100% 34KB 33.6KB/s 00:00
[root@server1 apache]# vim web.sls ##设置reload重置
apache-install:
pkg.installed:
- pkgs:
- httpd
- php
file.managed:
- name: /etc/httpd/conf/httpd.conf
- source: salt://apache/files/httpd.conf
- user: root
- group: root
- mode: 644
service.running:
- name: httpd
- enable: true
- reload: true
- watch:
- file: apache-install
[root@server1 apache]# /etc/init.d/salt-master restart
[root@server1 apache]# vim files/httpd.conf ##监听更改为8080
Listen 8080
[root@server1 apache]# salt server2 state.sls apache.web test=true ##推送测试
server2:
----------
ID: apache-install
Function: pkg.installed
Result: True
Comment: All specified packages are already installed
Started: 11:04:33.352805
Duration: 361.805 ms
Changes:
----------
ID: apache-install
Function: file.managed
Name: /etc/httpd/conf/httpd.conf
Result: None
Comment: The file /etc/httpd/conf/httpd.conf is set to be changed
Started: 11:04:33.716422
Duration: 65.763 ms
Changes:
----------
diff:
---
+++
@@ -133,7 +133,7 @@
# prevent Apache from glomming onto all bound IP addresses (0.0.0.0)
#
#Listen 12.34.56.78:80
-Listen 80
+Listen 8080
#
# Dynamic Shared Object (DSO) Support
----------
ID: apache-install
Function: service.running
Name: httpd
Result: None
Comment: Service is set to be reloaded
Started: 11:04:33.807884
Duration: 16.241 ms
Changes:
Summary for server2
------------
Succeeded: 3 (unchanged=2, changed=1)
Failed: 0
------------
Total states run: 3
Total run time: 443.809 ms
[root@server1 apache]# salt server2 state.sls apache.web ##推送
server2:
----------
ID: apache-install
Function: pkg.installed
Result: True
Comment: All specified packages are already installed
Started: 11:04:38.713050
Duration: 367.909 ms
Changes:
----------
ID: apache-install
Function: file.managed
Name: /etc/httpd/conf/httpd.conf
Result: True
Comment: File /etc/httpd/conf/httpd.conf updated
Started: 11:04:39.082857
Duration: 106.308 ms
Changes:
----------
diff:
---
+++
@@ -133,7 +133,7 @@
# prevent Apache from glomming onto all bound IP addresses (0.0.0.0)
#
#Listen 12.34.56.78:80
-Listen 80
+Listen 8080
#
# Dynamic Shared Object (DSO) Support
----------
ID: apache-install
Function: service.running
Name: httpd
Result: True
Comment: Service reloaded
Started: 11:04:39.215144
Duration: 59.79 ms
Changes:
----------
httpd:
True
Summary for server2
------------
Succeeded: 3 (changed=2)
Failed: 0
------------
Total states run: 3
Total run time: 534.007 ms
[root@server2 minion]# netstat -antlp | grep 8080 ##查看是否成功
tcp 0 0 :::8080 :::* LISTEN 3804/httpd
推送原理:根据订阅接受,先查看是否变更,再执行
[root@server2 minion]# cd /var/cache/salt/minion/
[root@server2 minion]# tree files/
files/
`-- base
`-- apache
|-- files
| `-- httpd.conf
`-- web.sls
3.nginx自动部署
[root@server1 salt]# mkdir pkgs
[root@server1 salt]# cd pkgs/
[root@server1 pkgs]# vim make.sls ##这个文件解决依赖性
nginx-make: ##名称(任意起)
pkg.installed: ##软件安装
- pkgs: ##安装多个
- gcc
- pcre-devel
- openssl-devel
[root@server1 salt]# mkdir nginx
[root@server1 salt]# cd nginx/
[root@server1 nginx]# mkdir files
[root@server1 files]# ls ##需要有这些东西
nginx nginx-1.14.0.tar.gz nginx.conf ##nginx文件为nginx的启动脚本
[root@server1 nginx]# vim install.sls ##这个文件安装nginx
include: ##包含运行
- pkgs.make
nginx-install:
file.managed: ##文件管理(文件同步操作)
- name: /mnt/nginx-1.14.0.tar.gz ##地址(或者写到第一行当名字,就可以不用这行了)
- source: salt://nginx/files/nginx-1.14.0.tar.gz ##来源
cmd.run: ##cmd执行
- name: cd /mnt && tar zxf nginx-1.14.0.tar.gz && cd nginx-1.14.0 && sed -i.bak 's/#define NGINX_VER "nginx\/" NGINX_VERSION/#define NGINX_VER "nginx"/g' src/core/nginx.h && sed -i.bak 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc &&
./configure --prefix=/usr/local/nginx --with-http_ssl_module --wit
h-http_stub_status_module &> /dev/null && make &> /dev/null && make install &> /dev/null
- creates: /usr/local/nginx/ ##检测/usr/local/nginx文件,有的话不执行,没有监测到再执行
- require:
- pkg: nginx-make
[root@server1 pkgs]# cd ../nginx/
[root@server1 nginx]# vim service.sls ##这个文件管理服务
include:
- nginx.install
- users.add
/usr/local/nginx/conf/nginx.conf:
file.managed:
- source: salt://nginx/files/nginx.conf
nginx-service:
file.managed:
- name: /etc/init.d/nginx
- source: salt://nginx/files/nginx
- mode: 755 ##权限
service.running:
- name: nginx
- enable: true ##开机自启
- reload: true ##重启
- require:
- user: nginx
- watch:
- file: /usr/local/nginx/conf/nginx.conf
[root@server1 salt]# mkdir users
[root@server1 salt]# cd users/
[root@server1 users]# vim add.sls ##这个文件管理用户
nginx:
user.present: ##添加用户
- uid: 800 ##uid指定
- shell: /sbin/nologin ##shell使用
[root@server1 salt]# cd nginx/files/
[root@server1 files]# vim nginx.conf ##改变nginx文件
user nginx nginx;
worker_processes auto;
[root@server1 files]# salt server2 state.sls nginx.install test=true ##测试
[root@server1 files]# salt server2 state.sls nginx.install ##推送
[root@server1 files]# salt server2 state.sls nginx.service test=true ##测试
[root@server1 files]# salt server2 state.sls nginx.service ##推送
2.推送集群
[root@server1 salt]# vim top.sls ##这个文件管理server2和server3的服务
base:
'server2':
- nginx.service
'server3':
- apache.web
[root@server1 salt]# salt '*' state.highstate ##状态推送
[root@server1 salt]# yum install -y salt-minion -y ##server1也当minion
[root@server1 salt]# vim /etc/salt/minion ##更改minion指向
master: 172.25.18.1
[root@server1 salt]# /etc/init.d/salt-minion start
[root@server1 salt]# salt-key -L ##查看节点
Accepted Keys:
server2
server3
Denied Keys:
Unaccepted Keys:
server1
Rejected Keys:
[root@server1 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@server1 salt]# salt-key -L ##查看节点
Accepted Keys:
server1
server2
server3
Denied Keys:
Unaccepted Keys:
Rejected Keys:
[root@foundation66 Desktop]# scp /etc/haproxy/haproxy.cfg server1:/srv/salt/haproxy/files
[root@server1 salt]# mkdir haproxy
[root@server1 salt]# cd haproxy/
[root@server1 haproxy]# mkdir files
[root@foundation66 Desktop]# yum install haproxy -y
[root@server1 haproxy]# 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
- enable: true
- reload: true
- watch:
- file: haproxy-install
[root@server1 haproxy]# cd files/
[root@server1 files]# vim haproxy.cfg
多个推送文件配置
[root@server1 salt]# ls
apache haproxy nginx pkgs top.sls users
[root@server1 salt]# vim top.sls
base:
'server1':
- haproxy.install
'server2':
- nginx.service
'server3':
- apache.web
推送
[root@server1 haproxy]# salt '*' state.highstate ##扫描全局的top.sls,再推送
真机测试
[root@foundation66 Desktop]# curl 172.25.66.1
<h1>server2</h1>
[root@foundation66 Desktop]# curl 172.25.66.1
<h1>server3</h1>
3.saltstack其他命令
1.Grians匹配
[root@server1 files]# salt server2 grains.item ipv4 ##查找server2的ip
server2:
----------
ipv4:
- 127.0.0.1
- 172.25.66.2
[root@server1 files]# salt server2 grains.item ipv6 ##查找server2的ipv6
server2:
----------
ipv6:
- ::1
- fe80::5054:ff:fef1:2f5f
[root@server1 files]# salt server2 grains.item uuid ##查找server2的uuid
server2:
----------
uuid:
b37df222-85e9-4e29-860b-db51b6984ece
[root@server1 files]# salt server2 grains.item os ##查找server2的操作系统
server2:
----------
os:
RedHat
[root@server1 files]# salt -G 'os:RedHat' test.ping ##ping系统为redhat的主机
server1:
True
server2:
True
server3:
True
[root@server1 files]# salt -G 'os:RedHat' cmd.run hostname ##显示系统为redhat的主机名
server3:
server3
server2:
server2
server1:
server1
[root@server1 salt]# salt -G 'os:RedHat' cmd.run 'touch /mnt/lel' ##在操作系统为redhat的主机上/mnt/新建文件lel
[root@server1 salt]# salt -G 'os:RedHat' cmd.run 'ip addr' ##操作系统为redhat的主机上显示执行命令ip addr
[root@server1 salt]# salt -G 'os:RedHat' cmd.run 'ip addr show eth0' ##操作系统为redhat的主机上显示eth0信息
server3是apache服务主机
[root@server3 pki]# vim /etc/salt/minion
120 grains:
121 roles:
122 - apache
[root@server3 pki]# /etc/init.d/salt-minion restart
[root@server2 salt]# vim /etc/salt/minion
120 grains:
121 roles:
122 - nginx
[root@server2 salt]# /etc/init.d/salt-minion restart
看下效果:
[root@server1 files]# salt -G 'roles:nginx' cmd.run hostname ##显示角色为nginx的主机名
server2:
server2
[root@server1 files]# salt -G 'roles:apache' cmd.run hostname ##显示角色为apache的主机名
server3:
server3
[root@server1 files]# salt server2 grains.item roles ##显示server2的角色
server2:
----------
roles:
- nginx
[root@server1 files]# salt server3 grains.item roles ##显示server3的角色
server3:
----------
roles:
- apache
host3 主机vim /etc/salt/grains
[root@server3 pki]# vim /etc/salt/grains
user:
lel
[root@server3 pki]# /etc/init.d/salt-minion restart
测试:
[root@server1 files]# salt server3 grains.item user
server3:
----------
user:
lel
对与master来说
[root@server1 salt]# vim top.sls
base:
'server1':
- haproxy.install
'roles:nginx':
- match: grain
- nginx.service
'roles:apache':
- match: grain
- apache.web
[root@server1 salt]# salt '*' state.highstate
这样也是可以的
3.相对于Grains的静态参数,Pillar可以配置更灵活的参数,熟练地运用Pillar可以十分强大的发挥Saltstack的威力。pillar是动态参数
须自定义minion里的key值(注意此处没有-)
[root@server2 salt]# vim /etc/salt/minion
grains:
roles:
nginx
[root@server3 pki]# vim /etc/salt/minion
grains:
roles:
apache
matser配置pillar工作目录
[root@server1 salt]# mkdir /srv/pillar
[root@server1 salt]# cd /srv/pillar/
[root@server1 pillar]# mkdir web
[root@server1 pillar]# vim web/server.sls
{% if grains['roles'] == 'apache' %}
webserver: apache
{% elif grains['roles'] == 'nginx' %}
webserver: nginx
{% endif %}
[root@server1 pillar]# vim top.sls
base:
'*':
- web.server
[root@server1 pillar]# tree .
.
├── top.sls
└── web
└── server.sls
完成后刷新动态参数
[root@server1 pillar]# salt ‘*’ saltutil.refresh_pillar
server1:
True
server3:
True
server2:
True
测试
server3:
———-
webserver:
apache
server2:
———-
webserver:
nginx
server1:
———-
webserver:
上边的/srv/pillar/web/server.sls可以写成这样
[root@server1 pillar]# vim web/server.sls
{% if grains['fqdn'] == 'server3' %}
webserver: apache
{% elif grains['fqdn'] == 'server2' %}
webserver: nginx
{% endif %}
刷新测试下
[root@server1 pillar]# salt '*' saltutil.refresh_pillar
server3:
True
server2:
True
server1:
True
[root@server1 pillar]# salt '*' pillar.item webserver
server2:
----------
webserver:
nginx
server3:
----------
webserver:
apache
server1:
----------
webserver:
4.一些命令
[root@server2 pillar]# salt 'host3' service.get_all ##查看host3开启的所有服务
[root@server2 pillar]# salt 'server2' service.start nginx ## 启动server2的nginx
[root@server2 pillar]# salt 'server2' service.stop nginx ## 关闭server2的nginx
[root@server2 ~]# salt-cp '*' /etc/passwd /tmp/ ##复制/etc/passwd 到所有节点/tmp下
[root@server2 ~]# salt '*' cmd.run 'rm -fr /tmp/passwd' ##删除所有节点/tmp/passwd
[root@server2 ~]# salt '*' state.show_top ##查看最近动过的服务
[root@server2 ~]# salt '*' state.single pkg.installed tree ##所有node安装tree
[root@server1 ~]# salt-run jobs.list_jobs ##查看最近执行的命令
5.执行命令的查看,保存,执行结果状态
1.minion端会给master和数据库主机发份return
这里把数据库安装在server1上,你也可以装在其他主机上上不要紧
[root@server1 ~]# yum install mysql-server -y
[root@server1 ~]# /etc/init.d/mysqld start
[root@server1 ~]# mysql_secure_installation
[root@server1 ~]# mysql -p < test.sql ##把准备好的sql文件导进去
Enter password:
[root@server1 ~]# mysql -pwestos
mysql> grant all on salt.* to salt@'%' identified by 'westos'; ##授权
其中一minion节点server2安装python-MYSQL模块,配置minion文件
[root@server2 ~]# yum install MySQL-python -y
[root@server2 ~]# vim /etc/salt/minion
810 #return:
811 # - mysql
812 # - hipchat
813 # - slack
814
815 mysql.host: '172.25.66.1'
816 mysql.user: 'salt'
817 mysql.pass: 'westos'
818 mysql.db: 'salt'
819 mysql.port: '3306'
[root@server2 ~]# /etc/init.d/salt-minion restart
在master上执行条命令
[root@server1 ~]# salt 'server2' test.ping --return mysql
server2:
True
[root@server1 ~]# mysql -h 172.25.66.1 -u salt -pwestos
mysql> select * from salt.salt_returns;
+-----------+----------------------+--------+---------+---------+-------------------------------------------------------------------------------------------------------------------------------------+---------------------+
| fun | jid | return | id | success | full_ret | alter_time |
+-----------+----------------------+--------+---------+---------+-------------------------------------------------------------------------------------------------------------------------------------+---------------------+
| test.ping | 20180522023218732091 | true | server2 | 1 | {"fun_args": [], "jid": "20180522023218732091", "return": true, "retcode": 0, "success": true, "fun": "test.ping", "id": "server2"} | 2018-05-22 02:32:18 |
+-----------+----------------------+--------+---------+---------+-------------------------------------------------------------------------------------------------------------------------------------+---------------------+
2.设置返还给master,不给数据库,由matser去发送给数据库
[root@server1 ~]# vim /etc/salt/master
1057 #return: mysql
1058
1059 master_job_cache: mysql
1060
1061 mysql.host: '172.25.66.1'
1062 mysql.user: 'salt'
1063 mysql.pass: 'westos'
1064 mysql.db: 'salt'
1065 mysql.port: 3306
[root@server1 ~]# /etc/init.d/salt-master restart
因为上边这个写法导致无法重启salt-master服务,只好每行空一格,如下图得以启动服务,至于原因尚且不只
[root@server1 ~]# vim /etc/salt/master
1057 #return: mysql
1058
1059 master_job_cache: mysql
1060
1061 mysql.host: '172.25.66.1'
1062 mysql.user: 'salt'
1063 mysql.pass: 'westos'
1064 mysql.db: 'salt'
1065 mysql.port: 3306
MySQL-python这个模块要装在master上
[root@server1 ~]# yum install MySQL-python -y
[root@server1 ~]# salt server3 cmd.run 'df -h' ##作出动作
server3:
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root 7.5G 988M 6.2G 14% /
tmpfs 246M 16K 246M 1% /dev/shm
/dev/vda1 485M 33M 427M 8% /boot
[root@foundation66 Desktop]# mysql -h 172.25.66.1 -u salt -pwestos ##登陆数据库查看
MySQL [(none)]> select * from salt.salt_returns; ##会显示出数据结果
6.自定义模块
编写自己的模块远程执行
[root@server1 ~]# mkdir /srv/salt/_modules ##必须是这个名字_modules ,否则无法同步
[root@server1 ~]# cd /srv/salt/_modules
[root@server1 _modules]# vim my_disk.py
#!/usr/bin/env python
def df():
cmd = 'df -H'
return __salt__['cmd.run'](cmd)
同步这个模块到server3
[root@server1 _modules]# salt server3 saltutil.sync_modules
server3:
- modules.my_disk
server3查看该模块
[root@server3 ~]# cd /var/cache/salt/minion/
[root@server3 minion]# tree .
.
├── accumulator
├── extmods
│ └── modules
│ └── my_disk.py
├── files
│ └── base
│ ├── apache
│ │ ├── files
│ │ │ └── httpd.conf
│ │ └── web.sls
│ ├── _modules
│ │ └── my_disk.py ##自定义模块在这里
│ └── top.sls
├── highstate.cache.p
├── module_refresh
├── pkg_refresh
├── proc
└── sls.p
执行同步过去的模块
[root@server1 _modules]# salt server3 my_disk.df
server3:
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root 8.1G 1.1G 6.6G 14% /
tmpfs 258M 17k 258M 1% /dev/shm
/dev/vda1 508M 35M 448M 8% /boot
7.jinja模块
这里实例httpd服务
1.简单设置
[root@server1 _modules]# cd /srv/salt/apache/
[root@server1 apache]# tree .
.
├── files
│ └── httpd.conf
└── web.sls
调用jinja模块
[root@server1 apache]# vim web.sls
apache-install:
pkg.installed:
- pkgs:
- httpd
- php
file.managed:
- name: /etc/httpd/conf/httpd.conf
- source: salt://apache/files/httpd.conf
- user: root
- group: root
- mode: 644
- template: jinja ##在这里
- context:
PORT: 8080
IP: 172.25.66.2
service.running:
- name: httpd
- enable: true
- reload: true
- watch:
- file: apache-install
配置文件引用
[root@server1 apache]# vim files/httpd.conf
... ##省略多行
Listen {{ IP }}:{{ PORT }} ##就这行引用,固定格式
... ##省略多行
为了实验效果,直接从server3上remove httpd
[root@server3 minion]# yum remove httpd -y
推送
[root@server1 apache]# salt server3 state.sls apache.web
...
-Listen 80
+Listen 172.25.66.3:8080 ##这里实现了引用
...
server3查看下80端口
[root@server3 minion]# netstat -antlp | grep 8080
tcp 0 0 172.25.66.3:8080 0.0.0.0:* LISTEN 2081/httpd
2.全局引用(优先级高)
[root@server1 apache]# pwd
/srv/salt/apache
[root@server1 apache]# vim files/lib.sls
{% set PORT= 80 %}
{% set IP = '172.25.66.2' %}
[root@server1 apache]# tree .
.
├── files
│ ├── httpd.conf
│ └── lib.sls
└── web.sls
http主配置文件
[root@server1 apache]# vim files/httpd.conf
{% from 'apache/files/lib.sls' import PORT with context %} ##写在第一行第一行
... ##省略
Listen {{ IP }}:{{ PORT }}
... ##省略
推送
[root@server1 apache]# salt server3 state.sls apache.web
...
#Listen 12.34.56.78:80
-Listen 172.25.66.3:8080
+Listen 172.25.66.3:80 ##改回来了
...
server3查看下端口
[root@server3 minion]# netstat -antlp | grep 80
tcp 0 0 172.25.66.3:80 0.0.0.0:* LISTEN 2081/httpd
3.变量的定义静态grain
{% from 'apache/files/lib.sls' import PORT with context %}
...
Listen {{ grains['ipv4'][1] }}:{{ PORT }} ##改成这种格式
...
之前用的80端口,这里该为8080
{% set PORT= 8080 %}
{% set IP = '172.25.66.3' %}
推送
[root@server1 apache]# salt server3 state.sls apache.web
...
#Listen 12.34.56.78:80
-Listen 172.25.66.3:80
+Listen 172.25.66.3:8080 ##改回来了
...
server3查看
[root@server3 minion]# netstat -antlp | grep 8080
tcp 0 0 172.25.66.3:8080 0.0.0.0:* LISTEN 2479/httpd
4.变量的定义动态参数pillar
[root@server1 apache]# vim /srv/pillar/web/server.sls
{% if grains['fqdn'] == 'server3' %}
webserver: apache
IP: 172.25.66.3
PORT: 80
{% elif grains['fqdn'] == 'server2' %}
webserver: nginx
IP: 172.25.66.2
PORT: 80
{% endif %}
[root@server1 apache]# vim /srv/salt/apache/files/httpd.conf
{% from 'apache/files/lib.sls' import PORT with context %}
...
Listen {{ pillar['IP'] }}:{{ pillar['PORT'] }}
...
推送
[root@server1 apache]# salt server3 state.sls apache.web
...
#Listen 12.34.56.78:80
-Listen 172.25.66.3:8080
+Listen 172.25.66.3:80
...
5.变量的另一种定义
[root@server1 apache]# vim web.sls
apache-install:
pkg.installed:
- pkgs:
- httpd
- php
file.managed:
- name: /etc/httpd/conf/httpd.conf
- source: salt://apache/files/httpd.conf
- user: root
- group: root
- mode: 644
- template: jinja
- context:
PORT: {{ pillar['PORT'] }}
IP: {{ pillar['IP'] }}
service.running:
- name: httpd
- enable: true
- reload: true
- watch:
- file: apache-install
推送,事实上这个时候files/http.conf的第一行定义已经无关紧要了,当你变动/srv/pillar/web/server.sls里边的参数时,推送会随之改变
8.源码包推送keepalived
[root@server1 salt]# mkdir keepalived
[root@server1 salt]# cd keepalived/
[root@server1 keepalived]# mkdir files
[root@server1 files]# ls files/
keepalived-1.4.3.tar.gz
[root@server1 keepalived]# vim install.sls
{% set version = '1.4.3' %}
keepalived-install:
file.managed:
- name: /mnt/keepalived-{{version}}.tar.gz
- source: salt://keepalived/files/keepalived-{{version}}.tar.gz
cmd.run:
- name: cd /mnt && yum install gcc openssl-devel -y &>/dev/null && tar zxf keepalived-{{version}}.tar.gz && cd keepalived-{{version}} && ./configure --prefix=/usr/local/keepalived --with-init=SYSV &>/dev/null && make &>/dev/null && make install &>/dev/null
- creates: /usr/local/keepalived
[root@server1 keepalived]# salt server3 state.sls keepalived.install ##先推送过去检查是否有问题,获取配置文件
[root@server3 ~]# scp /usr/local/keepalived/etc/keepalived/keepalived.conf server1:/srv/salt/keepalived/files ##配置文件
[root@server3 ~]# scp /usr/local/keepalived/etc/rc.d/init.d/keepalived server1:/srv/salt/keepalived/files ##脚本
接着继续写install.sls
[root@server1 keepalived]# vim install.sls
{% set version = '1.4.3' %}
keepalived-install:
file.managed:
- name: /mnt/keepalived-{{version}}.tar.gz
- source: salt://keepalived/files/keepalived-{{version}}.tar.gz
cmd.run:
- name: cd /mnt && yum install gcc openssl-devel -y &>/dev/null && tar zxf keepalived-{{version}}.tar.gz && cd keepalived-{{version}} && ./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
/sbin/keepalived:
file.symlink:
- target: /usr/local/keepalived/sbin/keepalived
/etc/init.d/keepalived:
file.managed:
- source: salt://keepalived/files/keepalived
- mode: 755
编写keepalived.conf
只是简单的高可用,并没有配置负载均衡
[root@server1 keepalived]# vim files/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
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 MASTER
interface eth0
virtual_router_id {{VRID}}
priority {{PRIORITY}}
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.66.3
}
}
静态参数
[root@server1 keepalived]# vim /srv/pillar/web/server.sls
{% if grains['fqdn'] == 'server3' %}
webserver: apache
IP: 172.25.66.3
PORT: 80
STATE: MASTER
VRID: 250
PRIORITY: 100
{% elif grains['fqdn'] == 'server2' %}
webserver: nginx
IP: 172.25.66.2
PORT: 80
STATE: BACKUP
VRID: 250
PRIORITY: 50
{% endif %}
编写启动文件
[root@server1 keepalived]# vim server.sls
include:
- keepalived.install
keepalived-service:
file.managed:
- name: /etc/keepalived/keepalived.conf
- source: salt://keepalived/files/keepalived.conf
- template: jinja
- context:
STATE: {{pillar['STATE']}}
VRID: {{pillar['VRID']}}
PRIORITY: {{pillar['PRIORITY']}}
service.running:
- name: keepalived
- enable: true
- reload: true
- watch:
- file: keepalived-service
编写批量推送文件
[root@server1 keepalived]# cd ..
[root@server1 salt]# vim top.sls
base:
'server2':
- keepalived.server
'server3':
- keepalived.server
批量推送
[root@server1 salt]# salt '*' state.highstate
期间会报错server1失败,没关系,top.sls里边就没定义server1推什么,主机多的话可以使用正则:比如:
salt server[2-3] state.highstate
salt server[2,3] state.highstate等
回头检查下,ps ax 查看server3进程keepalived启动,因为它为master,vip自然在它那;同样server2进程中也有keepalived,ok实验成功
[root@server3 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 52:54:00:cf:47:93 brd ff:ff:ff:ff:ff:ff
inet 172.25.66.3/24 brd 172.25.66.255 scope global eth0
inet 172.25.66.3/32 scope global eth0
inet6 fe80::5054:ff:fecf:4793/64 scope link
valid_lft forever preferred_lft forever
9.Salt Syndic,syndic的意思为理事,其实如果叫salt-proxy的话那就更好理解了,它就是一层代理,如同zabbix proxy功能一样,隔离master与minion,使其不需要通讯,只需要与syndic都通讯就可以,这样的话就可以在跨机房的时候将架构清晰部署了
基于上述实验:salt-matser为server1,salt-minion为server2和server3,salt为top-master
[root@server1 salt]# /etc/init.d/salt-minion stop
Stopping salt-minion:root:server1 daemon: OK
[root@server1 salt]# chkconfig salt-minion off
[root@server1 salt]# 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 salt]# salt-key -L
Accepted Keys:
server2
server3
Denied Keys:
Unaccepted Keys:
Rejected Keys:
安装salt-syndic
[root@server1 salt]# yum install salt-syndic -y ##一般salt-syndic部署在salt-master上
配置master文件指向top-master
[root@server1 salt]# vim /etc/salt/master
862 syndic_master: 172.25.66.4
[root@server1 salt]# /etc/init.d/salt-master restart
top-master安装salt-master(server4:ip 172.25.66.4)
[root@server4 ~]# yum install salt-master -y
[root@server4 ~]# vim /etc/salt/master
534 file_roots:
535 base:
536 - /srv/salt
694 pillar_roots:
695 base:
696 - /srv/pillar
858 order_masters: True
[root@server4 ~]# /etc/init.d/salt-master start
top-master关联server1
如果不显示server1,重启server1的salt-master和salt-syndic服务
[root@server4 ~]# salt-key -L
Accepted Keys:
Denied Keys:
Unaccepted Keys:
server1
Rejected Keys:
添加server1
[root@server4 ~]# salt-key -a server1
The following keys are going to be accepted:
Unaccepted Keys:
server1
Proceed? [n/Y] y
Key for minion server1 accepted.
server4测试一下
这里有坑,ping如果告诉你没反映,重启server1的salt-master和salt-syndic服务,注意报错,可能需要reboot,完成后还没响应,尝试用server1去平两台minion,如果不同,重启两个minion结点的的salt-minion服务
[root@server4 ~]# salt '*' test.ping
server2:
True
server3:
True
这个时候可以执行任务了比如
[root@server4 ~]# salt '*' cmd.run df
server2:
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/VolGroup-lv_root 7853764 1098452 6356364 15% /
tmpfs 251124 64 251060 1% /dev/shm
/dev/vda1 495844 33473 436771 8% /boot
server3:
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/VolGroup-lv_root 7853764 1083764 6371052 15% /
tmpfs 251124 16 251108 1% /dev/shm
/dev/vda1 495844 33473 436771 8% /boot
10:salt-ssh串行
server1安装salt-ssh
[root@server1 salt]# yum install salt-ssh -y
[root@server1 salt]# vim /etc/salt/roster
server2:
host: 172.25.66.2
user: root
passwd: westos
完成后直接测试
[root@server1 salt]# salt-ssh server2 test.ping -i
server2:
True
成功了,但是你会看见很多报错,别忘记了master文件里边配置了数据库,而数据库链接不到,要么注释掉数据库参数,要么启用数据库并且给root授权远程登陆,-i非交互式
11.api
安装api服务
[root@server1 salt]# yum install salt-api -y
[root@server1 salt]# cd /etc/pki/tls/private
[root@server1 private]# openssl genrsa 2048 >localhost.key
Generating RSA private key, 2048 bit long modulus
.......................................................................................+++
.................................+++
e is 65537 (0x10001)
[root@server1 private]# cd /etc/pki/tls/certs/
[root@server1 certs]# make testcert ##填写各种信息
...
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:shannxi
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) []:server1
Email Address []:root@localhost
完成后主配置文件修改
[root@server1 certs]# vim /etc/salt/master
12 default_include: master.d/*.conf ##取消注释
[root@server1 certs]# /etc/init.d/salt-master restart
添加用户设置密码westos
[root@server1 certs]# useradd saltapi
[root@server1 certs]# passwd saltapi
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 certs]# cd /etc/salt/master.d/
[root@server1 master.d]# vim eauth.conf
external_auth:
pam:
saltapi:
- .*
- '@wheel'
- '@runner'
- '@jobs'
[root@server1 master.d]# vim api.conf
rest_cherrypy:
host: 172.25.66.1
port: 8000
ssl_crt: /etc/pki/tls/certs/localhost.crt
ssl_key: /etc/pki/tls/private/localhost.key
[root@server1 master.d]# /etc/init.d/salt-api start
查看下api端口8000要开启
[root@server1 master.d]# netstat -anltpp | grep 8000
接着获取token
[root@server1 master.d]# curl -sSk https://172.25.66.1:8000/login -H 'Accept: application/x-yaml' -d username=saltapi -d password=westos -d eauth=pam
测试
[root@server1 master.d]# curl -sSk https://172.25.66.1:8000 -H 'Accept: application/x-yaml' -H 'X-Auth-Token: 14fbf0df3dc393508849c21ba98c1b6b3d1cc44a' -d client=local -d tgt='*' -d fun=test.ping
写各api接口脚本
[root@server1 master.d]# vim saltapi.py
#!/usr/bin/env python
# -*- 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.66.1:8000',username='saltapi',password='westos')
sapi.token_id()
print sapi.list_all_key() ##测试
#sapi.delete_key('test-01') ##删除key
#sapi.accept_key('test-01') ##添加key
#sapi.deploy('*','apache.http') ##推送
#print sapi.remote_noarg_execution('test-01','grains.items')
if __name__ == '__main__':
main()
给server2推送http服务
修改脚本如下图
执行./saltapi.py
去server3上看看是否成功