一、简介
Saltstack 是基于Python 开发的,也是基于 C/S 架构,服务端 master 和客户端 minions ;Saltstack 和 Puppet 很像,可以说 Saltstatck 整合了 Puppet 和 Chef 的功能,更加强大,更适合大规模批量管理服务器,并且它比 Puppet 更容易配置。
三大功能: 远程命令执行,配置管理(服务,文件,cron,用户,组),云管理。
支持系统:大多数系统都支持,windows 上不支持安装 master。
二、安装配置
1、准备工作
本实验是在CentOS7.8上做的,准备两台机器,关闭防火墙firewalld并清空规则,关闭selinux
服务端 | 192.168.33.123 |
---|---|
客户端 | 192.168.33.124 |
#systemctl stop firewalld #关闭防火墙
#systemctl disable firewalld #清除防火墙规则,禁用开机自启
#setenforce 0 #关闭selinux
2、修改主机名并编辑 hosts 文件
修改主机名并把主机名追加至/etc/sysconfig/network
文件中
#hostnamectl set-hostname test1 #修改master端主机名为test1
#echo "HOSTNAME=test1" >> /etc/sysconfig/network #在主机test1上做
#hostnamectl set-hostname test2 #修改minion端主机名为test2
#echo "HOSTNAME=test2" >> /etc/sysconfig/network #在主机test2上做
编辑/etc/hosts
文件,添加IP与主机名的映射关系,如果机器太多,可以搭建DNS,这样就不用每台机器都做
#echo "192.168.33.123 test1" >> /etc/hosts
#echo "192.168.33.124 test2" >> /etc/hosts
3、安装
(1)服务端安装
#yum -y install epel-release #配置额外的软件包源,服务器端和客户端都要先配置好源才能顺利安装salt
#yum -y install https://repo.saltstack.com/yum/redhat/salt-repo-latest-2.el7.noarch.rpm #配置最新版本的salt源
#yum clean all && yum makecache #重新建立yum源缓存
#yum -y install python-crypto
#yum -y install salt-master salt-minion #服务器端test1安装master和minion,可以不装minion,但是为了salt能管理本机,顺便看看实验效果,建议安装
(2)客户端安装
按照上面的源配置方法配置好yum源,配置好后,直接执行下面的安装指令,客户端只需要安装minion
#yum -y install salt-minion
4、配置
服务端和客户端都要配置 master
# vim /etc/salt/minion #在第16行添加
master: 192.168.33.123 #注意冒号后有一个空格
5、启动服务
(1)服务端
# /etc/init.d/salt-master start #启动master
# /etc/init.d/salt-minion start #启动minion
或者
#salt-master -d #启动并后台运行
#salt-minion -d #启动并后台运行
(2)客户端
# /etc/init.d/salt-minion start #启动minion
或者
#salt-minion -d #启动并后台运行
三、配置认证
(1)在服务端上操作
在服务器端执行如下语句可以查询到当前环境下有多少个客户端等待服务器端的认证
[root@test1 salt]# salt-key
从上图可以看出目前有两个机器test1和test2等待认证,执行如下语句接受
[root@test1 salt]# salt-key -a test1
[root@test1 salt]# salt-key -a test2
再次用命令salt-key
查看,发现两台机器已经由服务端认证并出现在已经通过的列表中
Note:-a :accept ,-A:accept-all,-d:delete,-D:delete-all。可以使用salt-key 命令查看到已经签名的客户端。此时我们在客户端的 /etc/salt/pki/minion 目录下面会多出一个minion_master.pub 文件。
(2)测试验证
示例1:salt '*' test.ping
[root@test1 master]# salt '*' test.ping //检测通讯是否正常,也可以指定其中一个 'test2'
示例2: salt '*' cmd.run 'df -h'
[root@test1 master]# salt '*' cmd.run 'df -h' //远程执行命令,查看磁盘情况
Note: 这里的*
必须是在 master 上已经被接受过的客户端,可以通过 salt-key 查到,通常是我们已经设定的 id 值。关于这部分内容,它支持通配、列表以及正则。比如两台客户端 web10、web11, 那我们可以写成salt 'web*'
salt 'web1[02]'
salt -L 'web10,web11'
salt -E 'web(10|11)'
等形式,使用列表,即多个机器用逗号分隔,而且需要加-L,使用正则必须要带-E选项。 它还支持 grains 和 pillar,分别加-G 和 -I 选项,下面会介绍到。
四、grains 和 pillar
1、grains
grains 是在 minion(客户端)启动时收集到的一些信息,比如操作系统类型、网卡ip等。
[root@test1 master]# salt 'test2' grains.ls //列出所有的 grains 项目名字
[root@test1 master]# salt 'test2' grains.items //列出所有的 grains 项目名以及值
Note:grains的信息并不是动态的,并不会时时变更,它只是在 minion 启动时收集到的。grains 还可以做配置管理。
下面进行自定义 grains的测试
(1)客户端上配置
[root@test2 ~]# vi /etc/salt/grains
//添加如下,注意横杠后有空格
grains:
role:
- nginx
env:
- test
myname:
重启客户端minion服务
[root@test2 salt]# pkill salt
[root@test2 salt]# ps -ef | grep salt
root 7933 4573 0 13:13 pts/1 00:00:00 grep --color=auto salt
[root@test2 salt]# salt-minion -d
/usr/lib/python2.7/site-packages/salt/scripts.py:212: DeprecationWarning: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. Salt will drop support for Python 2.7 in the Sodium release or later.
[root@test2 salt]# ps -ef | grep salt
root 7948 1 18 13:13 ? 00:00:00 /usr/bin/python /usr/bin/salt-minion -d
root 8078 4573 0 13:13 pts/1 00:00:00 grep --color=auto salt
(2)服务端获取 grains
[root@test1 master]# salt 'test2' grains.item role env myname //列出多个
[root@test1 master]# salt 'test2' grains.get myname //列出单个
Note:grains 在远程执行命令时很方便。可以按照 grains 的一些指标来操作。比如把所有的 web 服务器的 grains 的role 设置为 nginx,那这样就可以批量对nginx 的服务器进行操作了
[root@test1 master]# salt -G role:nginx cmd.run 'hostname'
[root@test1 master]# salt -G os:CentOS cmd.run 'hostname'
2、pillar
pillar 和 grains 不一样,pillar是在master 上定义的,并且是针对 minion 定义的一些信息。像一些比较重要的数据(如密码)可以存在 pillar 里,还可以定义变量等。
查看指定minion的 pillar 值:
[root@test1 master]# salt 'test2' pillar.items
test2:
----------
(1)服务端自定义配置 pillar
[root@test1 master]# vi /etc/salt/master //第837行,找到如下内容,去掉注释
[root@test1 master]# mkdir /srv/pillar
[root@test1 master]# vi /srv/pillar/test.sls //自定义配置文件,内容如下
conf: /etc/test.conf //注意冒号后有空格
myname: jingjing
[root@test1 master]# vim /srv/pillar/top.sls //总入口文件,内容如下
注意格式
base:
'test2':
- test
重启master
[root@test1 master]# pkill salt-master
[root@test1 master]# salt-master -d
Note:当更改完 pillar 配置文件后,可以通过刷新 pillar配置来获取新的 pillar 状态:
[root@test1 master]# salt '*' saltutil.refresh_pillar
(2)验证
[root@test1 pillar]# salt 'test2' pillar.items
[root@test1 pillar]# salt 'test2' pillar.item myname
pillar 同样可以用来作为 salt 的匹配对象。比如:
[root@test1 pillar]# salt -I 'conf:/etc/test.conf' test.ping
[root@test1 pillar]# salt -I 'conf:/etc/test.conf' cmd.run 'w'
五、使用Saltstack配置管理安装Apache
下面进行的演示是远程通过 yum 方式安装 Apache。步骤如下:
1、配置
[root@test1 pillar]# vi /etc/salt/master //注意是第667行的那个,取消注释,如下图所示
Note:base、dev(开发环境)、test(测试环境)、prod(生产环境)。
[root@test1 pillar]# mkdir /srv/salt //创建上面的环境目录
[root@test1 pillar]# vi /srv/salt/top.sls //入口文件,添加如下内容
base:
'*':
- apache
Note:若换成 ‘test2’,则表示在客户端test2执行 apache 模块,此处在test1和test2都进行apache的安装。
[root@test1 pillar]# vi /srv/salt/apache.sls //添加如下内容
apache-service:
pkg.installed:
- names: //如果只有一个服务,那么就可以写成 –name: httpd 不用再换一行
- httpd
- httpd-devel
service.running:
- name: httpd
- enable: True
Note:apache-service 是自定义的 id 名。pkg.installed为包安装函数,下面是要安装的包的名字。service.running 也是一个函数,来保证指定的服务启动,enable 表示开机启动。
2、重启salt-master服务
[root@test1 pillar]# pkill salt-master
[root@test1 pillar]# salt-master -d
3、执行命令进行apache的安装
[root@test1 pillar]# salt '*' state.highstate // //执行时间比较长,因为要安装httpd,中间不会有任何输出,想卡住了一样,这也是saltstack的一个槽点,但是ansible工具就不会这样
test2:
----------
ID: apache-service
Function: pkg.installed
Name: httpd
Result: True
Comment: The following packages were installed/updated: httpd
Started: 14:11:45.643270
Duration: 37747.083 ms
Changes:
----------
httpd:
----------
new:
2.4.6-93.el7.centos
old:
httpd-tools:
----------
new:
2.4.6-93.el7.centos
old:
----------
ID: apache-service
Function: pkg.installed
Name: httpd-devel
Result: True
Comment: The following packages were installed/updated: httpd-devel
Started: 14:12:23.414868
Duration: 8281.703 ms
Changes:
----------
httpd-devel:
----------
new:
2.4.6-93.el7.centos
old:
----------
ID: apache-service
Function: service.running
Name: httpd
Result: True
Comment: Service httpd has been enabled, and is running
Started: 14:12:32.418935
Duration: 318.327 ms
Changes:
----------
httpd:
True
Summary for test2
------------
Succeeded: 3 (changed=3)
Failed: 0
------------
Total states run: 3
Total run time: 46.347 s
test1:
----------
ID: apache-service
Function: pkg.installed
Name: httpd
Result: True
Comment: The following packages were installed/updated: httpd
Started: 14:11:45.672262
Duration: 36412.417 ms
Changes:
----------
apr:
----------
new:
1.4.8-5.el7
old:
apr-util:
----------
new:
1.5.2-6.el7
old:
httpd:
----------
new:
2.4.6-93.el7.centos
old:
httpd-tools:
----------
new:
2.4.6-93.el7.centos
old:
----------
ID: apache-service
Function: pkg.installed
Name: httpd-devel
Result: True
Comment: The following packages were installed/updated: httpd-devel
Started: 14:12:22.124900
Duration: 11622.839 ms
Changes:
----------
apr-devel:
----------
new:
1.4.8-5.el7
old:
apr-util-devel:
----------
new:
1.5.2-6.el7
old:
cyrus-sasl-devel:
----------
new:
2.1.26-23.el7
old:
expat-devel:
----------
new:
2.1.0-11.el7
old:
httpd-devel:
----------
new:
2.4.6-93.el7.centos
old:
libdb-devel:
----------
new:
5.3.21-25.el7
old:
openldap-devel:
----------
new:
2.4.44-21.el7_6
old:
----------
ID: apache-service
Function: service.running
Name: httpd
Result: True
Comment: Service httpd has been enabled, and is running
Started: 14:12:35.854064
Duration: 802.417 ms
Changes:
----------
httpd:
True
Summary for test1
------------
Succeeded: 3 (changed=3)
Failed: 0
------------
Total states run: 3
Total run time: 48.838 s
在test1上查询80端口的情况:
[root@test1 pillar]# lsof -i :80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 25331 root 4u IPv6 117853 0t0 TCP *:http (LISTEN)
httpd 25332 apache 4u IPv6 117853 0t0 TCP *:http (LISTEN)
httpd 25333 apache 4u IPv6 117853 0t0 TCP *:http (LISTEN)
httpd 25335 apache 4u IPv6 117853 0t0 TCP *:http (LISTEN)
httpd 25336 apache 4u IPv6 117853 0t0 TCP *:http (LISTEN)
httpd 25337 apache 4u IPv6 117853 0t0 TCP *:http (LISTEN)
在test2上查询80端口的情况:
[root@test2 salt]# lsof -i :80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 9496 root 4u IPv6 81455 0t0 TCP *:http (LISTEN)
httpd 9497 apache 4u IPv6 81455 0t0 TCP *:http (LISTEN)
httpd 9498 apache 4u IPv6 81455 0t0 TCP *:http (LISTEN)
httpd 9499 apache 4u IPv6 81455 0t0 TCP *:http (LISTEN)
httpd 9500 apache 4u IPv6 81455 0t0 TCP *:http (LISTEN)
httpd 9501 apache 4u IPv6 81455 0t0 TCP *:http (LISTEN)
如上图所示,说明 Apache 远程安装已成功。
六、使用Saltstack管理文件和目录
1、文件管理
(1)服务端配置
修改前面建立的top.sls文件
[root@test1 pillar]# vi /srv/salt/top.sls //修改如下
base:
'test2':
- filetest
新建 filetest.sls 文件
[root@test1 pillar]# vi /srv/salt/filetest.sls //添加如下内容,注意格式
file-test:
file.managed:
- name: /tmp/filetest.txt
- source: salt://test/wen/test.txt
- user: root
- group: root
- mode: 644
Note:第一行的 file-test 为自定的名字,表示该配置段的名字,可以在别的配置段中引用它;source指定文件从哪里拷贝,这里的 test 目录相当于是 /srv/salt/test 目录;name指定远程客户端要生成的文件名。
新建所要测试的源文件
[root@test1 pillar]# mkdir -p /srv/salt/test/wen/
[root@test1 pillar]# vi /srv/salt/test/wen/test.txt //加入如下内容后保存
hello world!
执行命令:
[root@test1 pillar]# salt 'test2' state.highstate
test2:
----------
ID: file-test
Function: file.managed
Name: /tmp/filetest.txt
Result: True
Comment: File /tmp/filetest.txt updated
Started: 14:49:24.062081
Duration: 49.946 ms
Changes:
----------
diff:
New file
mode:
0644
Summary for test2
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
Total run time: 49.946 ms
[root@test1 pillar]# cat /srv/salt/filetest.sls
file-test:
file.managed:
- name: /tmp/filetest.txt
- source: salt://test/wen/test.txt
- user: root
- group: root
- mode: 644
(2)客户端验证
2、目录管理
(1)服务端配置
接着编辑之前的 top.sls 文件
[root@test1 pillar]# vi /srv/salt/top.sls //修改为如下
base:
'test2':
- filedir
新建 filedir.sls 文件
[root@test1 pillar]# vi /srv/salt/filedir.sls //添加如下内容
file-dir:
file.recurse:
- name: /tmp/testdir
- source: salt://test1/wen1
- user: root
- file_mode: 644
- dir_mode: 755
- mkdir: True
- clean: True
Note:clean: True 源端删除文件或目录,目标端也会跟着删除,否则不会删除。可以默认设置为 False
新建所要测试的源目录
[root@test1 pillar]# mkdir -p /srv/salt/test1/wen1/
[root@test1 pillar]# vi /srv/salt/test1/wen1/test1.txt //添加如下内容并保存
happy everyday!
执行命令:
[root@test1 pillar]# salt 'test2' state.highstate
test2:
----------
ID: file-dir
Function: file.recurse
Name: /tmp/testdir
Result: True
Comment: Recursively updated /tmp/testdir
Started: 15:08:40.444403
Duration: 112.77 ms
Changes:
----------
/tmp/testdir/test1.txt:
----------
diff:
New file
mode:
0644
Summary for test2
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
Total run time: 112.770 ms
(2)客户端验证
(3)测试增删功能
在服务端新建 newdir 目录以及 newtestdir.txt文件,删除 test1.txt 文件:
[root@test1 ~]# mkdir /srv/salt/test1/wen1/newdir
[root@test1 ~]# touch /srv/salt/test1/wen1/newtestdir.txt
[root@test1 ~]# touch /srv/salt/test1/wen1/newdir/newdir.txt
[root@test1 ~]# rm -rf /srv/salt/test1/wen1/test1.txt
执行命令:
[root@test1 pillar]# salt 'test2' state.highstate
test2:
----------
ID: file-dir
Function: file.recurse
Name: /tmp/testdir
Result: True
Comment: Recursively updated /tmp/testdir
Started: 15:17:21.602381
Duration: 131.864 ms
Changes:
----------
/tmp/testdir/newdir:
----------
/tmp/testdir/newdir:
New Dir
/tmp/testdir/newdir/newdir.txt:
----------
diff:
New file
mode:
0644
/tmp/testdir/newtestdir.txt:
----------
diff:
New file
mode:
0644
removed:
- /tmp/testdir/test1.txt
Summary for test2
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
Total run time: 131.864 ms
客户端验证:
Note:由上图可知,成功在客户端 /tmp/testdir/ 目录下创建了 newdir 目录以及 newtestdir.txt 文件,并删除 test1.txt 文件。这里值得注意的是要成功创建 newdir 目录,前提是 newdir 目录下要有文件,如这里的newdir.txt 文件,如若没有,客户端是不会创建 newdir 目录的。
七、远程执行
前面提到远程执行命令 test.ping,cmd.run,点前面的是模块,点后面的是函数;这样不太规范化,下面详细介绍怎么远程执行脚本。
1、远程执行脚本
(1)服务端配置
接着编辑之前的 top.sls 文件
[root@test1 ~]# vi /srv/salt/top.sls
base:
'test2':
- shelltest
新建 shelltest.sls 文件
[root@test1 ~]# vi /srv/salt/shelltest.sls
shell-test:
cmd.script:
- source: salt://test/1.sh
- user: root
新建 1.sh 脚本文件
[root@test1 ~]# vi /srv/salt/test/1.sh
#!/bin/bash
touch /tmp/shelltest.txt
if [ -d /tmp/shelltest ];then
rm -rf /tmp/shelltest
else
mkdir /tmp/shelltest
fi
执行命令:
[root@test1 test]# salt 'test2' state.highstate
test2:
----------
ID: shell-test
Function: cmd.script
Result: True
Comment: Command 'shell-test' run
Started: 16:34:43.334454
Duration: 59.795 ms
Changes:
----------
pid:
59432
retcode:
0
stderr:
stdout:
Summary for test2
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
Total run time: 59.795 ms
(2)客户端验证
八、使用Saltstack管理任务计划
1、建立 cron
(1)服务端配置
编辑 top.sls 文件
[root@test1 ~]# vi /srv/salt/top.sls
base:
'test2':
- crontest
编辑 crontest.sls 文件
[root@test1 ~]# vi /srv/salt/crontest.sls
cron-test:
cron.present:
- name: /bin/touch /tmp/crontest.txt
- user: root
- minute: '*'
- hour: 20
- daymonth: 1-10
- month: '3,5'
- dayweek: '*'
Note:*
需要用单引号引起来。当然还可以使用 file.managed 模块来管理 cron,因为系统的 cron都是以配置文件的形式存在的。
执行命令:
[root@test1 ~]# salt 'test2' state.highstate
test2:
----------
ID: cron-test
Function: cron.present
Name: /bin/touch /tmp/crontest.txt
Result: True
Comment: Cron /bin/touch /tmp/crontest.txt added to root's crontab
Started: 16:56:09.934913
Duration: 145.614 ms
Changes:
----------
root:
/bin/touch /tmp/crontest.txt
Summary for test2
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
Total run time: 145.614 ms
(2)客户端验证
2、删除 cron
(1)服务端配置
只需修改 crontest.sls 文件,把 cron.present:
改成 cron.absent:
Note:两者不能共存,要想删除一个 cron,之前的 present 就得替换掉或者删除掉。
执行命令:
[root@test1 ~]# salt 'test2' state.highstate
test2:
----------
ID: cron-test
Function: cron.absent
Name: /bin/touch /tmp/crontest.txt
Result: True
Comment: Cron /bin/touch /tmp/crontest.txt removed from root's crontab
Started: 17:02:03.579733
Duration: 101.586 ms
Changes:
----------
root:
/bin/touch /tmp/crontest.txt
Summary for test2
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
Total run time: 101.586 ms
(2)客户端验证
九、Saltstack 常用命令
1、拷贝文件到客户端
[root@test1 ~]# salt 'test2' cp.get_file salt://crontest.sls /tmp/test2.txt
test2:
/tmp/test2.txt
2、拷贝目录到客户端
[root@test1 ~]# salt 'test2' cp.get_dir salt://test /tmp
test2:
- /tmp/test/1.sh
- /tmp/test/test.sh
3、显示存活的客户端
[root@test1 ~]# salt-run manage.up
- test1
- test2
4、命令下执行服务端的脚本
编写一个测试脚本
[root@test1 test]# vi /srv/salt/test/test1.sh
#!/bin/bash
echo -e "\e[31m hello world \e[0m" >> /tmp/test1.txt
执行命令:
[root@test1 test]# salt 'test2' cmd.script salt://test/test1.sh
test2:
----------
pid:
60884
retcode:
0
stderr:
stdout:
客户端查看