随着Linux运维的发展,我们可以发现,传统的linux运维有比较多的缺点:
1. 传统运维效率低,大多工作人工完成;
2. 传统运维工作繁琐,很容易出错;
3. 传统运维每日重复做相同的事情;
4. 传统运维没有标准化的流程;
5. 传统运维的脚本繁多,不方便管理。
这些缺点在公司规模较大的时候就体现得尤为明显。而自动化运维就被人们提出来,目的就是为了解决传统运维的这些问题。
目前主流的自动化运维工具有3种:Puppet
、Saltstack
和Ansible
,用的最多的还是Ansible。
Puppet:
官网:www.puppetlabs.com ,基于rubby开发,C/S架构,支持多平台,可管理配置文件、用户、cron任务、软件包、系统服务等。
分为社区版(免费)和企业版(收费),企业版支持图形化配置。
Saltstack:
官网:www.saltstack.com ,基于python开发,C/S架构,支持多平台,比puppet轻量,在远程执行命令是非常快捷。
配置和使用比puppet容易,能实现puppet几乎所有的功能。
Ansible:
官网:www.ansible.com ,更加简洁的自动化运维工具,不需要在客户端上安装agent,基于python开发,
可以实现批量操作系统配置、批量程序的部署、批量运行命令。
因为是C/S架构,所以需要安装服务端和客户端。
准备两台机器,一台作为服务端,IP:192.168.100.150,一台作为客户端,IP:192.168.100.160。
服务器
# hostnamectl status #查看hostname状态
Static hostname: localhost.localdomain
Transient hostname: status
Icon name: computer-vm
Chassis: vm
Machine ID: 8ceda531da354b5387daf27c67adbbfd
Boot ID: 4cbda1ce199d4c46a4383e818061c2df
Virtualization: vmware
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-693.el7.x86_64
Architecture: x86-64
# hostnamectl set-hostname lzx #设置hostname为lzx,重启后生效
# vim /etc/hosts #添加下面内容
192.168.100.150 lzx
192.168.100.160 lzx1
客户端
# hostnamectl status
Static hostname: localhost.localdomain
Icon name: computer-vm
Chassis: vm
Machine ID: 8ceda531da354b5387daf27c67adbbfd
Boot ID: 079465a872604f6b9b8c97d3a5a3eb31
Virtualization: vmware
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-693.el7.x86_64
Architecture: x86-64
# hostnamectl set-hostname lzx1 #设置hostname为lzx1,重启后生效
# vim /etc/hosts #添加下面内容
192.168.100.150 lzx
192.168.100.160 lzx1
在生产环境下,机器量很多的时候这样一台台去配置hosts会很浪费时间,可以去弄一个内部的DNS,自动分配hostname,无需再配置hosts。
服务器
# yum install -y https://repo.saltstack.com/yum/redhat/salt-repo-latest-2.el7.noarch.rpm #安装saltstack源
# yum install -y salt-master salt-minion #服务端安装salt-master和salt-minion
客户端
# yum install -y https://repo.saltstack.com/yum/redhat/salt-repo-latest-2.el7.noarch.rpm #安装saltstack源
# yum install -y salt-minion #客户端只需要安装salt-minion
服务器
# vim /etc/salt/minion
master: lzx
# systemctl start salt-master #启动salt-master,master会监听端口
# systemctl start salt-minion #启动salt-minion,minion不会监听任何端口
# ps aux |grep salt*
root 275 0.0 0.0 0 0 ? S< Sep10 0:00 [xfsalloc]
root 1247 0.7 4.0 389144 40656 ? Ss 02:17 0:00 /usr/bin/python /usr/bin/salt-master
root 1256 0.0 1.9 306184 19988 ? S 02:17 0:00 /usr/bin/python /usr/bin/salt-master
root 1261 0.0 3.4 469800 34212 ? Sl 02:17 0:00 /usr/bin/python /usr/bin/salt-master
root 1262 0.0 3.3 388140 33952 ? S 02:17 0:00 /usr/bin/python /usr/bin/salt-master
root 1265 0.6 4.4 402084 44972 ? S 02:17 0:00 /usr/bin/python /usr/bin/salt-master
root 1266 0.0 3.4 388992 34576 ? S 02:17 0:00 /usr/bin/python /usr/bin/salt-master
root 1267 4.5 3.5 765628 35064 ? Sl 02:17 0:04 /usr/bin/python /usr/bin/salt-master
root 1268 2.0 4.8 487020 48604 ? Sl 02:17 0:02 /usr/bin/python /usr/bin/salt-master
root 1269 2.0 4.8 487024 48600 ? Sl 02:17 0:02 /usr/bin/python /usr/bin/salt-master
root 1270 2.1 4.8 487024 48584 ? Sl 02:17 0:02 /usr/bin/python /usr/bin/salt-master
root 1277 1.9 4.8 487032 48624 ? Sl 02:17 0:02 /usr/bin/python /usr/bin/salt-master
root 1278 1.9 4.8 487032 48616 ? Sl 02:17 0:02 /usr/bin/python /usr/bin/salt-master
root 1279 0.1 3.5 462876 35004 ? Sl 02:17 0:00 /usr/bin/python /usr/bin/salt-master
root 2480 11.3 2.1 313776 21416 ? Ss 02:19 0:00 /usr/bin/python /usr/bin/salt-minion
root 2483 39.6 4.2 567384 42536 ? Sl 02:19 0:01 /usr/bin/python /usr/bin/salt-minion
root 2491 0.0 2.0 403992 20080 ? S 02:19 0:00 /usr/bin/python /usr/bin/salt-minion
# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 740/sshd
tcp 0 0 0.0.0.0:4505 0.0.0.0:* LISTEN 1261/python
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 840/master
tcp 0 0 0.0.0.0:4506 0.0.0.0:* LISTEN 1267/python
tcp6 0 0 :::22 :::* LISTEN 740/sshd
tcp6 0 0 ::1:25 :::* LISTEN 840/master
监听4505和4506端口,4505端口用来发布消息,4506端口用来在master和minion之间传输数据。
客户端
# vim /etc/salt/minion
master: lzx
# systemctl start salt-minion #启动salt-minion,minion不会监听任何端口
# ps aux |grep salt
root 1256 0.9 2.1 313776 21412 ? Ss 02:14 0:00 /usr/bin/python /usr/bin/salt-minion
root 1259 3.5 4.2 567388 42460 ? Sl 02:14 0:00 /usr/bin/python /usr/bin/salt-minion
root 1267 0.0 2.0 403992 20084 ? S 02:14 0:00 /usr/bin/python /usr/bin/salt-minion
master端和minion端通信需要建立一个安全通道,传输过程需要加密,所以得配置认证,也是通过密钥对来加密解密的。
minion端在第一次启动时,会把/etc/salt/pki/master
下生成密钥对,当master端接收到minion传过来的公钥后,通过salt-key工具接受这个公钥,一旦接受后就会在/etc/salt/pki/master/minions/
目录里存放刚刚接受的公钥;同时minion端也会接受master传过去的公钥,把它放在/etc/salt/pki/minion
目录下,并命名为minion_master.pub
。以上过程需要借助salt-key工具来实现。
# ls /etc/salt/pki/master/ #启动服务时会产生下面内容
master.pem master.pub minions minions_autosign minions_denied minions_pre minions_rejected
# ls /etc/salt/pki/minion/
minion.pem minion.pub
服务端执行
# salt-key -a lzx1 #认证主机;-a,指定对应主机名
The following keys are going to be accepted:
Unaccepted Keys: #第一次认证会提示
lzx1
Proceed? [n/Y] y #输入y
Key for minion lzx1 accepted.
# salt-key
Accepted Keys:
lzx1 #显示为绿色,表示已经通过认证
Denied Keys:
Unaccepted Keys:
lzx
Rejected Keys:
# ls /etc/salt/pki/master/minions
lzx1
# salt-key -A #-A,认证所有主机
The following keys are going to be accepted:
Unaccepted Keys:
lzx
Proceed? [n/Y] y
Key for minion lzx accepted.
# salt-key
Accepted Keys:
lzx
lzx1
Denied Keys:
Unaccepted Keys:
Rejected Keys:
客户端查看
# ls /etc/salt/pki/minion/
minion_master.pub minion.pem minion.pub #多出了minion_master.pub文件,即为master公钥
salt-key 更多用法:
-a 认证指定主机名 -A 认证所有主机
-r 拒绝指定主机名 -R 拒绝所有主机认证
-d 删除指定主机名 -D 删除全部主机认证
-y 省略交互,等于直接按了y
服务端执行
# salt '*' test.ping #* 表示所有已经签名的minion端,也可以单独指定一个
lzx1:
True
lzx:
True
# salt 'lzx1' test.ping #单独指定一个minion
lzx1:
True
# salt '*' cmd.run "hostname" #cmd.run,后面可以直接跟命令行下的命令
lzx:
lzx
lzx1:
lzx1
[root@lzx ~]# salt '*' cmd.run "ls"
lzx:
anaconda-ks.cfg
lzx1:
anaconda-ks.cfg
# salt -L 'lzx,lzx1' test.ping #支持列表;-L,表示使用列表
lzx1:
True
lzx:
True
# salt -E 'lzx[0-9]*' test.ping #支持正则;-E,表示使用正则
lzx1:
True
lzx:
True
另外,还支持grains,加-G选项;支持pillar,加-I选项,下面会介绍到。
grains是在minion启动时收集到的一些信息,比如操作系统类型、网卡ip、内核版本、CPU架构等。
# salt 'lzx' grains.ls #查看所有grains项目
lzx:
- SSDs
- biosreleasedate
- biosversion
- cpu_flags
- cpu_model
- cpuarch
- disks
- dns
- domain
- fqdn
- fqdn_ip4
- fqdn_ip6
- gid
- gpus
- groupname
- host
- hwaddr_interfaces
- id
- init
- ip4_gw
- ip4_interfaces
- ip6_gw
- ip6_interfaces
- ip_gw
- ip_interfaces
- ipv4
- ipv6
- kernel
- kernelrelease
- kernelversion
- locale_info
- localhost
- lsb_distrib_codename
- lsb_distrib_id
- machine_id
- manufacturer
- master
- mdadm
- mem_total
- nodename
- num_cpus
- num_gpus
- os
- os_family
- osarch
- oscodename
- osfinger
- osfullname
- osmajorrelease
- osrelease
- osrelease_info
- path
- pid
- productname
- ps
- pythonexecutable
- pythonpath
- pythonversion
- saltpath
- saltversion
- saltversioninfo
- selinux
- serialnumber
- server_id
- shell
- swap_total
- systemd
- uid
- username
- uuid
- virtual
- zfs_feature_flags
- zfs_support
- zmqversion
# salt 'lzx' grains.items #查看所有grains项目及具体的值
lzx:
----------
SSDs:
biosreleasedate:
05/19/2017
biosversion:
6.00
cpu_flags:
- fpu
- vme
- de
- pse
- tsc
- msr
- pae
- mce
- cx8
- apic
- sep
- mtrr
- pge
- mca
- cmov
- pat
- pse36
- clflush
- mmx
- fxsr
- sse
- sse2
- ss
- syscall
- nx
- pdpe1gb
- rdtscp
- lm
- constant_tsc
- arch_perfmon
- nopl
- xtopology
- tsc_reliable
- nonstop_tsc
- eagerfpu
- pni
- pclmulqdq
- ssse3
- cx16
- pcid
- sse4_1
- sse4_2
- x2apic
- movbe
- popcnt
- tsc_deadline_timer
- aes
- xsave
- rdrand
- hypervisor
- lahf_lm
- abm
- 3dnowprefetch
- fsgsbase
- tsc_adjust
- smep
- invpcid
- mpx
- rdseed
- smap
- clflushopt
- xsaveopt
- xsavec
- arat
cpu_model:
Intel(R) Pentium(R) Gold G5400 CPU @ 3.70GHz
cpuarch:
x86_64
disks:
- sda
- sr0
dns:
----------
domain:
ip4_nameservers:
- 8.8.8.8
- 4.4.4.4
ip6_nameservers:
nameservers:
- 8.8.8.8
- 4.4.4.4
options:
search:
sortlist:
domain:
fqdn:
lzx
fqdn_ip4:
- 192.168.100.150
fqdn_ip6:
- fe80::b6f9:83f6:f7f2:ece0
gid:
0
gpus:
|_
----------
model:
SVGA II Adapter
vendor:
unknown
groupname:
root
host:
lzx
hwaddr_interfaces:
----------
ens33:
00:0c:29:42:1c:de
lo:
00:00:00:00:00:00
id:
lzx
init:
systemd
ip4_gw:
192.168.100.2
ip4_interfaces:
----------
ens33:
- 192.168.100.150
lo:
- 127.0.0.1
ip6_gw:
False
ip6_interfaces:
----------
ens33:
- fe80::b6f9:83f6:f7f2:ece0
lo:
- ::1
ip_gw:
True
ip_interfaces:
----------
ens33:
- 192.168.100.150
- fe80::b6f9:83f6:f7f2:ece0
lo:
- 127.0.0.1
- ::1
ipv4:
- 127.0.0.1
- 192.168.100.150
ipv6:
- ::1
- fe80::b6f9:83f6:f7f2:ece0
kernel:
Linux
kernelrelease:
3.10.0-693.el7.x86_64
kernelversion:
#1 SMP Tue Aug 22 21:09:27 UTC 2017
locale_info:
----------
defaultencoding:
UTF-8
defaultlanguage:
en_US
detectedencoding:
UTF-8
localhost:
lzx
lsb_distrib_codename:
CentOS Linux 7 (Core)
lsb_distrib_id:
CentOS Linux
machine_id:
8ceda531da354b5387daf27c67adbbfd
manufacturer:
VMware, Inc.
master:
lzx
mdadm:
mem_total:
976
nodename:
lzx
num_cpus:
1
num_gpus:
1
os:
CentOS
os_family:
RedHat
osarch:
x86_64
oscodename:
CentOS Linux 7 (Core)
osfinger:
CentOS Linux-7
osfullname:
CentOS Linux
osmajorrelease:
7
osrelease:
7.4.1708
osrelease_info:
- 7
- 4
- 1708
path:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
pid:
2483
productname:
VMware Virtual Platform
ps:
ps -efHww
pythonexecutable:
/usr/bin/python
pythonpath:
- /usr/bin
- /usr/lib64/python27.zip
- /usr/lib64/python2.7
- /usr/lib64/python2.7/plat-linux2
- /usr/lib64/python2.7/lib-tk
- /usr/lib64/python2.7/lib-old
- /usr/lib64/python2.7/lib-dynload
- /usr/lib64/python2.7/site-packages
- /usr/lib/python2.7/site-packages
pythonversion:
- 2
- 7
- 5
- final
- 0
saltpath:
/usr/lib/python2.7/site-packages/salt
saltversion:
2018.3.2
saltversioninfo:
- 2018
- 3
- 2
- 0
selinux:
----------
enabled:
False
enforced:
Disabled
serialnumber:
VMware-56 4d 8f ab 54 0e 33 71-8f 77 4e 46 94 42 1c de
server_id:
933042753
shell:
/bin/sh
swap_total:
2047
systemd:
----------
features:
+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN
version:
219
uid:
0
username:
root
uuid:
ab8f4d56-0e54-7133-8f77-4e4694421cde
virtual:
VMware
zfs_feature_flags:
False
zfs_support:
False
zmqversion:
4.1.4
grains的信息并不是动态的,并不会实时更新,它是在minion启动时收集到的。我们可以根据grains收集到的一些信息,做配置管理工作。另外,grains支持自定义信息。
# vim /etc/salt/grains
role: nginx
env: test
# systemctl restart salt-minion #重启salt-minion
# salt '*' grains.item role env #查看指定grains项目
lzx1:
----------
env:
test
role:
nginx
lzx:
----------
env:
role: #可以看到,lzx1上是有指定的两个项目的,而lzx上没有
# salt -G role:nginx cmd.run 'hostname' #-G,指定grains项目执行命令,作为匹配条件
lzx1:
lzx1
pillar和grains不一样,它是在master上定义的,并且是针对minion定义的一些信息,像一些比较重要的数据(如密码)可以存在pillar里,还可以定义变量等。
# vim /etc/salt/master
pillar_roots: #顶格,否则报错
base: #相对于上一行空两格,否则报错
- /srv/pillar #相对于上一行空两格,否则报错
# systemctl restart salt-master
# ls /srv/pillar
ls: cannot access /srv/pillar: No such file or directory
# mkdir !$
mkdir /srv/pillar
# vim /srv/pillar/test.sls #写入下面内容,.sls作为后缀名便于区分
conf: /etc/123.conf
# vim /srv/pillar/top.sls #写入下面内容,top.sls作为总入口
base:
'lzx1':
- test
# salt '*' saltutil.refresh_pillar #刷新pillar
lzx1:
True
lzx:
True
# salt '*' pillar.item conf #查看指定pillar项目
lzx1:
----------
conf:
/etc/123.conf #可以看到上面定义的test.sls的内容
lzx:
----------
conf:
pillar同样可以用来作为匹配对象,如:
# salt -I 'conf:/etc/123.conf' cmd.run "w" #-I,指定pillar项目执行命令,作为匹配条件
lzx1:
04:26:11 up 5:01, 1 user, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/1 192.168.33.1 01:16 38:51 0.07s 0.07s -bash
# vim /etc/salt/master
file_roots:
base:
- /srv/salt/
# systemctl restart salt-master
# mkdir /srv/salt ; cd /srv/salt
# vim top.sls
base:
'*':
- httpd
# vim httpd.sls
httpd-service:
pkg.installed:
- names: #指定安装的服务名
- httpd
- httpd-devel
service.running:
- name: httpd #指定服务名
- enable: True #表示启动服务
# salt 'lzx' state.highstate #读取top.sls文件,并执行里面定义的sls文件
^Z
[1]+ Stopped salt 'lzx' state.highstate
# ps aux |grep yum
root 2649 8.0 2.7 327940 27612 ? S 03:47 0:00 /usr/bin/python /usr/bin/yum --quiet --assumeyes check-update --setopt=autocheck_running_kernel=false
root 2681 0.0 0.0 112704 964 pts/0 R+ 03:47 0:00 grep --color=auto yum
# fg
salt 'lzx' state.highstate
lzx:
----------
ID: httpd-service
Function: pkg.installed
Name: httpd
Result: True
Comment: The following packages were installed/updated: httpd
Started: 03:47:49.037900
Duration: 18426.528 ms
Changes:
----------
httpd:
----------
new:
2.4.6-80.el7.centos.1
old:
httpd-tools:
----------
new:
2.4.6-80.el7.centos.1
old:
mailcap:
----------
new:
2.1.41-2.el7
old:
----------
ID: httpd-service
Function: pkg.installed
Name: httpd-devel
Result: True
Comment: The following packages were installed/updated: httpd-devel
Started: 03:48:07.535416
Duration: 7518.31 ms
Changes:
----------
apr-devel:
----------
new:
1.4.8-3.el7_4.1
old:
apr-util-devel:
----------
new:
1.5.2-6.el7
old:
cyrus-sasl:
----------
new:
2.1.26-23.el7
old:
cyrus-sasl-devel:
----------
new:
2.1.26-23.el7
old:
cyrus-sasl-lib:
----------
new:
2.1.26-23.el7
old:
2.1.26-21.el7
expat-devel:
----------
new:
2.1.0-10.el7_3
old:
httpd-devel:
----------
new:
2.4.6-80.el7.centos.1
old:
libdb:
----------
new:
5.3.21-24.el7
old:
5.3.21-20.el7
libdb-devel:
----------
new:
5.3.21-24.el7
old:
libdb-utils:
----------
new:
5.3.21-24.el7
old:
5.3.21-20.el7
openldap:
----------
new:
2.4.44-15.el7_5
old:
2.4.44-5.el7
openldap-devel:
----------
new:
2.4.44-15.el7_5
old:
----------
ID: httpd-service
Function: service.running
Name: httpd
Result: True
Comment: Service httpd has been enabled, and is running
Started: 03:48:16.528163
Duration: 204.492 ms
Changes:
----------
httpd:
True
Summary for lzx
------------
Succeeded: 3 (changed=3)
Failed: 0
------------
Total states run: 3
Total run time: 26.149 s
# ps aux |grep httpd
root 2903 0.0 0.4 224020 4980 ? Ss 03:48 0:00 /usr/sbin/httpd -DFOREGROUND
apache 2904 0.0 0.2 224020 2960 ? S 03:48 0:00 /usr/sbin/httpd -DFOREGROUND
apache 2905 0.0 0.2 224020 2960 ? S 03:48 0:00 /usr/sbin/httpd -DFOREGROUND
apache 2906 0.0 0.2 224020 2960 ? S 03:48 0:00 /usr/sbin/httpd -DFOREGROUND
apache 2907 0.0 0.2 224020 2960 ? S 03:48 0:00 /usr/sbin/httpd -DFOREGROUND
apache 2908 0.0 0.2 224020 2960 ? S 03:48 0:00 /usr/sbin/httpd -DFOREGROUND
root 3100 0.0 0.0 112704 964 pts/0 R+ 03:51 0:00 grep --color=auto httpd
httpd安装成功并启动。
# vim test.sls
file_test: #自定义ID
file.managed:
- name: /tmp/lzx.com #指定minion上要替换的文件
- source: salt://test/123/1.txt #指定master上模板文件;salt:// 等同于 /srv/salt
- user: root #指定文件传到minion上的属主
- group: root #指定文件传到minion上的属组
- mode: 600 #指定文件传到minion上的权限
# mkdir -p test/123/
# cp /etc/inittab test/123/1.txt #保证master上要有模板文件
# vim top.sls
base:
'*':
- test
# salt 'lzx1' state.highstate
lzx1:
----------
ID: file_test
Function: file.managed
Name: /tmp/lzx.com
Result: True
Comment: File /tmp/lzx.com updated
Started: 04:20:06.214914
Duration: 140.874 ms
Changes:
----------
diff:
New file
Summary for lzx1
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
Total run time: 140.874 ms
到lzx1上查看
# ls -lt /tmp/lzx.com
-rw------- 1 root root 511 Sep 12 04:20 /tmp/lzx.com #文件存在,属主属组权限对应,且时间符合
# cat !$
cat /tmp/lzx.com
# inittab is no longer used when using systemd.
#
# ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target
#
# systemd uses 'targets' instead of runlevels. By default, there are two main targets:
#
# multi-user.target: analogous to runlevel 3
# graphical.target: analogous to runlevel 5
#
# To view current default target, run:
# systemctl get-default
#
# To set a default target, run:
# systemctl set-default TARGET.target
#
这样就实现master端对minion端的文件管理。
# vim test_dir.sls
file_dir: #自定义ID
file.recurse:
- name: /tmp/testdir #指定minion上要替换的目录
- source: salt://test/123 #指定master上的模板目录
- user: root #指定目录传到minion上的属主
- file_mode: 640 #指定目录中文件传到minion上的权限
- dir_mode: 750 #指定目录传到minion上的权限
- mkdir: True #表示自动创建模板目录
- clean: True #加上之后,指定master删除源文件或目录,minion上也会同步删除,否则不删除
# vim top.sls
base:
'*':
- test
- test_dir
# salt 'lzx1' state.highstate
lzx1:
----------
ID: file_test
Function: file.managed
Name: /tmp/lzx.com
Result: True
Comment: File /tmp/lzx.com is in the correct state
Started: 04:40:43.047724
Duration: 88.949 ms
Changes:
----------
ID: file_dir
Function: file.recurse
Name: /tmp/testdir
Result: True
Comment: Recursively updated /tmp/testdir
Started: 04:40:43.136910
Duration: 122.871 ms
Changes:
----------
/tmp/testdir/1.txt:
----------
diff:
New file
mode:
0640
Summary for lzx1
------------
Succeeded: 2 (changed=1)
Failed: 0
------------
Total states run: 2
Total run time: 211.820 ms
到lzx1上查看
# ls -l /tmp/testdir/
total 4
-rw-r----- 1 root root 511 Sep 12 04:40 1.txt
# ls -ld /tmp//testdir/
drwxr-x--- 2 root root 19 Sep 12 04:40 /tmp//testdir/
# cd test
# ls
123
# mkdir abc
# touch aaa.txt
# ls
123 aaa.txt abc
# mv abc/ 123/
# mv aaa.txt 123/
# salt 'lzx1' state.highstate
lzx1:
----------
ID: file_test
Function: file.managed
Name: /tmp/lzx.com
Result: True
Comment: File /tmp/lzx.com is in the correct state
Started: 05:28:02.256768
Duration: 71.776 ms
Changes:
----------
ID: file_dir
Function: file.recurse
Name: /tmp/testdir
Result: True
Comment: Recursively updated /tmp/testdir
Started: 05:28:02.328907
Duration: 182.866 ms
Changes:
----------
/tmp/testdir/aaa.txt:
----------
diff:
New file
mode:
0640
Summary for lzx1
------------
Succeeded: 2 (changed=1)
Failed: 0
------------
Total states run: 2
Total run time: 254.642 ms
# ls -l
total 0
drwxr-xr-x 3 root root 45 Sep 12 05:26 123
# tree
.
└── 123
├── 1.txt
├── aaa.txt
└── abc
2 directories, 2 files
到lzx1上查看
# tree /tmp/testdir/
/tmp/testdir/
├── 1.txt
└── aaa.txt
0 directories, 2 files
发现没有同步abc/ 目录,这是因为salt不同步空目录。
# touch 123/abc/2.txt
# salt 'lzx1' state.highstate
lzx1:
----------
ID: file_test
Function: file.managed
Name: /tmp/lzx.com
Result: True
Comment: File /tmp/lzx.com is in the correct state
Started: 05:36:01.999480
Duration: 112.723 ms
Changes:
----------
ID: file_dir
Function: file.recurse
Name: /tmp/testdir
Result: True
Comment: Recursively updated /tmp/testdir
Started: 05:36:02.112490
Duration: 200.572 ms
Changes:
----------
/tmp/testdir/abc:
----------
/tmp/testdir/abc:
New Dir
/tmp/testdir/abc/2.txt:
----------
diff:
New file
mode:
0640
Summary for lzx1
------------
Succeeded: 2 (changed=1)
Failed: 0
------------
Total states run: 2
Total run time: 313.295 ms
到lzx1上查看
# tree /tmp/testdir/
/tmp/testdir/
├── 1.txt
├── aaa.txt
└── abc
└── 2.txt
1 directory, 3 files
发现abc/ 目录同步了过来,即使abc/ 目录中有个空文件,但只要不是空目录就行。
# cd ..
# vim shell_test.sls
shell_test: #自定义ID
cmd.script:
- source: salt://test/1.sh #指定要执行的脚本
- user: root #指定执行脚本的用户
# vim test/1.sh #写入下面内容
#!/bin/bash
touch /tmp/111.txt
if [ ! -d /tmp/1233 ]
then
mkdir /tmp/1233
fi
# vim top.sls
base:
'*':
- shell_test
# salt 'lzx1' state.highstate
lzx1:
----------
ID: shell_test
Function: cmd.script
Result: True
Comment: Command 'shell_test' run
Started: 21:17:49.175979
Duration: 80.257 ms
Changes:
----------
pid:
1099
retcode:
0
stderr:
stdout:
Summary for lzx1
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
Total run time: 80.257 ms
到lzx1上查看
# ls -lt /tmp
total 4
drwxr-xr-x 2 root root 6 Sep 12 21:17 1233
-rw-r--r-- 1 root root 0 Sep 12 21:17 111.txt
srwx------ 1 mongod mongod 0 Sep 12 20:40 mongodb-27019.sock
drwx------ 3 root root 17 Sep 12 20:40 systemd-private-a58fd593274d46159203958328d8889f-chronyd.service-rue1z2
drwxr-x--- 3 root root 45 Sep 12 05:36 testdir
-rw------- 1 root root 511 Sep 12 04:20 lzx.com
可以看到创建的1233
目录,说明脚本成功执行。
# vim cron_test.sls
cron-test:
cron.present:
- name: /bin/touch /tmp/www.txt #命令要用绝对路径,指定要执行的任务计划
- user: root #指定执行任务计划的用户
- minute: '*'
- hour: 20
- daymonth: '*'
- month: '*'
- dayweek: '*'
*
要用单引号括起来,我们可以用file.managed
模块来管理cron。
# vim top.sls
base:
'*':
- cron_test
# salt 'lzx1' state.highstate
lzx1:
----------
ID: cron-test
Function: cron.present
Name: /bin/touch /tmp/www.txt
Result: True
Comment: Cron /bin/touch /tmp/www.txt already present
Started: 21:57:03.577338
Duration: 140.875 ms
Changes:
Summary for lzx1
------------
Succeeded: 1
Failed: 0
------------
Total states run: 1
Total run time: 140.875 ms
到lzx1上查看
# crontab -l
# Lines below here are managed by Salt, do not edit
# SALT_CRON_IDENTIFIER:/bin/touch /tmp/www.txt
* 20 * * * /bin/touch /tmp/www.txt #有计划任务
计划任务上面的两行不能修改,否则master端无法管理minion的cron。
# vim cron_test.sls
cron-test:
cron.absent:
- name: /bin/touch /tmp/www.txt
# salt 'lzx1' state.highstate
lzx1:
----------
ID: cron-test
Function: cron.absent
Name: /bin/touch /tmp/www.txt
Result: True
Comment: Cron /bin/touch /tmp/www.txt removed from root's crontab
Started: 22:02:36.094802
Duration: 287.551 ms
Changes:
----------
root:
/bin/touch /tmp/www.txt
Summary for lzx1
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
Total run time: 287.551 ms
到lzx1上查看
# crontab -l
# Lines below here are managed by Salt, do not edit #已经没有了touch /tmp/www.txt的计划任务
cp.get_file
拷贝master上的文件到minion上:# ls test
123 1.sh
# salt '*' cp.get_file salt://test/1.sh /tmp/123.sh #拷贝test/1.sh到minion上,master上文件不存在时会无法拷贝
lzx1:
/tmp/123.sh
lzx:
/tmp/123.sh
# ls /tmp
123.sh
systemd-private-340efaf7bd0145018059f8fc09350b64-chronyd.service-02xcwz
systemd-private-340efaf7bd0145018059f8fc09350b64-httpd.service-KEEBwq
cp.get_dir
拷贝master上目录到minion上:# ls test/123/
1.txt aaa.txt abc
# salt '*' cp.get_dir salt://test/123 /tmp #拷贝目录,master上目录不存在时会无法拷贝
lzx1:
- /tmp/123/1.txt
- /tmp/123/aaa.txt
- /tmp/123/abc/2.txt
lzx:
- /tmp/123/1.txt
- /tmp/123/aaa.txt
- /tmp/123/abc/2.txt
# ls /tmp/123
1.txt aaa.txt abc
需要注意的是,cp.get_dir
拷贝目录时会自动在minion端创建目录,所以/tmp
后面不要加目录,如果写成/tmp/123
则会形成/tmp/123/123
目录。
salt-run manage.up
显示存活的minion:# salt-run manage.up #显示存活的minion
- lzx
- lzx1
salt '*' cmd.script
命令行执行master上的shell脚本:# salt '*' cmd.script salt://test/1.sh #命令行执行master上的shell脚本
lzx1:
----------
pid:
1567
retcode:
0
stderr:
stdout:
lzx:
----------
pid:
6436
retcode:
0
stderr:
stdout:
salt-ssh不需要对客户端做认证,客户端也不用安装salt-minion,有点类似于expect。
# yum install -y salt-ssh
# vim /etc/salt/roster
lzx:
host: 192.168.100.150
user: root #使用root用户
passwd: lzxlzxlzx #指定root密码
lzx1:
host: 192.168.100.160
user: root
passwd: lzxlzxlzx
# salt-ssh --key-deploy '*' -r 'w'
# 第一次执行的时候会自动把本机的公钥放到minion上,之后就可以把roster里面的密码器啊去掉
lzx1:
----------
retcode:
254
stderr:
stdout:
The host key needs to be accepted, to auto accept run salt-ssh with the -i flag:
The authenticity of host '192.168.33.160 (192.168.33.160)' can't be established.
ECDSA key fingerprint is SHA256:ZPsmO+OKZbdZegsq2gmGWqhl7fBOCbSljaF/K159vMQ.
ECDSA key fingerprint is MD5:a6:61:af:87:78:db:c7:38:69:1b:ac:bc:e1:fa:51:7e.
Are you sure you want to continue connecting (yes/no)?
lzx:
----------
retcode:
254
stderr:
stdout:
The host key needs to be accepted, to auto accept run salt-ssh with the -i flag:
The authenticity of host '192.168.33.150 (192.168.33.150)' can't be established.
ECDSA key fingerprint is SHA256:ZPsmO+OKZbdZegsq2gmGWqhl7fBOCbSljaF/K159vMQ.
ECDSA key fingerprint is MD5:a6:61:af:87:78:db:c7:38:69:1b:ac:bc:e1:fa:51:7e.
Are you sure you want to continue connecting (yes/no)?
上面没有执行成功,是因为第一次执行,需要我们输入yes。
# ssh lzx
\The authenticity of host 'lzx (192.168.33.150)' can't be established.
ECDSA key fingerprint is SHA256:ZPsmO+OKZbdZegsq2gmGWqhl7fBOCbSljaF/K159vMQ.
ECDSA key fingerprint is MD5:a6:61:af:87:78:db:c7:38:69:1b:ac:bc:e1:fa:51:7e.
Are you sure you want to continue connecting (yes/no)? yes //输入yes
Warning: Permanently added 'lzx' (ECDSA) to the list of known hosts.
root@lzx's password: #输入密码
Last login: Wed Sep 12 21:04:51 2018 from 192.168.33.1
# ssh lzx1
The authenticity of host 'lzx1 (192.168.33.160)' can't be established.
ECDSA key fingerprint is SHA256:ZPsmO+OKZbdZegsq2gmGWqhl7fBOCbSljaF/K159vMQ.
ECDSA key fingerprint is MD5:a6:61:af:87:78:db:c7:38:69:1b:ac:bc:e1:fa:51:7e.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'lzx1' (ECDSA) to the list of known hosts.
root@lzx1's password:
Last failed login: Wed Sep 12 22:41:43 EDT 2018 from 192.168.33.150 on ssh:notty
There was 1 failed login attempt since the last successful login.
Last login: Wed Sep 12 22:02:36 2018
# salt-ssh --key-deploy '*' -r 'w'
lzx1:
----------
retcode:
0
stderr:
stdout:
22:42:55 up 1:39, 1 user, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.33.1 21:04 32:55 0.01s 0.01s -bash
lzx:
----------
retcode:
0
stderr:
stdout:
22:42:55 up 1:39, 1 user, load average: 0.02, 0.04, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.33.1 21:04 7.00s 0.62s 0.01s /usr/bin/python /usr/bin/salt-ssh --key-deploy * -r w
这次执行就没问题了。
lzx上查看
# ls -l ~/.ssh/authorized_keys
-rw------- 1 root root 390 Sep 12 22:37 /root/.ssh/authorized_keys
# date
Wed Sep 12 22:45:06 EDT 2018
lzx1上查看
# ls -l ~/.ssh/authorized_keys
-rw------- 1 root root 390 Sep 12 22:37 /root/.ssh/authorized_keys
# cat !$
cat ~/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDQGI/0xyhDa4MfvIl2DSEjVvH7ktk/PmKul6RFJwpKXa/U78BTyXIOnyOu2CPgFBuUX6AOPMXswzHYoiSQP49D6R2n9Hv8g1gQ54Y8H6zAUQXGjHFcoSH5HPwXGgS3TMWXc3tzL6k0acqKE2e13cacgswV8qmHODXJADEkXy1rmruTHbFDI17V3cfc66uWkS0NMjlajj0of+G/9kGLCp1z0YlFxsWiMVQ9LdxZzXCeXALpa53p2Tyj5B80HBD88MDxaIBkJagAK8G+Sr9ksZ6y6TEYPW6DcujxqIOuckxZ7DSQz4hxONAjEwFF2/B7hzPD8A/elXD2hnf3rNDnS9bz root@lzx
# vim /etc/salt/roster
lzx:
host: 192.168.100.150
user: root
lzx1:
host: 192.168.100.160
user: root
# salt-ssh --key-deploy '*' -r 'w'
lzx:
----------
retcode:
0
stderr:
stdout:
22:58:11 up 1:54, 1 user, load average: 0.01, 0.05, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.33.1 21:04 3.00s 0.72s 0.00s /usr/bin/python /usr/bin/salt-ssh --key-deploy * -r w
lzx1:
----------
retcode:
0
stderr:
stdout:
22:58:11 up 1:54, 1 user, load average: 0.00, 0.03, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.33.1 21:04 3:07 0.02s 0.02s -bash
删除密码后,再次执行也不存在问题,这是因为已经把公钥推送到客户端了。
更多资料参考:
saltstack 全面介绍