光说不练假把式,上一节我们已经了解了基本的salt功能,相信大家已经迫不及待想上手试一试了。这一节我们就来一起搭建一个本地的测试环境,体验下这些功能。
我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。
文章目录
安装saltstack
因为管理的机器类型繁多,操作系统各异,安装软件可能给人的感觉很繁琐。但是安装saltstack是非常容易的,因为官方已经给我们准备好了跨平台的一键安装脚本。
https://repo.saltstack.com/#bootstrap
但是这个一键安装脚本是基于shell的,并不是所有平台都支持。对于不支持的平台可以去下载对应平台的安装包,地址也是上面那个。
如果只是想在本地搭一个实验环境,官方的教程里面已经给我们准备好了vagrant镜像,点这里将整个git仓库下载到本地,就可以一键生成3个节点的实验环境。如下所示,整个集群包含一个master节点和两个minion节点。我们这一节就是使用这个官方的实验环境。
c:\saltstack\salt-vagrant-demo>vagrant status
Current machine states:
master running (virtualbox)
minion1 running (virtualbox)
minion2 running (virtualbox)
This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.
vagrant是基于镜像批量创建和管理vm的工具。关于vagrant的使用,可以参考我的vagrant入门教程专栏
基本远程控制操作
下面的操作是基于官方教程创建的实验环境,但是除了登陆机器的方式不一样,其余操作和生产环境没有任何区别。
salt命令的格式如下
salt [options] '<target>' <module.function> [arguments]
具体的函数源码可以直接上salt的github仓库查看,远程操作的都在/salt/salt/modules
这个目录中。这一节只介绍一些基本的操作,更多具体命令的使用后面专门讲解。
接受minions
saltstack的master以及minion的通信都是加密过的。为了达到这个目的minion机器会主动发送自己的public key给master,必须手动在master机器上接受这个key以后,对应的minion才能够接受master的指令。
首先进入master节点
c:\saltstack\salt-vagrant-demo>vagrant ssh master
可以直接免密码切换到root用户
vagrant@saltmaster:~$ sudo su
root@saltmaster:/home/vagrant#
接受全部的key
salt-key --accept-all
查看是否两个minion都已经被接受
root@saltmaster:/home/vagrant# salt-key --list-all
Accepted Keys:
minion1
minion2
Denied Keys:
Unaccepted Keys:
Rejected Keys:
检测连通性
这里利用的是/salt/salt/modules/test.py
中的ping
函数,并不是ICMP ping。返回True表示该minion连接性完好
root@saltmaster:/home/vagrant# salt '*' test.ping
minion1:
True
minion2:
True
跑shell命令
root@saltmaster:/home/vagrant# salt '*' cmd.run 'ls -l /home'
minion1:
total 4
drwxr-xr-x 5 vagrant vagrant 4096 Dec 14 18:19 vagrant
minion2:
total 4
drwxr-xr-x 5 vagrant vagrant 4096 Dec 14 18:19 vagrant
root@saltmaster:/home/vagrant#
跑salt的自建函数
salt社区在不停创造简单好用的自建函数,这些自建函数才是salt的核心所在。而且这些命令在所有支持的平台可以跨平台无障碍使用。例如,获取minion的磁盘使用情况,这里使用的是/salt/salt/modules/disk.py
下的usage
函数
root@saltmaster:/home/vagrant# salt '*' disk.usage
minion2:
----------
/:
----------
1K-blocks:
64800356
available:
59755976
capacity:
3%
filesystem:
/dev/mapper/vagrant--vg-root
used:
1722936
...
...
...
安装新的软件
root@saltmaster:/home/vagrant# salt '*' pkg.install cowsay
minion1:
----------
cowsay:
----------
new:
3.03+dfsg2-4
old:
minion2:
----------
cowsay:
----------
new:
3.03+dfsg2-4
old:
显示网卡信息
这里使用的是/salt/salt/modules/network.py
中的interfaces
函数
root@saltmaster:/home/vagrant# salt '*' network.ip_addrs
minion1:
- 10.0.2.15
- 192.168.50.11
minion2:
- 10.0.2.15
- 192.168.50.12
如果针对命令需要根据参数名去指定参数,可以在后面直接用等号来指定,例如
root@saltmaster:/home/vagrant# salt '*' network.ip_addrs cidr='10.0.0.0/8'
minion2:
- 10.0.2.15
minion1:
- 10.0.2.15
对目标minion进行筛选
很少有人会直接用'*'
去对所有的minion进行操作,根据目的适当筛选还是有必要的。下面举几个例子,更详细的筛选的方法可以参考官方文档。
根据名字匹配
其中最简单的就是根据名字,实验环境里面的两个minion分别叫做minion1和minion2。在安装minion的时候默认的minion ID是机器的hostname,想修改这个名字有两个方法
- 前面提到的一键安装脚本运行时利用
-i
选项指定名字 - 进入minion机器,在
/etc/salt/minion
配置中,修改id: xx
root@saltmaster:/home/vagrant# salt 'minion1' cmd.run 'ls -l /home'
minion1:
total 4
drwxr-xr-x 5 vagrant vagrant 4096 Dec 18 07:29 vagrant
名字也可以用通配符
root@saltmaster:/home/vagrant# salt 'minion*' cmd.run 'ls -l /home'
minion1:
total 4
drwxr-xr-x 5 vagrant vagrant 4096 Dec 18 07:29 vagrant
minion2:
total 4
drwxr-xr-x 5 vagrant vagrant 4096 Dec 14 18:19 vagrant
根据收集的grains来筛选
利用-G
参数来表示grains,利用name:value
的方式去表示对应的键值对。需要注意的是假如grain的值是一个列表的话,可能会出现无法匹配的情况。如果是单个值或者是字典都是没问题的。
root@saltmaster:/etc/salt# salt -G 'ipv4:192.168.50.12' cmd.run 'ls -l /home'
minion2:
total 4
drwxr-xr-x 5 vagrant vagrant 4096 Dec 14 18:19 vagrant
如果grains的值也是一个字典,就用冒号进行下一层的键值对匹配,例如
root@saltmaster:/home/vagrant# salt -G 'ip_interfaces:eth1:192.168.50.11' cmd.run 'ls /home/'
minion1:
vagrant
grains是master对管理的机器收集上来的静态信息,可以在master上通过类似
salt minion1 grains.ls
的命令去查看收集的条目名称,通过类似salt minion1 grains.items
或者salt minion1 grains.get xx
的命令去查看条目的内容。如果要自定义grains可以通过修改minion的/etc/salt/minion
文件的grains:
部分,或者添加一个/etc/salt/grains
文件来达到目的。配置文件对于单独的grains文件具有优先级。之后需要手动在master上通过salt minion1 saltutil.refresh_modules
命令来进行刷新
补充一点的就是,利用salt.modules.grains.items
去查看,但是注意获取单个grain的内容的时候用salt.modules.grains.get
而不要再用salt.modules.grains.item
,因为前者可以针对返回为字典的结果直接获取下一级的key对应的内容,例如
root@saltmaster:/home/vagrant# salt '*' grains.get ip_interfaces
minion2:
----------
eth0:
- 10.0.2.15
- fe80::a00:27ff:febc:dca4
eth1:
- 192.168.50.12
- fe80::a00:27ff:fe3b:7579
lo:
- 127.0.0.1
- ::1
minion1:
----------
eth0:
- 10.0.2.15
- fe80::a00:27ff:febc:dca4
eth1:
- 192.168.50.11
- fe80::a00:27ff:fec7:82f
lo:
- 127.0.0.1
- ::1
root@saltmaster:/home/vagrant# salt '*' grains.get ip_interfaces:eth0
minion2:
- 10.0.2.15
- fe80::a00:27ff:febc:dca4
minion1:
- 10.0.2.15
- fe80::a00:27ff:febc:dca4
根据正则表达式来筛选
利用-E
参数
root@saltmaster:/etc/salt# salt -E 'minion[0-9]' test.ping
minion1:
True
minion2:
True
根据列举的内容来筛选
利用-L
参数
root@saltmaster:/etc/salt# salt -L 'minion1,minion2' test.ping
minion1:
True
minion2:
True
组合筛选
利用-C
参数将前面几种匹配进行组合,使用起来有点复杂,这里只是有一个直观印象即可
root@saltmaster:/etc/salt# salt -C 'G@os:Ubuntu and minion* or S@192.168.50.*' test.ping
minion2:
True
minion1:
True
自定义群组
自定义群组的定义可以参考《Saltstack入门到精通教程(六):master和minion关键配置详解》这里面master的配置。
nodegroups:
group1: 'G@os:Ubuntu'
然后就可以利用-N
参数去引用这个群组
root@saltmaster:/home/vagrant# salt -N group1 test.ping
这也是一个非常有实用性的一个功能,不过需要维护好master的配置文件了,考虑将这个配置放在master.d/*.conf
中。
灰度操作
很多时候我们需要对目标机器一批批地进行操作,以确保服务的连续性,例如重启某些服务的操作。例如-b
参数可以设置每次灰度的数目或者是百分比
root@saltmaster:/home/vagrant# salt '*' -b 1 test.ping
Executing run on [u'minion2']
jid:
20200129082234520320
minion2:
True
retcode:
0
Executing run on [u'minion1']
jid:
20200129082234744354
minion1:
True
retcode:
0
这里不仅给出了每次执行的目标minion,还给出了jid和返回码。不想太操心就可以直接用百分比,salt会自动去分配每次执行的数量
root@saltmaster:/home/vagrant# salt '*' -b 30% test.ping
Executing run on [u'minion2']
jid:
20200129082728179565
minion2:
True
retcode:
0
Executing run on [u'minion1']
jid:
20200129082728418917
minion1:
True
retcode:
0
认识states文件
state系统用来对机器进行配置管理,其核心就是一个个的sls文件(SaLt State file),每一个sls文件表示机器应该处于的一种状态。通过结构清晰的YAML格式,使得对机器的配置管理变得更有效率。
这里只需要简单理解states的使用,真正厉害的地方在于states和pillar配合使用的时候,下一节会详细讲
上面的实验环境已经将saltmaster的/srv/salt
目录映射到了本地的salt-vagrant-demo-master/saltstack/salt
目录,直接在里面添加nettools.sls
文件,内容为
install_network_packages:
pkg.installed:
- pkgs:
- rsync
- lftp
- curl
这里调用的是pkg模块的installed函数,并给其中的pkgs参数赋值了一个list。具体的函数源码可以直接上salt的github仓库查看,和states有关的模块在salt/salt/states
中,这里使用的是salt/salt/states/pkg.py
模块中定义的installed
函数。
然后进入saltmaster发现文件已经出现在了/srv/salt
目录
vagrant@saltmaster:/srv/salt$ ll
total 5
drwxrwxrwx 1 vagrant vagrant 0 Dec 18 10:38 ./
drwxr-xr-x 4 root root 4096 Dec 19 03:24 ../
drwxrwxrwx 1 vagrant vagrant 0 Dec 17 08:33 common/
-rwxrwxrwx 1 vagrant vagrant 101 Dec 18 10:38 nettools.sls*
-rwxrwxrwx 1 vagrant vagrant 29 Dec 17 08:33 top.sls*
以root身份跑下面的命令对minion2采用刚才创建的state
salt 'minion2' state.apply nettools
结果如下
root@saltmaster:/srv/salt# salt 'minion2' state.apply nettools
minion2:
----------
ID: install_network_packages
Function: pkg.installed
Result: True
Comment: The following packages were installed/updated: lftp
The following packages were already installed: rsync, curl
Started: 03:53:47.100324
Duration: 29853.117 ms
Changes:
----------
lftp:
----------
new:
4.8.1-1ubuntu0.1
old:
Summary for minion2
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
Total run time: 29.853 s
耗时29.85秒更新了一个软件的版本,这段时间终端是没有任何输出打印的,容易给人一种卡了的感觉,注意不要中断命令
为states文件设置目标minion
上一部分我们创建了一个sls文件,并且在命令行指定minion2去应用这个配置,这样人为指定目标minion效率还是太低。一个sls文件可以发送给多个minion,一个minion也可以接受多个sls文件,将这个过程自动化是通过top.sls
文件达到的。
回到上一部分的例子,在/srv/salt
中已经有了一个top.sls
文件和另外一个common
目录,我们直接修改这个top.sls
文件即可
vagrant@saltmaster:/srv/salt$ ll
total 5
drwxrwxrwx 1 vagrant vagrant 0 Dec 18 10:38 ./
drwxr-xr-x 4 root root 4096 Dec 19 03:24 ../
drwxrwxrwx 1 vagrant vagrant 0 Dec 17 08:33 common/
-rwxrwxrwx 1 vagrant vagrant 101 Dec 18 10:38 nettools.sls*
-rwxrwxrwx 1 vagrant vagrant 29 Dec 17 08:33 top.sls*
将其改为如下图所示,所有minion都应用common
目录下的所有sls文件,只有minion1这一个minion应用nettools.sls
这个文件。.sls
的后缀要省略。
base:
'*':
- common
'minion1':
- nettools
然后跑下面的命令对所有的minion应用这个top.sls
设定
salt '*' state.apply
state.apply后面不接参数的话叫做highstate,会自动去应用top.sls文件
结果如下
root@saltmaster:/srv/salt# salt '*' state.apply
minion2:
----------
ID: common_packages
Function: pkg.installed
Result: True
Comment: All specified packages are already installed
Started: 07:33:37.272663
Duration: 72.592 ms
Changes:
Summary for minion2
------------
Succeeded: 1
Failed: 0
------------
Total states run: 1
Total run time: 72.592 ms
minion1:
----------
ID: common_packages
Function: pkg.installed
Result: True
Comment: All specified packages are already installed
Started: 07:33:36.974546
Duration: 73.18 ms
Changes:
----------
ID: install_network_packages
Function: pkg.installed
Result: True
Comment: The following packages were installed/updated: lftp
The following packages were already installed: rsync, curl
Started: 07:33:37.047973
Duration: 19997.737 ms
Changes:
----------
lftp:
----------
new:
4.8.1-1ubuntu0.1
old:
Summary for minion1
------------
Succeeded: 2 (changed=1)
Failed: 0
------------
Total states run: 2
Total run time: 20.071 s
下一步
这一节我们通过实验环境体验了salt的几个基本功能模块,但是目前接触的还比较浅显,下一节我们就针对配置管理这一个模块深入的学习一下。我们下一节见。