1. 主机规划
服务器名称 | 操作系统版本 | 内网IP | 外网IP(模拟) | Hostname | 部署模块 |
---|---|---|---|---|---|
salt100 | CentOS7.5 | 172.16.1.100 | 10.0.0.100 | salt100 | salt-master、salt-minion |
salt01 | CentOS7.5 | 172.16.1.11 | 10.0.0.11 | salt01 | salt-minion |
salt02 | CentOS7.5 | 172.16.1.12 | 10.0.0.12 | salt02 | salt-minion |
salt03 | CentOS7.5 | 172.16.1.13 | 10.0.0.13 | salt03 | salt-minion |
salt 版本
[root@salt100 ~]# salt --version
salt 2018.3.3 (Oxygen)
[root@salt100 ~]# salt-minion --version
salt-minion 2018.3.3 (Oxygen)
netapi modules
https://docs.saltstack.com/en/latest/ref/netapi/all/index.html
rest_cherrypy
https://docs.saltstack.com/en/latest/ref/netapi/all/salt.netapi.rest_cherrypy.html
文章参考:
参考GitHub
https://github.com/yueyongyue/saltshaker
2. 必要的准备
2.1. 安装部署Python3
[root@salt100 Python-3.7.3]# yum install -y libffi-devel # 提前安装
[root@salt100 Python-3.7.3]# pwd
/root/software/
[root@salt100 software]# ll
total 22436
-rw-r--r-- 1 root root 22973527 Apr 1 00:15 Python-3.7.3.tgz
[root@salt100 software]# tar xf Python-3.7.3.tgz
[root@salt100 software]# cd Python-3.7.3/
[root@salt100 Python-3.7.3]# ./configure # 配置
[root@salt100 Python-3.7.3]# make && make install # 编译 与 安装
# 建立软连接
[root@salt100 ~]# ln -s /usr/local/bin/python3.7 /usr/bin/python3
[root@salt100 ~]# ll /usr/bin/python3
lrwxrwxrwx 1 root root 24 Apr 1 20:33 /usr/bin/python3 -> /usr/local/bin/python3.7
2.2. 安装salt-api
等到配置完毕后才能启动salt-api
[root@salt100 ~]# yum install -y salt-api
[root@salt100 ~]# systemctl enable salt-api.service # 开机自启动
2.3. 新建saltapi用户
[root@salt100 ~]# useradd -M -s /sbin/nologin -u 1010 saltapi && echo '123456' | /usr/bin/passwd --stdin saltapi
2.4. 安装pip和CherryPy
[root@salt100 software]# wget https://bootstrap.pypa.io/get-pip.py
[root@salt100 software]# python3 get-pip.py
[root@salt100 software]# pip -V # 查看pip版本
[root@salt100 software]# pip install CherryPy==3.2.6 # 注意版本
3. 添加https证书
[root@salt100 certs]# pwd
/etc/pki/tls/certs
[root@salt100 certs]# ll
total 12
lrwxrwxrwx. 1 root root 49 Nov 14 05:41 ca-bundle.crt -> /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
lrwxrwxrwx. 1 root root 55 Nov 14 05:41 ca-bundle.trust.crt -> /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
-rwxr-xr-x. 1 root root 610 Apr 11 2018 make-dummy-cert
-rw-r--r--. 1 root root 2516 Apr 11 2018 Makefile
-rwxr-xr-x. 1 root root 829 Apr 11 2018 renew-dummy-cert
[root@salt100 certs]# make testcert
umask 77 ; \
/usr/bin/openssl genrsa -aes128 2048 > /etc/pki/tls/private/localhost.key
Generating RSA private key, 2048 bit long modulus
.........................................................................+++
........................+++
e is 65537 (0x10001)
Enter pass phrase: # 键入加密短语
Verifying - Enter pass phrase: # 确认加密短语
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
Enter pass phrase for /etc/pki/tls/private/localhost.key: # 再次输入相同的加密短语
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]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:
[root@salt100 certs]# ll
total 16
lrwxrwxrwx. 1 root root 49 Nov 14 05:41 ca-bundle.crt -> /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
lrwxrwxrwx. 1 root root 55 Nov 14 05:41 ca-bundle.trust.crt -> /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
-rw------- 1 root root 1220 Mar 31 22:53 localhost.crt
-rwxr-xr-x. 1 root root 610 Apr 11 2018 make-dummy-cert
-rw-r--r--. 1 root root 2516 Apr 11 2018 Makefile
-rwxr-xr-x. 1 root root 829 Apr 11 2018 renew-dummy-cert
[root@salt100 certs]# cd /etc/pki/tls/private/ # 进入目录
[root@salt100 private]# ll
total 4
-rw------- 1 root root 1766 Mar 31 22:52 localhost.key
[root@salt100 private]# openssl rsa -in localhost.key -out localhost_nopass.key # 生成无密码秘钥
Enter pass phrase for localhost.key: # 输入和之前一样的加密短语
writing RSA key
[root@salt100 private]# ll
total 8
-rw------- 1 root root 1766 Mar 31 22:52 localhost.key
-rw-r--r-- 1 root root 1679 Mar 31 22:56 localhost_nopass.key
4. 添加配置文件
配置文件存放位置
[root@salt100 ~]# vim /etc/salt/master
##### Primary configuration settings #####
##########################################
# This configuration file is used to manage the behavior of the Salt Master.
# Values that are commented out but have an empty line after the comment are
# defaults that do not need to be set in the config. If there is no blank line
# after the comment then the value is presented as an example and is not the
# default.
# Per default, the master will automatically include all config files
# from master.d/*.conf (master.d is a directory in the same directory
# as the main master config file).
#default_include: master.d/*.conf # 默认配置即可
…………
添加配置文件
[root@salt100 master.d]# pwd
/etc/salt/master.d
[root@salt100 master.d]# ll
total 8
-rw-r--r-- 1 root root 126 Mar 31 23:29 api.conf
-rw-r--r-- 1 root root 239 Mar 31 23:38 eauth.conf
[root@salt100 master.d]# cat eauth.conf
external_auth:
pam:
saltapi:
- .*
- '@wheel' # to allow access to all wheel modules
- '@runner' # to allow access to all runner modules
- '@jobs' # to allow access to the jobs runner and/or wheel module
[root@salt100 master.d]# cat api.conf
rest_cherrypy:
port: 8000
ssl_crt: /etc/pki/tls/certs/localhost.crt
ssl_key: /etc/pki/tls/private/localhost_nopass.key
5. 重启salt-master
[root@salt100 ~]# systemctl restart salt-master.service # 使配置生效
6. 启动salt-api
[root@salt100 master.d]# systemctl start salt-api.service
[root@salt100 ~]# netstat -lntup | grep 'salt' # 端口查看
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 22078/salt-api
tcp 0 0 0.0.0.0:4505 0.0.0.0:* LISTEN 19802/salt-master Z
tcp 0 0 0.0.0.0:4506 0.0.0.0:* LISTEN 19808/salt-master M
7. 使用PAM进行登录验证
[root@salt100 master.d]# curl -k https://172.16.1.100:8000/login \
-H 'Accept: application/x-yaml' \
-d username='saltapi' \
-d password='123456' \
-d eauth='pam'
return:
- eauth: pam
expire: 1554173316.621825
perms:
- .*
- '@wheel'
- '@runner'
- '@jobs'
start: 1554130116.621824
token: 6bb11fd17c3476cb7d07373113c93faaa9c27f9a
user: saltapi
这个token使我们需要的,方便后文操作
8. 得到指定minion的grains信息
[root@salt100 master.d]# curl -k https://172.16.1.100:8000/minions/salt01 \
-H 'Accept: application/x-yaml' \
-H 'X-Auth-Token: 6bb11fd17c3476cb7d07373113c93faaa9c27f9a'
## 返回如下信息
return:
- salt01:
SSDs: []
biosreleasedate: 05/19/2017
biosversion: '6.00'
cpu_flags:
………………
9. 获取minion状态【上下线状态】
## 备注: client='runner' 代表在master执行 client='local' 代表在minion执行
[root@salt100 ~]# curl -k https://172.16.1.100:8000/ \
-H 'Accept: application/x-yaml' \
-H 'X-Auth-Token: 6bb11fd17c3476cb7d07373113c93faaa9c27f9a' \
-d client='runner' \
-d fun='manage.status'
## 返回如下信息
return:
- down: []
up:
- salt01
- salt02
- salt03
- salt100
10. test.ping测试
curl -k https://172.16.1.100:8000 \
-H 'Accept: application/x-yaml' \
-H 'X-Auth-Token: 6bb11fd17c3476cb7d07373113c93faaa9c27f9a'\
-d client=local \
-d tgt='*' \
-d fun=test.ping
## 返回如下信息
return:
- salt01: true
salt02: true
salt03: true
salt100: true
11. 查看jobs信息
在标签1执行
[root@salt100 ~]# salt 'salt01' cmd.run 'whoami && sleep 300'
在标签2执行
[root@salt100 ~]# curl -k https://172.16.1.100:8000/jobs \
> -H 'Accept: application/x-yaml' \
> -H 'X-Auth-Token: 6bb11fd17c3476cb7d07373113c93faaa9c27f9a'
return:
- '20190401225621862530':
Arguments: []
Function: test.ping
StartTime: 2019, Apr 01 22:56:21.862530
Target: '*'
Target-type: glob
User: sudo_yun
'20190401232000770358':
Arguments: []
Function: test.ping
StartTime: 2019, Apr 01 23:20:00.770358
Target: '*'
Target-type: glob
User: saltapi
'20190401232353892493':
Arguments:
- whoami && sleep 300
Function: cmd.run
StartTime: 2019, Apr 01 23:23:53.892493
Target: salt01
Target-type: glob
User: sudo_yun
'20190401232358925816':
Arguments:
- '20190401232353892493'
Function: saltutil.find_job
StartTime: 2019, Apr 01 23:23:58.925816
Target:
- salt01
Target-type: list
User: sudo_yun
'20190401232406139505':
Arguments: []
Function: saltutil.running
StartTime: 2019, Apr 01 23:24:06.139505
Target: '*'
Target-type: glob
User: root
'20190401232408955596':
Arguments:
- '20190401232353892493'
Function: saltutil.find_job
StartTime: 2019, Apr 01 23:24:08.955596
Target:
- salt01
Target-type: list
User: sudo_yun
'20190401232418970482':
Arguments:
- '20190401232353892493'
Function: saltutil.find_job
StartTime: 2019, Apr 01 23:24:18.970482
Target:
- salt01
Target-type: list
User: sudo_yun
[root@salt100 ~]#
[root@salt100 ~]# curl -k https://172.16.1.100:8000/jobs/20190401232353892493 \
-H 'Accept: application/x-yaml' \
-H 'X-Auth-Token: 6bb11fd17c3476cb7d07373113c93faaa9c27f9a'
## 返回如下信息
info:
- Arguments:
- whoami && sleep 300
Function: cmd.run
Minions:
- salt01
Result: {}
StartTime: 2019, Apr 01 23:23:53.892493
Target: salt01
Target-type: glob
User: sudo_yun
jid: '20190401232353892493'
return:
- {}
12. 其他常用操作
# salt 'salt01' state.sls web.apache ,执行 apache.sls # yum 部署httpd
curl -k https://172.16.1.100:8000/ \
-H 'Accept: application/x-yaml' \
-H 'X-Auth-Token: 6bb11fd17c3476cb7d07373113c93faaa9c27f9a' \
-d client=local \
-d tgt='salt01' \
-d fun=state.sls \
-d arg='web.apache'
# salt -L 'salt01,salt02,salt03' test.ping
curl -k https://172.16.1.100:8000 \
-H 'Accept: application/x-yaml' \
-H 'X-Auth-Token: 6bb11fd17c3476cb7d07373113c93faaa9c27f9a'\
-d client=local \
-d tgt='salt01,salt02,salt03' \
-d expr_form='list' \
-d fun=test.ping
# salt -G 'host:salt01' cmd.run ifconfig
curl -k https://172.16.1.100:8000 \
-H 'Accept: application/x-yaml' \
-H 'X-Auth-Token: 6bb11fd17c3476cb7d07373113c93faaa9c27f9a'\
-d client=local \
-d tgt='host:salt01' \
-d expr_form='grain' \
-d fun=cmd.run \
-d arg='ifconfig'
# 以json格式输出
# salt -G 'host:salt01' cmd.run ifconfig
curl -k https://172.16.1.100:8000 \
-H 'Accept: application/json' \
-H 'X-Auth-Token: 6bb11fd17c3476cb7d07373113c93faaa9c27f9a'\
-d client=local \
-d tgt='host:salt01' \
-d expr_form='grain' \
-d fun=cmd.run \
-d arg='ifconfig'
13. 参数解释
client : 模块,python处理salt-api的主要模块,‘client interfaces <netapi-clients>’
local : 使用‘LocalClient <salt.client.LocalClient>’ 发送命令给受控主机,等价于saltstack命令行中的'salt'命令
local_async : 和local不同之处在于,这个模块是用于异步操作的,即在master端执行命令后返回的是一个jobid,任务放在后台运行,通过产看jobid的结果来获取命令的执行结果。
runner : 使用'RunnerClient<salt.runner.RunnerClient>' 调用salt-master上的runner模块,等价于saltstack命令行中的'salt-run'命令
runner_async : 异步执行runner模块
wheel : 使用'WheelClient<salt.wheel.WheelClient>', 调用salt-master上的wheel模块,wheel模块没有在命令行端等价的模块,但它通常管理主机资源,比如文件状态,pillar文件,salt配置文件,以及关键模块<salt.wheel.key>功能类似于命令行中的salt-key。
wheel_async : 异步执行wheel模块
备注:一般情况下local模块,需要tgt和arg(数组),kwarg(字典),因为这些值将被发送到minions并用于执行所请求的函数。而runner和wheel都是直接应用于master,不需要这些参数。
tgt : minions
fun : 函数
arg : 参数
expr_form : tgt的匹配规则
'glob' - Bash glob completion - Default
'pcre' - Perl style regular expression
'list' - Python list of hosts
'grain' - Match based on a grain comparison
'grain_pcre' - Grain comparison with a regex
'pillar' - Pillar data comparison
'nodegroup' - Match on nodegroup
'range' - Use a Range server for matching
'compound' - Pass a compound match string