saltstack 基础平台管理工具---批量执行
简介SaltStack是一个服务器基础架构集中化管理平台,具备配置管理、远程执行、监控等功能,一般可以理解为简化版的puppet和加强版的func。SaltStack基于Python语言实现,结合轻量级消息队列(ZeroMQ)与Python第三方模块(Pyzmq、PyCrypto、Pyjinjia2、python-msgpack和PyYAML等)构建。
通过部署SaltStack环境,我们可以在成千上万台服务器上做到批量执行命令,根据不同业务特性进行配置集中化管理、分发文件、采集服务器数据、操作系统基础及软件包管理等,SaltStack是运维人员提高工作效率、规范业务配置与操作的利器。
官方网站:https://saltstack.com/
官方文档:https://docs.saltstack.com/en/latest/
GitHub:https://github.com/saltstack
中国saltstack用户组:https://www.saltstack.cn/
特性
(1)、部署简单、方便;
(2)、支持大部分UNIX/Linux及Windows环境;
(3)、主从集中化管理;
(4)、配置简单、功能强大、扩展性强;
(5)、主控端(master)和被控端(minion)基于证书认证,安全可靠;
(6)、支持API及自定义模块,可通过Python轻松扩展。
三种运行方式:
Local,Master/Minion ,Salt SSH
三大功能:
远程执行,配置管理,云管理
操作
安装:
IP地址
角色
192.168.20.93
master
192.168.20.172
minion
master 端:
yum install salt
-master salt-minion -y
minion端:
yum install salt
-minion -y 开机自启动:
chkconfig salt-minion on
启动master:
/etc/init.d/salt-master start
编译:vim /etc/salt/minion(master端和minion端都要配置)
配置17行:master 的主机IP地址
master: 192.168.20.93
id:XXXXXXXX #在master端显示的名称。
Master与Minion认证与快速入门
(1)、minion在第一次启动时,会在/etc/salt/pki/minion/(该路径在/etc/salt/minion里面设置)下自动生成minion.pem(private key)和 minion.pub(public key),然后将 minion.pub发送给master。
(2)、master在接收到minion的public key后,通过salt-key命令accept minion public key,这样在master的/etc/salt/pki/master/minions下的将会存放以minion>
minion端:
/etc/salt/pki/minion
# ll
total
8
-r-------- 1 root root 1679 May 31 12:57 minion.pem
-rw-r--r-- 1 root root451 May 31 12:57 minion.pub
master端:
# pwd
/etc/salt/pki/master
# ll
total 28
-r-------- 1 root root 1679 May 31 13:00 master.pem
-rw-r--r-- 1 root root451 May 31 13:00 master.pub
drwxr-xr-x 2 root root 4096 May 31 13:00 minions
drwxr-xr-x 2 root root 4096 May 31 13:00 minions_autosign
drwxr-xr-x 2 root root 4096 May 31 13:00 minions_denied
drwxr-xr-x 2 root root 4096 May 31 13:05 minions_pre
drwxr-xr-x 2 root root 4096 May 31 13:00 minions_rejected
在minion_pre 中有一个等待同意的主机名称
# tree
.
├── master.pem
├── master.pub
├── minions
├── minions_autosign
├── minions_denied
├── minions_pre
│ └── openfire2
└── minions_rejected
# salt-key
Accepted Keys:
Denied Keys:
Unaccepted Keys: #未同意的key
openfire2
Rejected Keys:
同意:
—A 同意所有;
# salt-key -a openfire2
The following keys are going to be accepted:
Unaccepted Keys:
openfire2
Proceed? Y
Key for minion openfire2 accepted.
和上面的tree 的结果进行对比发现openfire2 在不同的目录下了。
# tree
.
├── master.pem
├── master.pub
├── minions
│ └── openfire2
├── minions_autosign
├── minions_denied
├── minions_pre
└── minions_rejected
发现客户端也有master的public key
# ls
minion_master.pubminion.pemminion.pub
简单操作:
# salt '*' test.ping
openfire2:
True
[iyunv@js
-93 master]# salt '*' cmd.run 'uptime'
openfire2:
13:17:55 up 255 days,1:29,1 user,load average: 0.08, 0.07, 0.05
You have mail
in /var/spool/mail/root
[iyunv@js
-93 master]# salt '*' cmd.run 'df -h'
openfire2:
Filesystem >% Mounted on
/dev/sda3 195G4.6G181G 3% /
tmpfs
1.9G 12K1.9G 1% /dev/shm
/dev/sda1 194M 27M158M15% /boot
快速入门:
修改 master端的/etc/salt/master 文件:#该配置文件里面一定要保持使用空格,如果使用tab键,那么一定会报错。
416 file_roots:
417 base:
418 - /srv/salt
然后查看master端是否有
/srv/salt 这个目录,如果没有则创建。 mkdir /srv/salt 然后重启服务: /etc/init.d/salt-master restart
写一个apache服务的配置:
# cat apache.sls
apache
-install:
pkg.installed:
- names:
- httpd
- httpd-devel
apache
-service:
service.running:
- name: httpd
- enable: True #开机启动
->
****一定要注意缩进,该缩进按照2个空格进行缩进,每个层级关系在一起,下一个层级关系则会多增加两个空格。一定不要有别的字符,例如:tab
执行Apache.sls 配置。
master端:# salt '*' state.sls apache
openfire2:
----------
ID: apache-install
Function: pkg.installed
Name: httpd
Result: True
Comment: Package httpd is already installed.
Started: 14:46:21.941103
Duration: 1343.879 ms
Changes:
----------
ID: apache-install
Function: pkg.installed
Name: httpd-devel
Result: True
Comment: Package httpd-devel is already installed.
Started: 14:46:23.285596
Duration: 1.452 ms
Changes:
----------
ID: apache-service
Function: service.running
Name: httpd
Result: True
Comment: Service httpd has been enabled, and is running
Started: 14:46:23.288696
Duration: 263.856 ms
Changes:
----------
httpd:
True
Summary
------------
Succeeded: 3 (changed=1)
Failed: 0
------------
Total states run: 3
minion 端:
# ps -ef|grep yum
root 6961 6921 4 14:38 ? 00:00:00 /usr/bin/python2.6.6 /usr/bin/yum --quiet check-update
# chkconfig --list|grep httpd
httpd 0:off1:off2:on3:on4:on5:on6:off
# ps -ef|grep httpd
root 7170 10 14:46 ? 00:00:00 /usr/sbin/httpd
apache 717271700 14:46 ? 00:00:00 /usr/sbin/httpd
apache 717371700 14:46 ? 00:00:00 /usr/sbin/httpd
apache 717471700 14:46 ? 00:00:00 /usr/sbin/httpd
apache 717571700 14:46 ? 00:00:00 /usr/sbin/httpd
apache 717671700 14:46 ? 00:00:00 /usr/sbin/httpd
apache 717771700 14:46 ? 00:00:00 /usr/sbin/httpd
apache 717971700 14:46 ? 00:00:00 /usr/sbin/httpd
apache 718071700 14:46 ? 00:00:00 /usr/sbin/httpd
root 719063580 14:47 pts/0 00:00:00 grep httpd
saltstack 数据系统
grains数据系统
Grains:存放着minion启动时的数据信息(存储在minion端),只有在minion启动的时候才会收集。重启以后才会重新收集
# salt '*' grains.ls
openfire2:
- SSDs
- cpu_flags
- cpu_model
- cpuarch
- domain
- fqdn
- fqdn_ip4
- fqdn_ip6
- gpus
- host
- hwaddr_interfaces
->
- init
- ip4_interfaces
- ip6_interfaces
- ip_interfaces
- ipv4
- ipv6
- kernel
- kernelrelease
- locale_info
- localhost
- lsb_distrib_codename
- lsb_distrib_id
- lsb_distrib_release
- machine_id
- master
- mdadm
- mem_total
- nodename
- num_cpus
- num_gpus
- os
- os_family
- osarch
- oscodename
- osfinger
- osfullname
- osmajorrelease
- osrelease
- osrelease_info
- path
- ps
- pythonexecutable
- pythonpath
- pythonversion
- saltpath
- saltversion
- saltversioninfo
- selinux
- server_id
- shell
- virtual
- zmqversion
grains 的名称
# salt '*' grains.items
openfire2:
----------
SSDs:
cpu_flags:
- fpu
- vme
- de
- pse
- tsc
- msr
- pae
- mce
- cx8
- apic
- sep
- mtrr
- pge
- mca
- cmov
- pat
- pse36
- clflush
- dts
- mmx
- fxsr
- sse
- sse2
- ss
- ht
- syscall
- nx
- rdtscp
- lm
- constant_tsc
- arch_perfmon
- pebs
- bts
- xtopology
- tsc_reliable
- nonstop_tsc
- aperfmperf
- unfair_spinlock
- pni
- pclmulqdq
- ssse3
- cx16
- sse4_1
- sse4_2
- x2apic
- popcnt
- aes
- hypervisor
- lahf_lm
- arat
- dts
cpu_model:
Intel(R) Xeon(R) CPU E5606@
2.13GHz
cpuarch:
x86_64
domain:
fqdn:
openfire2
fqdn_ip4:
- 192.168.20.172
fqdn_ip6:
gpus:
|_
----------
model:
SVGA II Adapter
vendor:
unknown
host:
openfire2
hwaddr_interfaces:
----------
eth1:
00:0c:29:ed:a9:14
lo:
00:00:00:00:00:00
id:
openfire2
init:
upstart
ip4_interfaces:
----------
eth1:
- 192.168.20.172
lo:
- 127.0.0.1
ip6_interfaces:
----------
eth1:
- fe80::20c:29ff:feed:a914
lo:
- ::1
ip_interfaces:
----------
eth1:
- 192.168.20.172
- fe80::20c:29ff:feed:a914
lo:
- 127.0.0.1
- ::1
ipv4:
- 127.0.0.1
- 192.168.20.172
ipv6:
- ::1
- fe80::20c:29ff:feed:a914
kernel:
Linux
kernelrelease:
2.6.32-431.el6.x86_64
locale_info:
----------
defaultencoding:
UTF8
defaultlanguage:
en_US
detectedencoding:
UTF-8
localhost:
openfire2
lsb_distrib_codename:
Final
lsb_distrib_id:
CentOS
lsb_distrib_release:
6.5
machine_id:
e8c670405579b8d0809d7d1800000022
master:
192.168.20.93
mdadm:
mem_total:
3824
nodename:
openfire2
num_cpus:
4
num_gpus:
1
os:
CentOS
os_family:
RedHat
osarch:
x86_64
oscodename:
Final
osfinger:
CentOS-6
osfullname:
CentOS
osmajorrelease:
6
osrelease:
6.5
osrelease_info:
- 6
- 5
path:
/sbin:/usr/sbin:/bin:/usr/bin
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/lib/python2.6/site-packages
- /usr/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg-info
pythonversion:
- 2
- 6
- 6
- final
- 0
saltpath:
/usr/lib/python2.6/site-packages/salt
saltversion:
2015.5.10
saltversioninfo:
- 2015
- 5
- 10
- 0
selinux:
----------
enabled:
False
enforced:
Disabled
server_id:
1314904039
shell:
/bin/bash
virtual:
VMware
zmqversion:
3.2.5
grains 的详细信息
获取机器单个选项信息:
[iyunv@js
-93 salt]# salt '*' grains.item fqdn
openfire2:
----------
fqdn:
openfire2
[iyunv@js
-93 salt]# salt '*' grains.getfqdn
openfire2:
openfire2
# salt '*' grains.get ip_interfaces
openfire2:
----------
eth1:
- 192.168.20.172
- fe80::20c:29ff:feed:a914
lo:
- 127.0.0.1
- ::1
grains 的操作实例:
指定系统进行远程命令操作;
# salt -G os:CentOS cmd.run 'free -m'
openfire2:
total used free shared buffers cached
Mem:
3824 2860 964 0 169 1358
-/+ buffers/cache: 1333 2491
Swap: 2047 0 2047
参数:-G 表示用grains 的数据进行匹配。
grains 可以给minion端赋予 roles角色,然后通过salt远程执行对应的roles角色就行。
minion端:
# cat
/etc/salt/grains #这里面的role名称不能用roles 否则会冲突
web: check12
#
/etc/init.d/salt-minion restart
master端:
[iyunv@js
-93 master]# salt -G web:check12 cmd.run 'w'
openfire2:
17:50:08 up 255 days,6:01,1 user,load average: 0.12, 0.08, 0.01
USER TTY FROM LOGIN@>
root pts
/0 192.168.16.7 10:55 21.00s0.58s0.58s -bash
grains: 在master 的top.sls 里面进行配置minion 的信息,进行执行命令;
master端:
[iyunv@js
-93 salt]# cat top.sls
base:
'web:check12':
- match: grain
- apache
这里的apache 是
/src/salt/apache.sls 里面的信息。# salt '*' state.highstate #执行这个命令就会有信息返回
Pillar 数据系统
pillar 数据系统默认是关着的(master上面),因此要使用pillar需要修改 master端的 /etc/salt/master 的 552行 "#pillar_opts: False "改成 pillar_opts: True"
# /etc/init.d/salt-master restart
# salt '*' pillar.items #就可以查看到很多信息。
# salt '*' pillar.items
openfire2:
----------
master:
----------
__role:
master
auth_mode:
1
auto_accept:
False
cache_sreqs:
True
cachedir:
/var/cache/salt/master
cli_summary:
False
client_acl:
----------
client_acl_blacklist:
----------
cluster_masters:
cluster_mode:
paranoid
con_cache:
False
conf_file:
/etc/salt/master
config_dir:
/etc/salt
cython_enable:
False
daemon:
True
default_include:
master.d
/*.conf
enable_gpu_grains:
False
enforce_mine_cache:
False
enumerate_proxy_minions:
False
environment:
None
event_return:
event_return_blacklist:
event_return_queue:
0
event_return_whitelist:
ext_job_cache:
ext_pillar:
extension_modules:
/var/cache/salt/extmods
external_auth:
----------
failhard:
False
file_buffer_size:
1048576
file_client:
local
file_ignore_glob:
None
file_ignore_regex:
None
file_recv:
False
file_recv_max_size:
100
file_roots:
----------
base:
- /srv/salt
fileserver_backend:
- roots
fileserver_followsymlinks:
True
fileserver_ignoresymlinks:
False
fileserver_limit_traversal:
False
gather_job_timeout:
10
gitfs_base:
master
gitfs_env_blacklist:
gitfs_env_whitelist:
gitfs_insecure_auth:
False
gitfs_mountpoint:
gitfs_passphrase:
gitfs_password:
gitfs_privkey:
gitfs_pubkey:
gitfs_remotes:
gitfs_root:
gitfs_user:
hash_type:
md5
hgfs_base:
default
hgfs_branch_method:
branches
hgfs_env_blacklist:
hgfs_env_whitelist:
hgfs_mountpoint:
hgfs_remotes:
hgfs_root:
id:
openfire2
interface:
0.0.0.0
ioflo_console_logdir:
ioflo_period:
0.01
ioflo_realtime:
True
ioflo_verbose:
0
ipv6:
False
jinja_lstrip_blocks:
False
jinja_trim_blocks:
False
job_cache:
True
keep_jobs:
24
key_logfile:
/var/log/salt/key
keysize:
2048
log_datefmt:
%H:%M:%S
log_datefmt_logfile:
%Y-%m-%d %H:%M:%S
log_file:
/var/log/salt/master
log_fmt_console:
[%(levelname)-8s] %(message)s
log_fmt_logfile:
%(asctime)s,%(msecs)03.0f [%(name)-17s][%(levelname)-8s][%(process)d] %(message)s
log_granular_levels:
----------
log_level:
warning
loop_interval:
60
maintenance_floscript:
/usr/lib/python2.6/site-packages/salt/daemons/flo/maint.flo
master_floscript:
/usr/lib/python2.6/site-packages/salt/daemons/flo/master.flo
master_job_cache:
local_cache
master_pubkey_signature:
master_pubkey_signature
master_roots:
----------
base:
- /srv/salt-master
master_sign_key_name:
master_sign
master_sign_pubkey:
False
master_tops:
----------
master_use_pubkey_signature:
False
max_event_size:
1048576
max_minions:
0
max_open_files:
100000
minion_data_cache:
True
minionfs_blacklist:
minionfs_env:
base
minionfs_mountpoint:
minionfs_whitelist:
nodegroups:
----------
open_mode:
False
order_masters:
False
outputter_dirs:
peer:
----------
permissive_pki_access:
False
pidfile:
/var/run/salt-master.pid
pillar_opts:
True
pillar_roots:
----------
base:
- /srv/pillar
pillar_safe_render_error:
True
pillar_source_merging_strategy:
smart
pillar_version:
2
pillarenv:
None
ping_on_rotate:
False
pki_dir:
/etc/salt/pki/master
preserve_minion_cache:
False
pub_hwm:
1000
publish_port:
4505
publish_session:
86400
queue_dirs:
raet_alt_port:
4511
raet_clear_remotes:
False
raet_main:
True
raet_mutable:
False
raet_port:
4506
range_server:
range:80
reactor:
reactor_refresh_interval:
60
reactor_worker_hwm:
10000
reactor_worker_threads:
10
renderer:
yaml_jinja
ret_port:
4506
root_dir:
/
rotate_aes_key:
True
runner_dirs:
saltversion:
2015.5.10
search:
search_index_interval:
3600
serial:
msgpack
show_jid:
False
show_timeout:
True
sign_pub_messages:
False
sock_dir:
/var/run/salt/master
sqlite_queue_dir:
/var/cache/salt/master/queues
ssh_passwd:
ssh_port:
22
ssh_scan_ports:
22
ssh_scan_timeout:
0.01
ssh_sudo:
False
ssh_timeout:
60
ssh_user:
root
state_aggregate:
False
state_auto_order:
True
state_events:
False
state_output:
full
state_top:
salt://top.sls
state_top_saltenv:
None
state_verbose:
True
sudo_acl:
False
svnfs_branches:
branches
svnfs_env_blacklist:
svnfs_env_whitelist:
svnfs_mountpoint:
svnfs_remotes:
svnfs_root:
svnfs_tags:
tags
svnfs_trunk:
trunk
syndic_dir:
/var/cache/salt/master/syndics
syndic_event_forward_timeout:
0.5
syndic_jid_forward_cache_hwm:
100
syndic_master:
syndic_max_event_process_time:
0.5
syndic_wait:
5
timeout:
5
token_dir:
/var/cache/salt/master/tokens
token_expire:
43200
transport:
zeromq
user:
root
verify_env:
True
win_gitrepos:
-
https://github.com/saltstack/salt-winrepo.git
win_repo:
/srv/salt/win/repo
win_repo_mastercachefile:
/srv/salt/win/repo/winrepo.p
worker_floscript:
/usr/lib/python2.6/site-packages/salt/daemons/flo/worker.flo
worker_threads:
5
zmq_filtering:
False
pillar 的信息 修改 master端的:/etc/salt/master
#pillar_opts: True 这个再次改成False
pillar_opts: False
pillar_roots:
base:
- /srv/pillar# mkdir /srv/pillar
# /etc/init.d/salt-master restart#重启
使用:
先创建一个pillar的一个信息文件:
[iyunv@js
-93 salt]# cat /srv/pillar/apache.sls
{
% if grains['os'] == 'CentOS' %}
apache: httpd
{
% elif grains['os'] == 'Debian' %}
apache: apache2
{
% endif %}
然后指定能够读取这个文件的命令或文件:
[iyunv@js
-93 salt]# cat /srv/pillar/top.sls
base:
'*':
- apache
查看pillar数据系统的信息:
[iyunv@js
-93 salt]# salt '*' pillar.items
openfire2:
----------
apache:
httpd
因为apache.sls 里面指定的是CentOS的信息才会显示上面的内容,不然不会显示。
# salt -I 'apache:httpd' test.ping
openfire2:
Minion did not
return.
You have mail
in /var/spool/mail/root
-93 salt]# salt '*'saltutil.refresh_pillar
openfire2:
True
当不能使用的时候,要刷新一下。
# salt -I 'apache:httpd' test.ping
openfire2:
True
Grains 与Pillar的区别
名称
存储位置
数据类型
采集更新方式
应用
Grains
MInion端
静态数据
minion启动时手机,也可以使用saltutil.sync_grains进行刷新
存储Minion基本数据。比如用于匹配Minion,自身数据可以用来做资产管理等
Pillar
Master端
动态数据
在Master端定义,指定给对应的Minion。可以使用saltutil.refresh_pillar刷新
存储Master指定的数据,只有指定的Minion可以看到。用于敏感数据保存。
远程执行命令详解
远程执行命令三大内容:目标(targeting),模块(Module),返回(Returners)
目标(targeting)
https://docs.saltstack.com/en/latest/topics/targeting/所有支持的远程操作命令:主要是看正则表达式;
模块(Module)
https://docs.saltstack.com/en/latest/ref/modules/all/官方所有模块配置的地址。
返回(Returners)
https://docs.saltstack.com/en/latest/ref/returners/all/index.html
salt 的访问控制
首先修改/etc/salt/master 的acl控制:
vi
/etc/salt/master
245 client_acl:
246 ryan:
247 - test.ping
248 - network.*
修改这里表示,ryan 系统用户只能执行 test.ping 以及network.
* 的方法。
别的模块及方法则不行
[ryan@js
-93 ~]$ salt '*' test.ping
openfire2:
True
[ryan@js
-93 ~]$ salt '*' cmd.run 'w'
Failed to authenticate
! This is most likely because this user is not permitted to execute commands, but there is a small possibility that a disk error occurred (check disk/inode usage). 还可以指定某个用户只能访问某类型的机器,或者指定用户不能使用某个方法,以及不能使用某些模块。
salt 的信息还可以写入到mysql数据库。这个主要用于二次开发,或者收集记录信息等等,可以在官方文档查看到。
saltstack配置管理
top file 是saltstack的入口文件。
首先修改master端的 /etc/salt/master
file_roots:
base:
- /srv/salt/base
test:
- /srv/salt/test
prod:
- /srv/salt/prod
重启:
# /etc/init.d/salt-master restart
# mkdir /srv/salt/{base,test,prod}
写入一个批量修改reslov.conf的配置:
# pwd
/srv/salt/base
[iyunv@js
-93 base]# cat dns.sls
/etc/resolv.conf:
file.managed:
- source: salt://files/resolv.conf
- user: root
- group: root
- mode: 644
注释 salt://这是一个相对路径就相当于:/srv/salt/base的绝对路径一样。
因此,还要在base目录下面创建一个 files目录,用于存放resolv.conf文件;
查看一下需要配置的resolv.conf文件:
# pwd
/srv/salt/base/files
[iyunv@js
-93 files]# cat resolv.conf
# Generated by NetworkManager
nameserver
202.96.209.133
nameserver
4.4.4.4
nameserver
8.8.8.8
nameserver
114.114.114.114
直接命令行执行:
# salt '*' state.sls dns
js
-93:
----------
ID:
/etc/resolv.conf
Function: file.managed
Result: True
Comment: File
/etc/resolv.conf updated
Started:
14:12:36.775940
Duration:
41.112 ms
Changes:
----------
diff:
---
+++
@@ -1,3 +1,5 @@
# Generated by NetworkManager
nameserver 202.96.209.133
-#nameserver 114.114.114.114
+nameserver 4.4.4.4
+nameserver 8.8.8.8
+nameserver 114.114.114.114
Summary
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
openfire2:
----------
ID: /etc/resolv.conf
Function: file.managed
Result: True
Comment: File /etc/resolv.conf updated
Started: 14:05:11.366982
Duration: 38.805 ms
Changes:
----------
diff:
---
+++
@@ -1,3 +1,5 @@
-
-nameserver 192.168.19.1
-nameserver 202.96.209.5
+# Generated by NetworkManager
+nameserver 202.96.209.133
+nameserver 4.4.4.4
+nameserver 8.8.8.8
+nameserver 114.114.114.114
Summary
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
View Code 查看minion端的reslov.conf 是否修改成功:
# cat /etc/resolv.conf
# Generated by NetworkManager
nameserver
202.96.209.133
nameserver
4.4.4.4
nameserver
8.8.8.8
nameserver
114.114.114.114
这上面 命令行执行只是一个低级状态,如果有多个状态,则需要多次执行,因此。可以写一个高级状态,top file文件里面去定义。
# pwd
/srv/salt/base
[iyunv@js
-93 base]# cat dns.sls
/etc/resolv.conf:
file.managed:
- source: salt://files/resolv.conf
- user: root
- group: root
- mode: 644
# cat top.sls
base:
'*':
- dns
执行结果:
执行:salt '*' state.highstate
# salt '*' state.highstate
js
-93:
----------
ID:
/etc/resolv.conf
Function: file.managed
Result: True
Comment: File
/etc/resolv.conf updated
Started:
14:24:08.642733
Duration:
11.801 ms
Changes:
----------
diff:
---
+++
@@ -1,2 +1,5 @@
# Generated by NetworkManager
nameserver 202.96.209.133
+nameserver 4.4.4.4
+nameserver 8.8.8.8
+nameserver 114.114.114.114
Summary
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
openfire2:
----------
ID: /etc/resolv.conf
Function: file.managed
Result: True
Comment: File /etc/resolv.conf updated
Started: 14:16:48.282799
Duration: 29.424 ms
Changes:
----------
diff:
---
+++
@@ -1,2 +1,5 @@
# Generated by NetworkManager
nameserver 202.96.209.133
+nameserver 4.4.4.4
+nameserver 8.8.8.8
+nameserver 114.114.114.114
Summary
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
View Code 案例1:
新系统思想:
1.系统初始化
2.功能模块
3.业务模块
YAML规则语法:
1,缩进;Yaml使用一个固定的缩进放歌表示数据层结构关系。salt需要每个缩进级别有两个空格组成。不要使用tab
2,冒号;每个冒号后面都有一个空格,除了以冒号结尾和路径。
3,短横线;想要表示列表项,使用一个短横杠加一个空格。多个项使用同样的缩进级别作为同一列表的一部分。
jinja 用法:
# cat dns.sls
/etc/resolv.conf:
file.managed:
- source: salt://files/resolv.conf
- user: root
- group: root
- mode: 644
- template: jinja
- defaults:
DNS_SERVER01: 202.96.209.133
DNS_SERVER02: 114.114.114.114
# cat files/resolv.conf
# Generated by NetworkManager
nameserver {{DNS_SERVER01}}
nameserver {{DNS_SERVER02}}
执行:salt '*' state.highstate
# salt '*' state.highstate
openfire2:
----------
ID:
/etc/resolv.conf
Function: file.managed
Result: True
Comment: File
/etc/resolv.conf updated
Started:
14:49:54.703800
Duration:
40.246 ms
Changes:
----------
diff:
---
+++
@@ -1,5 +1,4 @@
# Generated by NetworkManager
nameserver 202.96.209.133
-nameserver 4.4.4.4
-nameserver 8.8.8.8
nameserver 114.114.114.114
+
Summary
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
js-93:
----------
ID: /etc/resolv.conf
Function: file.managed
Result: True
Comment: File /etc/resolv.conf updated
Started: 14:57:40.053564
Duration: 24.137 ms
Changes:
----------
diff:
---
+++
@@ -1,5 +1,4 @@
# Generated by NetworkManager
nameserver 202.96.209.133
-nameserver 4.4.4.4
-nameserver 8.8.8.8
nameserver 114.114.114.114
+
Summary
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
执行结果 查看minion结果:
# cat /etc/resolv.conf
# Generated by NetworkManager
nameserver
202.96.209.133
nameserver
114.114.114.114
其中:
- template: jinja 这里表示一个模板;
- defaults:
DNS_SERVER01: 202.96.209.133
DNS_SERVER02: 114.114.114.114
这上面三句话表示变量。
files/resolv.conf 这里面表示变量的引用。模板的名称和文件里面的名称一定要一样。
系统初始化“模块”
配置resolv.conf 文件:
# cat dns.sls
/etc/resolv.conf:
file.managed:
- source: salt://init/files/resolv.conf
- user: root
- group: root
- mode: 644
设置history的操作时间,操作用户:
# cat history.sls
/etc/profile:
file.append:
- text:
- export HISTTIMEFORMAT="%F %T `whoami`"
把操作命令已日志的方式记录到 /var/log/message 里面;
export PROMPT_COMMAND='{ msg=$(history 1|{ read x y; echo $y; });logger "":$(who am i):[`pwd`]"$msg";}'
写成 sls 文件:
# cat audit.sls
/etc/bashrc:
file.append:
- text:
- export PROMPT_COMMAND='{ msg=$(history 1|{ read x y; echo $y; });logger "":$(who am i):[`pwd`]"$msg";}'
调整内核参数:
# cat sysctl.sls
vm.swappiness: #不使用交换分区
sysctl.present:
- value: 0
net.ipv4.ip_local_port_range: #本地随机端口号范围
sysctl.present:
- value: 10000 65000
fs.file
-max: #打开的最大文件数
sysctl.present:
- value: 100000
把上面的所有初始化的内容写入到一个sls文件里面:
# cat env_init.sls
include:
- init.dns
- init.history
- init.audit
- init.sysctl
然后写入 top file文件里面 引用高级状态:
# cat top.sls
base:
'*':
- init.env_init
init.env_init:表示init目录下的 env_init.sls 文件。
执行结果:
salt '*' state.highstate test=True #test=True 测试执行,可以查看到需要更高后的结果,但是,并不会真正的改变内容。
# salt '*' state.highstate test=True
js
-93:
----------
ID:
/etc/resolv.conf
Function: file.managed
Result: True
Comment: The file
/etc/resolv.conf is in the correct state
Started:
16:07:09.456946
Duration:
8.706 ms
Changes:
----------
ID:
/etc/profile
Function: file.append
Result: None
Comment: File
/etc/profile is set to be updated
Started:
16:07:09.465787
Duration:
3.052 ms
Changes:
----------
diff:
---
+++
@@ -80,3 +80,4 @@
export PATH=/application/mysql/bin:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
export PATH=/usr/local/mysql/bin:$PATH
export PATH=/usr/local/python27/bin:$PATH
+export HISTTIMEFORMAT="%F %T `whoami`"
----------
ID: /etc/bashrc
Function: file.append
Result: None
Comment: File /etc/bashrc is set to be updated
Started: 16:07:09.468979
Duration: 3.908 ms
Changes:
----------
diff:
---
+++
@@ -84,3 +84,4 @@
unset pathmunge
fi
# vim:ts=4:sw=4
+export PROMPT_COMMAND='{ msg=$(history 1|{ read x y; echo $y; });logger "":$(who am i):[`pwd`]"$msg";}'
----------
ID: vm.swappiness
Function: sysctl.present
Result: None
Comment: Sysctl option vm.swappiness set to be changed to 0
Started: 16:07:09.474272
Duration: 29.895 ms
Changes:
----------
ID: net.ipv4.ip_local_port_range
Function: sysctl.present
Result: None
Comment: Sysctl option net.ipv4.ip_local_port_range set to be changed to 10000 65000
Started: 16:07:09.504508
Duration: 25.928 ms
Changes:
----------
ID: fs.file-max
Function: sysctl.present
Result: None
Comment: Sysctl option fs.file-max set to be changed to 100000
Started: 16:07:09.530710
Duration: 28.35 ms
Changes:
Summary
------------
Succeeded: 6 (unchanged=5, changed=2)
Failed: 0
------------
Total states run: 6
openfire2:
----------
ID: /etc/resolv.conf
Function: file.managed
Result: True
Comment: The file /etc/resolv.conf is in the correct state
Started: 15:59:44.178131
Duration: 22.931 ms
Changes:
----------
ID: /etc/profile
Function: file.append
Result: None
Comment: File /etc/profile is set to be updated
Started: 15:59:44.201484
Duration: 5.118 ms
Changes:
----------
diff:
---
+++
@@ -83,3 +83,4 @@
PATH=$PATH:$HOME/bin
PATH=$PATH:$HOME/bin:/usr/local/python27/bin
+export HISTTIMEFORMAT="%F %T `whoami`"
----------
ID: /etc/bashrc
Function: file.append
Result: None
Comment: File /etc/bashrc is set to be updated
Started: 15:59:44.206841
Duration: 7.952 ms
Changes:
----------
diff:
---
+++
@@ -84,3 +84,4 @@
unset pathmunge
fi
# vim:ts=4:sw=4
+export PROMPT_COMMAND='{ msg=$(history 1|{ read x y; echo $y; });logger "":$(who am i):[`pwd`]"$msg";}'
----------
ID: vm.swappiness
Function: sysctl.present
Result: None
Comment: Sysctl option vm.swappiness set to be changed to 0
Started: 15:59:44.218022
Duration: 67.859 ms
Changes:
----------
ID: net.ipv4.ip_local_port_range
Function: sysctl.present
Result: None
Comment: Sysctl option net.ipv4.ip_local_port_range set to be changed to 10000 65000
Started: 15:59:44.286496
Duration: 51.831 ms
Changes:
----------
ID: fs.file-max
Function: sysctl.present
Result: None
Comment: Sysctl option fs.file-max set to be changed to 100000
Started: 15:59:44.338812
Duration: 51.0 ms
Changes:
Summary
------------
Succeeded: 6 (unchanged=5, changed=2)
Failed: 0
------------
Total states run: 6
初始化 top file 的结果 salt '*' state.highstate
# salt '*' state.highstate
js
-93:
----------
ID:
/etc/resolv.conf
Function: file.managed
Result: True
Comment: File
/etc/resolv.conf updated
Started:
16:22:25.288082
Duration:
11.363 ms
Changes:
----------
diff:
---
+++
@@ -1,4 +1,4 @@
# Generated by NetworkManager
nameserver 202.96.209.133
-nameserver 4.4.4.4
+nameserver 114.114.114.114
----------
ID: /etc/profile
Function: file.append
Result: True
Comment: Appended 1 lines
Started: 16:22:25.299569
Duration: 2.153 ms
Changes:
----------
diff:
---
+++
@@ -80,3 +80,4 @@
#export PATH=/application/mysql/bin:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
export PATH=/usr/local/mysql/bin:$PATH
export PATH=/usr/local/python27/bin:$PATH
+export HISTTIMEFORMAT="%F %T `whoami`"
----------
ID: /etc/bashrc
Function: file.append
Result: True
Comment: Appended 1 lines
Started: 16:22:25.301827
Duration: 3.519 ms
Changes:
----------
diff:
---
+++
@@ -84,3 +84,4 @@
unset pathmunge
fi
# vim:ts=4:sw=4
+export PROMPT_COMMAND='{ msg=$(history 1|{ read x y; echo $y; });logger "":$(who am i):[`pwd`]"$msg";}'
----------
ID: vm.swappiness
Function: sysctl.present
Result: True
Comment: Updated sysctl value vm.swappiness = 0
Started: 16:22:25.306579
Duration: 34.697 ms
Changes:
----------
vm.swappiness:
0
----------
ID: net.ipv4.ip_local_port_range
Function: sysctl.present
Result: True
Comment: Updated sysctl value net.ipv4.ip_local_port_range = 10000 65000
Started: 16:22:25.341528
Duration: 34.841 ms
Changes:
----------
net.ipv4.ip_local_port_range:
10000 65000
----------
ID: fs.file-max
Function: sysctl.present
Result: True
Comment: Updated sysctl value fs.file-max = 100000
Started: 16:22:25.376573
Duration: 38.181 ms
Changes:
----------
fs.file-max:
100000
Summary
------------
Succeeded: 6 (changed=6)
Failed: 0
------------
Total states run: 6
openfire2:
----------
ID: /etc/resolv.conf
Function: file.managed
Result: True
Comment: File /etc/resolv.conf updated
Started: 16:14:50.016655
Duration: 28.94 ms
Changes:
----------
diff:
---
+++
@@ -1,4 +1,4 @@
# Generated by NetworkManager
nameserver 202.96.209.133
-nameserver 4.4.4.4
+nameserver 114.114.114.114
----------
ID: /etc/profile
Function: file.append
Result: True
Comment: Appended 1 lines
Started: 16:14:50.045861
Duration: 5.464 ms
Changes:
----------
diff:
---
+++
@@ -80,3 +80,4 @@
PATH=$PATH:$HOME/bin:/usr/local/python3/bin
PATH=$PATH:$HOME/bin
PATH=$PATH:$HOME/bin:/usr/local/python27/bin
+export HISTTIMEFORMAT="%F %T `whoami`"
----------
ID: /etc/bashrc
Function: file.append
Result: True
Comment: Appended 1 lines
Started: 16:14:50.051566
Duration: 8.297 ms
Changes:
----------
diff:
---
+++
@@ -84,3 +84,4 @@
unset pathmunge
fi
# vim:ts=4:sw=4
+export PROMPT_COMMAND='{ msg=$(history 1|{ read x y; echo $y; });logger "":$(who am i):[`pwd`]"$msg";}'
----------
ID: vm.swappiness
Function: sysctl.present
Result: True
Comment: Updated sysctl value vm.swappiness = 0
Started: 16:14:50.062927
Duration: 68.223 ms
Changes:
----------
vm.swappiness:
0
----------
ID: net.ipv4.ip_local_port_range
Function: sysctl.present
Result: True
Comment: Updated sysctl value net.ipv4.ip_local_port_range = 10000 65000
Started: 16:14:50.131850
Duration: 64.959 ms
Changes:
----------
net.ipv4.ip_local_port_range:
10000 65000
----------
ID: fs.file-max
Function: sysctl.present
Result: True
Comment: Updated sysctl value fs.file-max = 100000
Started: 16:14:50.197403
Duration: 67.141 ms
Changes:
----------
fs.file-max:
100000
Summary
------------
Succeeded: 6 (changed=6)
Failed: 0
------------
Total states run: 6
View Code
编译安装proxy
状态模块:状态间关系
功 能:条件判断,用于cmd状态模块
常用方法:
onlyif:检查命令,仅当“onlyif”选项指向的命令返回true时才执行name定义的命令
unless:用于检查的命令,仅当“unless”选项指向的命令返回false时才执行name指向的命令。
功能名称:requisites
功 能:处理状态间关系
常用方法:
require #我依赖某个状态
require_in #我被某个状态依赖
watch #我关注某个状态
watch_in #我被某个状态关注
已完成以后的目录结构:
# tree
.
├── haproxy
│ ├── files
│ │ ├── haproxy
-1.6.10.tar.gz
│ │ └── haproxy.init
│ └── install.sls
└── pkg
└── pkg
-init.sls
3 directories, 4 files
linux安装一个软件之前,首先要安装这个软件所依赖的软件包。因此,写一个批量安装依赖包的sls
# cat pkg/pkg-init.sls
pkg
-init:
pkg.installed:
- names:
- gcc
- gcc-c++
- glibc
- make
- autoconf
- openssl-devel
安装haproxy:通过saltstack进行远程批量安装,(当然,批量是指,minion端已经和master端进行过认证的服务器)
# cat haproxy/install.sls
include:
- pkg.pkg-init
haproxy
-install:
file.managed:
- name: /usr/local/src/haproxy-1.6.10.tar.gz
- source: salt://haproxy/files/haproxy-1.6.10.tar.gz
- user: root
- group: root
- mode: 755
cmd.run:
- name: cd /usr/local/src && tar zxf haproxy-1.6.10.tar.gz && cd haproxy-1.6.10 && make TARGET=linux26 PREFIX=/usr/local/haproxy && make install PREFIX=/usr/local/haproxy
- unless: test -d /usr/local/haproxy
- require:
- pkg: pkg-init
- file: haproxy-install
haproxy-init:
file.managed:
- name: /etc/init.d/haproxy
- source: salt://haproxy/files/haproxy.init
- user: root
- group: root
- mode: 755
- require:
- cmd: haproxy-install
cmd.run:
- name: chkconfig --add haproxy
- unless: chkconfig --list|grep haproxy
- require:
- file: haproxy-init
net.ipv4.ip_nonlocal_bind:
sysctl.present:
- value: 1
haproxy-config-dir:
file.directory:
- name: /etc/haproxy
- user: root
- group: root
- mode: 755
在 /usr/local/src 下面需要有haproxy的安装包。并且在 files下面有haproxy的启动脚本,会放在/etc/init.d下面。(启动脚本需要修改:BIN=/usr/local/haproxy/sbin/$BASENAME)
执行:salt 'openfire*' state.sls haproxy.install env=prod(这里一定要指定环境,而且,这个执行的过程比较慢,主要是yum安装依赖包,并且编译安装haproxy的配置文件。)
Saltstack配置管理-业务引用haproxy
首先要有一个haproxy.cfg的配置文件:
# cat cluster/files/haproxy-outside.cfg
global
log
127.0.0.1 local3 notice
maxconn
4096
uid
0
gid
0
daemon
defaults
log
global
mode tcp
optiontcplog
optiondontlognull
retries
3
maxconn
2000
option redispatch
timeout connect
5000
timeout client
50000
timeout server
50000
listenserver_haproxy
bind
*:8066
balance roundrobin
mode tcp
server server_01
192.168.20.93:8066weight 3 check
server server_02
192.168.20.172:8066weight 3 check
haproxy-outside.cfg 然后写一个haproxy的文件配置管理,与服务管理:
# cat cluster/haproxy-outside.sls
include:
- haproxy.install #引用上面的安装。
haproxy
-service:
file.managed:
- name: /etc/haproxy/haproxy.cfg
- source: salt://cluster/files/haproxy-outside.cfg
- user: root
- group: root
- mode: 644
service.running:
- name: haproxy
- enable: True #加入开机自启动
->
- require:
- cmd: haproxy-init
- watch: #如果检测到文件被改变,则服务会被重启
- file: haproxy-service
这里的逻辑性比较高,需要结合前面的haproxy 的配置进行解释。
然后到base目录下去编写 topfile文件:
# cat base/top.sls
base:
'*':
- init.env_init
prod:
'openfire*':
- cluster.haproxy-outside
'js-*':
- cluster.haproxy-outside
执行:salt ‘*’ state.highstate
因此:salt下的整体目录结构就是:
# tree
.
├──
base
│ ├── init #系统初始化时需要做的一些事情。
│ │ ├── audit.sls
│ │ ├── dns.sls
│ │ ├── env_init.sls
│ │ ├── files
│ │ │ └── resolv.conf
│ │ ├── history.sls
│ │ └── sysctl.sls
│ └── top.sls
├── prod
│ ├── cluster #这里主要是配置文件管理,集群安装,服务启动等等
│ │ ├── files
│ │ │ └── haproxy
-outside.cfg
│ │ └── haproxy
-outside.sls
│ ├── haproxy #这里主要是安装依赖包,安装haproxy的软件
│ │ ├── files
│ │ │ ├── haproxy
-1.6.10.tar.gz
│ │ │ └── haproxy.init
│ │ └── install.sls
│ └── pkg
│ └── pkg
-init.sls
└── test
安装keepalived
keepalived的目录结构:
# tree keepalived/
keepalived
/
├── files
│ ├── keepalived #启动脚本 ==>/usr/local/src/keepalived-1.3.5/keepalived/etc/init.d/keepalived
│ ├── keepalived
-1.3.5.tar.gz #安装包
│ ├── keepalived.conf #配置文件 ==> /usr/local/src/keepalived-1.3.5/keepalived/etc/keepalived/keepalived.conf
│ └── keepalived.sysconfig #配置文件(编译安装生成以后的文件) ==> ll /usr/local/keepalived/etc/sysconfig/keepalived
└── install.sls #saltstack安装keepalived的安装文件
其中上面的启动脚本keepalived 的 “daemon keepalived ${KEEPALIVED_OPTIONS}”要修改成为:“daemon /usr/local/keepalived/sbin/keepalived ${KEEPALIVED_OPTIONS}”
安装keepalived的sls配置文件。
# cat install.sls
include:
- pkg.pkg-init
keepalived
-install:
file.managed:
- name: /usr/local/src/keepalived-1.3.5.tar.gz
- source: salt://keepalived/files/keepalived-1.3.5.tar.gz
- user: root
- group: root
- mode: 755
cmd.run:
- name: cd /usr/local/src && tar xf keepalived-1.3.5.tar.gz && cd keepalived-1.3.5 &&./configure --prefix=/usr/local/keepalived --disable-fwmark && make && make install
- unless: test -d /usr/local/keepalived
- require:
- pkg: pkg-init
- file: keepalived-install
keepalived-init:
file.managed:
- name: /etc/init.d/keepalived
- source: salt://keepalived/files/keepalived
- user: root
- group: root
- mode: 755
cmd.run:
- name: chkconfig --add keepalived
- unless: chkconfig --list|grep keepalived
- require:
- file: keepalived-init
/etc/sysconfig/keepalived:
file.managed:
- source: salt://keepalived/files/keepalived.sysconfig
- user: root
- group: root
- mode: 644
/etc/keepalived:
file.directory:
- user: root
- group: root
执行: salt '*' state.sls keepalived.install env=prod
业务引用keepalived
keepalived+haproxy 当前的目录结构:
# tree
.
├──
base
│ ├── ;
│ ├── init
│ │ ├── audit.sls
│ │ ├── dns.sls
│ │ ├── env_init.sls
│ │ ├── files
│ │ │ └── resolv.conf
│ │ ├── history.sls
│ │ └── sysctl.sls
│ └── top.sls
├── prod
│ ├── cluster
│ │ ├── files
│ │ │ ├── haproxy
-outside.cfg
│ │ │ └── haproxy
-outside-keepalived.conf
│ │ ├── haproxy
-outside-keepalived.sls
│ │ └── haproxy
-outside.sls
│ ├── haproxy
│ │ ├── files
│ │ │ ├── haproxy
-1.6.10.tar.gz
│ │ │ └── haproxy.init
│ │ └── install.sls
│ ├── keepalived
│ │ ├── files
│ │ │ ├── keepalived
│ │ │ ├── keepalived
-1.3.5.tar.gz
│ │ │ ├── keepalived.conf
│ │ │ └── keepalived.sysconfig
│ │ └── install.sls
│ └── pkg
│ └── pkg
-init.sls
└── test
haproxy-outside-keepalived.conf 的内容为:
# cat files/haproxy-outside-keepalived.conf
! Configuration File for keepalived
global_defs{
notification_email {
saltstack@example.com
}
notification_email_from keepalived@example.com
smtp_server
127.0.0.1
smtp_connect_timeout
39
router_id {{ROUTEID}}
}
vrrp_instance haproxy_ha{
state {{STATEID}}
interface eth1
virutal_router_id
36
priority {{PRIORITYID}}
advert_int
1
authentication {
auth_type PASS
auth_pass
1111
}
virtual_ipaddress {
192.168.20.249
}
}
haproxy-outside-keepalived.conf
haproxy-outside.cfg 的内容为:
# cat files/haproxy-outside.cfg
global
maxconn
100000
chroot
/usr/local/haproxy
uid
99
gid
99
daemon
nbproc
1
pidfile
/usr/local/haproxy/logs/haproxy.pid
log
127.0.0.1 local3 info
defaults
option http
-keep-alive
maxconn
100000
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
listen stats
mode http
bind
0.0.0.0:8777
stats enable
stats uri
/haproxy-status
stats auth haproxy:saltstack
frontend frontend_www_example_com
bind
192.168.20.93:80
mode http
option httplog
log
global
default_backend backend_www_example_com
backend backend_www_example_com
option httpchk HEAD
/ HTTP/1.0
balance roundrobin
server js
-93 192.168.20.93:8080 check inter 2000 rise 30 fall 15
server openfire2
192.168.20.172:8080 check inter 2000 rise 30 fall 15
haproxy-outside.cfg
haproxy-outside-keepalived.sls 部署keepalived的sls文件:
# cat haproxy-outside-keepalived.sls
include:
- keepalived.install
keepalived
-service:
file.managed:
- name: /etc/keepalived/keepalived.conf
- source: salt://cluster/files/haproxy-outside-keepalived.conf
- user: root
- group: root
- mode: 644
- template: jinja
{%if grains['fqdn'] == 'js-93' %}
- ROUTEID: haproxy_ha
- STATEID: MASTER
- PRIORITYID: 150
{% elif grains['fqdn'] == 'openfire2' %}
- ROUTEID: haproxy_ha
- STATEID: BACKUP
- PRIORITYID: 100
{% endif %}
service.running:
- name: keepalived
- enable: True
- watch:
- file: keepalived-service
haproxy-outside-keepalived.sls
然后写入到 top file 里面:
# cat /srv/salt/base/top.sls
base:
'*':
- init.env_init
prod:
'openfire*':
- cluster.haproxy-outside
- cluster.haproxy-outside-keepalived
'js-*':
- cluster.haproxy-outside
- cluster.haproxy-outside-keepalived
增加zabbix agent
目前为止所有目录结构:
# tree srv
srv
├── pillar
│ ├── apache.sls
│ ├──
base
│ │ ├── top.sls
│ │ └── zabbix.sls
│ └── top.sls
└── salt
├──
base
│ ├
│ ├── init
│ │ ├── audit.sls
│ │ ├── dns.sls
│ │ ├── env_init.sls
│ │ ├── files
│ │ │ ├── resolv.conf
│ │ │ └── zabbix_agentd.conf
│ │ ├── history.sls
│ │ ├── sysctl.sls
│ │ └── zabbix_agent.sls
│ └── top.sls
├── prod
│ ├── cluster
│ │ ├── files
│ │ │ ├── haproxy
-outside.cfg
│ │ │ └── haproxy
-outside-keepalived.conf
│ │ ├── haproxy
-outside-keepalived.sls
│ │ └── haproxy
-outside.sls
│ ├── haproxy
│ │ ├── files
│ │ │ ├── haproxy
-1.6.10.tar.gz
│ │ │ └── haproxy.init
│ │ └── install.sls
│ ├── keepalived
│ │ ├── files
│ │ │ ├── keepalived
│ │ │ ├── keepalived
-1.3.5.tar.gz
│ │ │ ├── keepalived.conf
│ │ │ └── keepalived.sysconfig
│ │ └── install.sls
│ └── pkg
│ └── pkg
-init.sls
└── test
添加zabbix agent 用到了pillar 因此,修改了/etc/salt/master 的配置文件:
pillar_roots:
base:
- /srv/pillar/base
其中:zabbix_agent.sls 的配置如下:
# cat /srv/salt/base/init/zabbix_agent.sls
zabbix
-agent-install:
pkg.installed:
- name: zabbix-agent
file.managed:
- name: /etc/zabbix/zabbix_agentd.conf
- source: salt://init/files/zabbix_agentd.conf
- template: jinja
- defaults:
Server: {{ pillar['zabbix-agent']['Zabbix_Server'] }}
- require:
- pkg: zabbix-agent-install
service.running:
- name: zabbix-agent
- enable: True
- watch:
- pkg: zabbix-agent-install
- file: zabbix-agent-install
zabbix_agent.sls 然后在环境初始化env_init.sls 添加zabbix_agent:
# cat env_init.sls
include:
- init.dns
- init.history
- init.audit
- init.sysctl
- init.zabbix_agent
zabbix_agent.conf 的配置内容为:
# cat files/zabbix_agentd.conf |egrep-v "^#|^$"
PidFile
=/var/run/zabbix/zabbix_agentd.pid
LogFile
=/var/log/zabbix/zabbix_agentd.log
LogFileSize
=0
Server
={{ Server }} #注意这一行,这一行是用到了pillar的变量
ServerActive
=116.228.90.94
Hostname
=hezitwo
UserParameter
=mount_disk_discovery,/bin/bash /etc/zabbix/monitor_scripts/mount_disk_discovery.sh mount_disk_discovery
因为现在用了了pillar 修改了pillar的路径:/srv/pillar/base
# cat zabbix.sls
zabbix
-agent:
Zabbix_Server:
192.168.20.212
[iyunv@js
-93 base]# cat top.sls
base:
'*':
- zabbix
执行: salt '*' state.highstate 即可完成minion端的 zabbix agent的安装;
github 的文档:包含了nginx memecached pcre等等。
https://github.com/unixhot/saltbook-code
架构扩展
# lsof -i:4505
COMMAND PID USER FD TYPE DEVICE>/OFF NODE NAME
salt
-mini 19331 root 24uIPv4 17761248 0t0TCP 192.168.20.93:11393->192.168.20.93:4505 (ESTABLISHED)
salt
-mast 30477 root 12uIPv4 17759720 0t0TCP *:4505 (LISTEN)
salt
-mast 30477 root 14uIPv4 17760302 0t0TCP 192.168.20.93:4505->openfire2:24389 (ESTABLISHED)
salt
-mast 30477 root 15uIPv4 17761249 0t0TCP 192.168.20.93:4505->192.168.20.93:11393 (ESTABLISHED)
[iyunv@js
-93 base]# lsof -i:4506
COMMAND PID USER FD TYPE DEVICE>/OFF NODE NAME
salt
-mini 19331 root 13uIPv4 17759778 0t0TCP 192.168.20.93:37211->192.168.20.93:4506 (ESTABLISHED)
salt
-mast 30493 root 20uIPv4 17759741 0t0TCP *:4506 (LISTEN)
salt
-mast 30493 root 22uIPv4 17759777 0t0TCP 192.168.20.93:4506->openfire2:12236 (ESTABLISHED)
salt
-mast 30493 root 23uIPv4 17759779 0t0TCP 192.168.20.93:4506->192.168.20.93:37211 (ESTABLISHED)
可以看到 minion端和master端,保持一个长连接的模式。这个模式的好处再于,master处理的信息发送到4505,然后发送到minion端,然后处理后的结果会发送到4506 这个端口。
salt信息显示:
# yum install python-setproctitle #安装这个可以看到python启动的进程信息
[iyunv@js
-93 base]# ps -ef|grep salt
root
3148 10 17:57 ? 00:00:00 /usr/bin/python2.6 /usr/bin/salt-master -d ProcessManager #salt的中心管理进程
root
314931489 17:57 ? 00:00:00 /usr/bin/python2.6 /usr/bin/salt-master -d Maintenance
root
315031480 17:57 ? 00:00:00 /usr/bin/python2.6 /usr/bin/salt-master -d Publisher
root
315931480 17:57 ? 00:00:00 /usr/bin/python2.6 /usr/bin/salt-master -d EventPublisher
root
316031480 17:57 ? 00:00:00 /usr/bin/python2.6 /usr/bin/salt-master -d ReqServer_ProcessManager
root
31723160 18 17:57 ? 00:00:00 /usr/bin/python2.6 /usr/bin/salt-master -d MWorker
root
31733160 18 17:57 ? 00:00:00 /usr/bin/python2.6 /usr/bin/salt-master -d MWorker
root
317431609 17:57 ? 00:00:00 /usr/bin/python2.6 /usr/bin/salt-master -d MWorker
root
317531609 17:57 ? 00:00:00 /usr/bin/python2.6 /usr/bin/salt-master -d MWorker
root
317631609 17:57 ? 00:00:00 /usr/bin/python2.6 /usr/bin/salt-master -d MWorker
root
318131600 17:57 ? 00:00:00 /usr/bin/python2.6 /usr/bin/salt-master -d MWorkerQueue
root
19331 10 May31 ? 00:01:04 /usr/bin/python2.6 /usr/bin/salt-minion -d
root
32133 260180 16:49 pts/2 00:00:00 /usr/bin/python2.6 /usr/bin/salt * state.highstate
优化1: 把master 的 /etc/salt/master的 timeout修改成为: timeout: 30(如果是公网的可能会数值调大)
salt-syndic
具体使用方法可查看官当文档:Salt Syndic 这一章节
更换master 的方法:
1.先停止 minion端的 服务,以及master服务。
2.清理 minion端所有key:/etc/salt/pki 下面所有的内容,
3.修改 /etc/salt/minion :master: 192.168.20.93(修改改变的master IP地址。)
4.重启:/etc/init.d/salt-minion start
saltstack 二次开发
grains:
注释:grains 是静态的。获取一次就不会改变。
首先要在 file_roots 下面创建 _grains 的目录;然后写一个编写一个my grains 的python脚本
# pwd
/srv/salt/base/_grains
[iyunv@js
-93 _grains]# cat my_grains.py
#
!/usr/bin/env python
#coding:utf
-8
def my_grains():
'''
My Custin Grains
'''
grains = { 'key1':'val1','key2':'val2'}
return grains
然后执行:salt '*' saltutil.sync_grains 这会把自己写的grians 同步到各个minion上面;
# salt '*' saltutil.sync_grains
js
-93:
- grains.my_grains
openfire2:
- grains.my_grains
上面这一步会同步到minion端,如下:
# ll /var/cache/salt/minion/extmods/grains
total
8
-rw------- 1 root root 157 Jun2 19:07 my_grains.py
-rw------- 1 root root 382 Jun2 19:07 my_grains.pyc
# cat my_grains.py
#!/usr/bin/env python
#coding:utf-8
def my_grains():
'''
My Custin Grains
'''
grains = { 'key1':'val1','key2':'val2'}
return grains
获取自己写的 grains:
自己写的grains的结果 模块: modules
安装salt 时,自己的模块存放路径为:/usr/lib/python2.6/site-packages/salt/modules
首先要在 file_roots 下面创建一个_module 目录,然后写一个模块:
# pwd
/srv/salt/base/_modules
[iyunv@js
-93 _modules]# cat my_disk.py
#
!/usr/bin/env python
def list():
cmd
= 'df -h'
ret
= __salt__['cmd.run'](cmd)
return ret
同步到minion:
# salt '*' saltutil.sync_modules
openfire2:
- modules.my_disk
js
-93:
- modules.my_disk
minion端查看同步的模块:
# pwd
/var/cache/salt/minion/extmods/modules
# cat my_disk.py
#
!/usr/bin/env python
def list():
cmd
= 'df -h'
ret
= __salt__['cmd.run'](cmd)
return ret
执行自己写的模块:
# salt '*' my_disk.list
js
-93:
Filesystem >% Mounted on
/dev/md1 1.8T1.2T517G71% /
tmpfs
3.9G 16K3.9G 1% /dev/shm
/dev/md0 194M 59M126M32% /boot
openfire2:
Filesystem >% Mounted on
/dev/sda3 195G4.7G181G 3% /
tmpfs
1.9G 12K1.9G 1% /dev/shm
/dev/sda1 194M 27M158M15% /boot
页:
[1]