|
Saltstack是一个具备puppet与func功能为一身的集中化管理平台,它基于python实现,功能十分强大,各模块融合度及复用性极高,官方极力推荐作为云计算平台的基础架构。可以轻松维护成千上万台服务器. 相对于同类型的其他平台, 例如Ruby下的Chef, 以及大家比较熟知的puppet, Salt的优势在于他的配置更加简单, 运行效率更高, 自带的模块更加丰富, 以及API是全python语法对于我们搞运维的同学来说相对比较易读, 所以笔者认为是一个大家值得去学习的自动化部署平台.
本文将帮助大家如何快速部署一个Salt平台.
大家如果想了解更多地相关知识, 可以去访问salt的官方文档 (中文版需VPN)
https://docs.saltstack.com/en/latest/topics/index.html
http://docs.saltstack.cn/zh_CN/latest/
安装环境:
System: Centos 6.3
Salt master: salt-master.example.com
Salt minion: salt-client01.example.com
一. 环境部署及安装
1. 关闭iptables和SELINUX
# service iptables stop
# setenforce 0
# vi /etc/sysconfig/selinux
...
SELINUX=disabled
...
2. 安装第三方yum源
# rpm -Uvh http://ftp.linux.ncsu.edu/pub/ep ... ease-6-8.noarch.rpm
3. 更新系统证书模块和python到最新版本
# yum upgrade ca-certificates --disablerepo=epel -y
# yum update python -y
4. 在服务器端(Salt master)安装Salt-master
# yum install salt-master -y
5. 在客户端(Salt minion)安装Salt-minion
# yum install salt-minion -y
二. 初始配置
[Salt minion side]
1. 在客户端添加服务端地址从而提交申请
# vi /etc/salt/minion
...
# Set the location of the salt master server, if the master server cannot be
# resolved, then the minion will fail to start.
master: salt-master.example.com
...
# /etc/init.d/salt-minion restart
[Salt master side]
2. 检查客户端申请
# salt-key list
Accepted Keys:
Denied Keys:
Unaccepted Keys:
salt-client01.example.com
Rejected Keys:
3. 获准申请
# salt-key -a salt-client01.example.com
The following keys are going to be accepted:
Unaccepted Keys:
salt-client01.example.com
Proceed? [n/Y] y
Key for minion salt-client01.example.com accepted.
这里服务端与客户端的连接配置基本完成.
三. 模块介绍
这里我们可以通过此命令列出Salt常用的模块, 接下来我将介绍一些常用模块的使用方法
# salt '*' sys.list_modules
salt-client01.example.com:
- acl
- aliases
- alternatives
- archive
- artifactory
- at
- blockdev
- bridge
- btrfs
- buildout
- cloud
- cmd
…
1. cmd module
1). 执行远程客户端CLI
# salt '*' cmd.run 'hostname'
salt-client01.example.com:
salt-client01.example.com
2). 将脚本推送到客户端(目录位置: /var/cache/salt/minion/files/base/test.sh) 并远程去执行该脚本
# cd /src/salt
# echo 'hostname' > test.sh
# salt '*' cmd.script salt://test.sh
salt-client01.example.com:
----------
pid:
3028
retcode:
0
stderr:
stdout:
salt-client01.example.com
2. cp module
1). GET_FILE方法
Tip: Salt默认的文件根文件目录为/src/salt, 所以我们可以将我们需要推送的文件放到此目录, 从而可以使用salt自带的协议去传送.
这里cp.get_file方法是将具体master端的文件推送到客户端具体目录
[Salt master side]
# mkdir -p /srv/salt && cd /srv/salt
# echo "test" > test.txt
# salt '*' cp.get_file salt://test.txt /root/test.txt makedirs=True
salt-client01.example.com:
/root/test.txt
若传送的文件很大, 而服务器的硬件资源又很充裕, 我们可以通过他的压缩=>传输=>解压的方法提高我们的文件传输速率(这里1到9表示压缩文件的比率)
# salt '*' cp.get_file salt://test.txt /root/test.txt gzip=5
2). GET_DIR方法
这里cp.get_dir 方法是将具体master端的目录及子目录文件推送到客户端
# mkdir -p /srv/salt/test_folder && cd /srv/salt/test_folder
# touch test_file0{1,2,3}
# salt '*' cp.get_dir salt://test_folder /root
salt-client01.example.com:
- /root/test_folder/test_file01
- /root/test_folder/test_file02
- /root/test_folder/test_file03
压缩传送
# salt '*' cp.get_dir salt://test_folder /root gzip=5 template=jinja
3). GET_URL方法
下载具体的URL文件到客户端
# salt '*' cp.get_url http://www.iyunv.com ~/index.html
salt-client01.example.com:
/root/index.html
3. cron module
1). 查看客户端计划任务列表
# salt '*' cron.raw_cron root
salt-client01.example.com:
* * * * 0 /bin/sh ~/test.sh
2). 添加一个计划任务
# salt '*' cron.set_job root '*' '*' '*' '*' 1 /usr/local/weekly
salt-client01.example.com:
new
# salt '*' cron.raw_cron root
salt-client01.example.com:
* * * * 0 /bin/sh ~/test.sh
# Lines below here are managed by Salt, do not edit
* * * * 1 /usr/local/weekly
3). 删除一个计划任务
# salt '*' cron.rm_job root /usr/local/weekly
salt-client01.example.com:
removed
4. dnsutil module
1). 添加一个HOST记录
# salt '*' dnsutil.hosts_append /etc/hosts 127.0.0.1 salt-client01
salt-client01.example.com:
The following line was added to /etc/hosts:
127.0.0.1 salt-client01
2). 删除一个HOST记录
# salt '*' dnsutil.hosts_remove /etc/hosts salt-client01
salt-client01.example.com:
None
5. file module
1). 获取客户端文件md5值
# salt '*' file.get_sum /etc/passwd md5
salt-client01.example.com:
17d14d55b712bd36a735b66dd708c177
2). 检查该文件是否匹配给定的md5值, 匹配则返回Ture
# salt '*' file.check_hash /etc/passwd md5:17d14d55b712bd36a735b66dd708c177
salt-client01.example.com:
True
3). 更新客户端文件属主及属组
# salt '*' file.chown ~/test.txt nobody nobody
salt-client01.example.com:
None
4). 调用客户端cp命令
# salt '*' file.copy ~/test.txt ~/test1.txt
salt-client01.example.com:
True
5). 查看客户端文件是否存在
# salt '*' file.directory_exists /etc
salt-client01.example.com:
True
6). 获取客户端文件的详细属性
# salt '*' file.stats /etc/passwd
salt-client01.example.com:
----------
atime:
1442470687.07
ctime:
1396603826.1
gid:
0
group:
root
inode:
277879
mode:
0644
mtime:
1396603826.1
size:
1560
target:
/etc/passwd
type:
file
uid:
0
user:
root
7). 获取客户端文件权限
# salt '*' file.get_mode /etc/passwd
salt-client01.example.com:
0644
8). 更改客户端文件权限
# salt '*' file.set_mode ~/test.txt 0777
salt-client01.example.com:
0777
9). 创建客户端目录
# salt '*' file.mkdir ~/test_dir
salt-client01.example.com:
None
10). 替换客户端文件内容字符串.
# salt '*' file.sed /etc/httpd/conf/httpd.conf 'LogLevel warn' 'LogLevel info'
salt-client01.example.com:
----------
pid:
3666
retcode:
0
stderr:
stdout:
11). 添加客户端文件字符串
# salt '*' file.append ~/test.conf "maxclient 100"
salt-client01.example.com:
Wrote 1 lines to "/root/test.conf"
12). 删除客户端文件
# salt '*' file.remove ~/test1.txt
salt-client01.example.com:
True
6. network module
1). 调用dig, ping, traceroute命令并返回结果.
# salt '*' network.dig http://www.iyunv.com
# salt '*' network.ping http://www.iyunv.com ;
# salt '*' network.traceroute http://www.iyunv.com
7. pkg package module
这里本例使用的是CentOS系统, 则这里调用的是yum包管理安装, 若为Ubuntu Salt会调用apt-get.
1). 安装PHP到客户端
# salt '*' pkg.install php
2). 删除客户端PHP
# salt '*' pkg.remove php
3). 更新客户端所有yum包
# salt '*' pkg.upgrade
8. service module
1). 开启或关闭httpd服务系统启动(可以理解调用chkconfig命令)
# salt '*' service.enable httpd
# salt '*' service.disable httpd
2). 调用service命令(reload, restart, start, stop, status)执行相关服务操作
# salt '*' service.reload httpd
# salt '*' service.restart httpd
# salt '*' service.start httpd
# salt '*' service.stop httpd
# salt '*' service.status httpd
9. Grains module
Grains翻译过来的意思其实就是谷粒, 引用到Saltstack其实通俗来讲就是它会将检测到的的系统硬件信息(系统名, 内核参数, 网卡配置等)存储到自己的RAM下, 方便Salt其他模块去调用.
1). 返回匹配给定内核版本的主机
# salt -G 'kernelrelease:2.6.32-279.el6.x86_64' cmd.run 'uname -a'
2). 获取所有客户端grain模块相关信息
# salt '*' grains.ls
3). 获取客户端系统名
# salt '*' grains.item os
salt-client01.example.com:
----------
os:
CentOS
4). 获取客户端系统相关信息
# salt '*' grains.items
salt-client01.example.com:
----------
SSDs:
biosreleasedate:
12/01/2006
biosversion:
VirtualBox
cpu_flags:
- fpu
- vme
- de
- pse
- tsc
- msr
- pae
- mce
- cx8
- apic
- mtrr
- pge
- mca
- cmov
- pat
- pse36
- clflush
- mmx
- fxsr
- sse
- sse2
- syscall
- nx
- rdtscp
- lm
- constant_tsc
- up
- rep_good
- pni
- monitor
- ssse3
- lahf_lm
cpu_model:
Intel(R) Core(TM) i7-4750HQ CPU @ 2.00GHz
cpuarch:
x86_64
domain:
example.com
fqdn:
salt-client01.example.com
fqdn_ip4:
- 10.110.16.251
fqdn_ip6:
gpus:
|_
----------
model:
VirtualBox Graphics Adapter
vendor:
unknown
host:
salt-client01
hwaddr_interfaces:
----------
eth0:
08:00:27:cd:54:79
lo:
00:00:00:00:00:00
id:
salt-client01.example.com
init:
upstart
ip4_interfaces:
----------
eth0:
- 10.110.16.251
lo:
- 127.0.0.1
ip6_interfaces:
----------
eth0:
- fe80::a00:27ff:fecd:5479
lo:
- ::1
ip_interfaces:
----------
eth0:
- 10.110.16.251
- fe80::a00:27ff:fecd:5479
lo:
- 127.0.0.1
- ::1
ipv4:
- 10.110.16.251
- 127.0.0.1
ipv6:
- ::1
- fe80::a00:27ff:fecd:5479
kernel:
Linux
kernelrelease:
2.6.32-279.el6.x86_64
locale_info:
----------
defaultencoding:
unknown
defaultlanguage:
unknown
detectedencoding:
ANSI_X3.4-1968
localhost:
salt-client01.example.com
lsb_distrib_codename:
Final
lsb_distrib_id:
CentOS
lsb_distrib_release:
6.3
machine_id:
1307a6546720f165db6c202900000006
manufacturer:
innotek GmbH
master:
salt-master.example.com
mdadm:
mem_total:
996
nodename:
salt-client01.example.com
num_cpus:
1
num_gpus:
1
os:
CentOS
os_family:
RedHat
osarch:
x86_64
oscodename:
Final
osfinger:
CentOS-6
osfullname:
CentOS
osmajorrelease:
6
osrelease:
6.3
osrelease_info:
- 6
- 3
path:
/sbin:/usr/sbin:/bin:/usr/bin
productname:
VirtualBox
ps:
ps -efH
pythonexecutable:
/usr/bin/python2.6
pythonpath:
- /usr/bin
- /usr/lib64/python26.zip
- /usr/lib64/python2.6
- /usr/lib64/python2.6/plat-linux2
- /usr/lib64/python2.6/lib-tk
- /usr/lib64/python2.6/lib-old
- /usr/lib64/python2.6/lib-dynload
- /usr/lib64/python2.6/site-packages
- /usr/lib64/python2.6/site-packages/gtk-2.0
- /usr/lib/python2.6/site-packages
pythonversion:
- 2
- 6
- 6
- final
- 0
saltpath:
/usr/lib/python2.6/site-packages/salt
saltversion:
2015.5.5
saltversioninfo:
- 2015
- 5
- 5
- 0
selinux:
----------
enabled:
False
enforced:
Disabled
serialnumber:
0
server_id:
1640489673
shell:
/bin/bash
virtual:
VirtualBox
zmqversion:
3.2.5
5). Python API
我们也可以在minion端使用python api来查看系统默认或自定义的grains值, 这个方法方便我们在minions端去confirm该值.
[Salt minion side]
# yum install ipython -y
# ipython
In [1]: import salt.config
In [2]: import salt.loader
In [3]: __opts__ = salt.config.minion_config('/etc/salt/minion')
In [4]: __grains__ = salt.loader.grains(__opts__)
In [5]: print __grains__['id']
salt-client01.example.com
In [6]: print __grains__['selinux']
{'enforced': 'Permissive', 'enabled': True}
In [7]: print __grains__['selinux']['enforced']
Permissive
四. pillar介绍
Pillar是Saltstack最重要的组件之一, 其作用是定义与被控主机端相关的任何配置, 使其可以随时被模板, state, API等调用, 他的规范采用YAML形式, 简单来说可以理解为他是一个字典形式的参数列表, 大家随后写的部署脚本等都可以从这里调用数据, 而不需要在具体的脚本里将数据写死, 提高脚本的复用性.
1. 获取当前pillar配置信息
# vi /etc/salt/master
替换pillar_opts 参数为True.
# salt '*' pillar.data
2. SLS文件定义
pillar定义的配置参数会保存在sls文件中, 格式需符合YAML规范, 我们常规会配置一个top.sls的入口文件, 用来定义pillar数据的覆盖被控主机的有效范围.
a. 首先在master主配置文件中定义pillar主目录
# vi /etc/salt/master
添加:
pillar_roots:
base:
- /srv/pillar
b. 定义入口文件top.sls
Tip: base代表master主配置文件pillar_roots下定义的对象 (官方推荐定义为具体部署的测试环境,例如dev, stage, prod)
"*" 代表任意主机
- apache代表该同级目录下的一个apache.sls文件
# vi /srv/sillar/top.sls
base:
'*':
- apache
c. 定义具体的apache参数文件
# vi /srv/sillar/apache.sls
appname: website
flow:
maxconn: 30000
maxmem: 6G
d. 校验以上定义好的pillar
通过查看"salt-client01.example.com"主机的pillar数据,我们可以看到apache数据项, 原因是我们定义top.sls时使用了"*"涵盖了所有主机
如果返回结果为空我们尝试刷新被控主机数据后查看最终配置结果.
# salt '*' saltutil.refresh_pillar
# salt '*' pillar.data appname flow
salt-client01.example.com:
----------
appname:
website
flow:
----------
maxconn:
30000
maxem:
6G
这里返回的是我们定义好的appname和flow参数对应的值.
e.pillar的使用
完成pilar配置后, 我们可以在state, 模板文件中引用配置好的参数字典
例如:
一维字典: {{ pillar['appname'] }}
二维字典: {{ pillar['flow']['maxconn'] }}
我们也可以根据配置项过滤出匹配该参数的主机, 使用任意方法来让其返回相应的系统信息.
这里通过 -I 参数过滤出该主机并查看该主机的连通状态.
# salt -I 'appname:website' test.ping
salt-client01.example.com:
True
五. state介绍
state是saltstack最核心的功能, 它通过预先定制好的sls(salt state file)文件, 类似于chef的cookbook对被控主机进行状态管理, 支持常见的pkg, file, network, service, user模块调用, 更多模块可以参考官方文档: http://docs.saltstack.com/ref/states/all/index.html
1. state定义
state的定义是通过sls文件进行描述的, 支持YAML语法, 定义规则如下
$ID:
$State:
- $state: state
$ID 表示具体操作的对象, $State表示具体操作的使用的模块, - $state state表示对具体具体模块方法的调用.
例如:
apache: # state名称
pkg: # 使用pkg状态对象
- installed # 执行installed方法
service: # 使用service管理系统守护进程
- running # 执行查看running方法查看是否服务正常安装,未安装则需安装并运行
- require: # 确保apache只有在安装后, 才会启动.
- pkg: apache
上述代码检查apache软件包是否安装, 如未安装将通过yum或者api进行安装, 并最终检查apache服务是否处于运行状态.
六. pillar和state的集成配置实现将apache部署到客户端
1. 配置pillar
# vi /srv/pillar/top.sls
base:
'*':
- apache
b. 通过检查客户端系统, 判断具体的apache服务名
# mkdir -p /srv/pillar/apache
# vi /srv/pillar/apache/init.sls
pkgs:
{% if grains['os_family'] == 'Debian' %}
apache: apache2
{% elif grains['os_family'] == 'Redhat' %}
apache: httpd
{% elif grains['os'] == 'CentOS' %}
apache: httpd
{% endif %}
c. 测试pillar数据返回结果
# salt '*' pillar.data pkgs
salt-client01.example.com:
----------
pkgs:
----------
apache:
httpd
结果返回CentOS下apache服务名httpd, 说明配置已生效.
d. 配置 state
# vi /srv/salt/top.sls
base:
'*':
- apache
# mkdir /srv/salt/apache
# vi /srv/salt/apache/init.sls
这里可以看到通过python字典来调用pillar已配置参数.
pkg:
- installed
- name: {{ pillar['pkgs']['apache']}}
service.running:
- name: {{ pillar['pkgs']['apache']}}
- require:
- pkg: {{ pillar['pkgs']['apache']}}
e. 执行state
这里将执行最终的配置, 从而将apache远程部署到客户端.
# salt '*' state.highstate
salt-client01.example.com:
----------
ID: apache
Function: pkg.installed
Name: httpd
Result: True
Comment: The following packages were installed/updated: httpd
Started: 04:35:34.311058
Duration: 58831.849 ms
Changes:
----------
httpd:
----------
new:
2.2.15-47.el6.centos
old:
----------
ID: apache
Function: service.running
Name: httpd
Result: True
Comment: Started Service httpd
Started: 04:36:33.148020
Duration: 192.294 ms
Changes:
----------
httpd:
True
Summary
------------
Succeeded: 2 (changed=2)
Failed: 0
------------
Total states run: 2
部署完毕...
|
|