一、自动化运维
传统运维:传统运维效率低,大多工作需要人工完成,工作繁琐,容易出错,每日重复做相同的事情,没有标准化流程,脚本过多,不方便管理。
自动化运维就可以解决上面的问题。
常见自动化运维工具
Puppet:基于rubby开发,c/s架构,支持多平台,可管理配置文件、用户、cron任务、软件包、系统服务等。分为社区版和企业版,企业版支持图形化配置。
Saltstack:基于Python开发,c/s架构,支持多平台,比Puppet轻量,在远程执行命令时非常快捷,配置和使用比puppet容易,能实现puppet几乎所有的功能。
Ansible:更加简洁的自动化运维工具,不需要在客户端上安装客户端软件,基于Python开发的。可以实现批量操作系统配置、批量程序的部署、批量执行命令。
二、saltstack安装
准备两台机子做演示:
服务端(A机):192.168.10.101,主机名:lb01
客户端(B机):192.168.10.102,主机名:lb02
两台机子的hosts添加ip、主机名解析
192.168.10.101 lb01
192.168.10.102 lb02
saltstack官网:https://repo.saltstack.com/
1、服务端安装
(1)安装saltstack的yum源
[root@lb01 ~]# yum install -y https://repo.saltstack.com/yum/redhat/salt-repo-latest-2.el7.noarch.rpm
(2)安装salt-master、salt-minion
[root@lb01 ~]# yum install -y salt-master salt-minion
(3)修改配置文件
编辑/etc/salt/minion,添加一行:mastet: 127.0.0.1
(4)启动salt-master,salt-minion服务
[root@lb01 ~]# systemctl start salt-master salt-minion
2、客户端安装
(1)安装saltstack的yum源
[root@lb02 ~]# yum install -y https://repo.saltstack.com/yum/redhat/salt-repo-latest-2.el7.noarch.rpm
(2)安装salt-minion
[root@lb02 ~]# yum install -y salt-minion
(3)修改配置文件
编辑/etc/salt/minion,添加一行:mastet: lb01
(4)启动salt-minion服务
[root@lb02 ~]# systemctl start salt-minion
三、启动salt相关服务
前面中已经配置好saltstack了,就可以启动相关服务了。
服务端:systemctl start salt-master salt-minion
客户端:systemctl start salt-minion
服务端有两个端口:
4505端口:消息发布的端口
4506端口:和客户端通信的端口
客户端启动salt-minion服务后,不需要监听任何端口。
四、saltstack配置认证
master和minon的通信需要建立一个安全的通道,传输过程需要加密,所以要配置认证。
minion在第一次启动时会在/etc/salt/pki/minion/目录中生成:minion.pem 、minion.pub两个文件,其中minion.pub为公钥,它会把公钥传输给master
master在第一次启动时会在/etc/salt/pki/master/目录中生成密钥对,当master接收到minion传过来的公钥后,通过salt-key工具接受这个公钥,一旦接受后就会在/etc/salt/pki/minion/目录中存放刚刚接受的公钥,同时,客户端也会接受master传过去的公钥,把它放在/etc/salt/pki/minion/目录下,并命名为minion_master.pub。
以上过程需要使用salt-key工具来实现。
服务端认证lb02:
[root@lb01 ~]# salt-key -a lb02 The following keys are going to be accepted: Unaccepted Keys: lb02 Proceed? [n/Y] yKey for minion lb02 accepted. [root@lb01 ~]#
参数解释:
-a 后面跟主机名,认证指定主机
-A 认证所有主机
-r 跟主机名,拒绝指定主机
-R 拒绝所有主机
-d 跟主机名,删除指定主机认证
-D 删除全部主机认证
-y 省略掉交互,相当于直接按了y
查看认证:
[root@lb01 ~]# salt-keyAccepted Keys: lb02 Denied Keys: Unaccepted Keys: Rejected Keys: [root@lb01 ~]#
服务端认证自己:
[root@lb01 ~]# salt-key -a lb01 The following keys are going to be accepted: Unaccepted Keys: lb01 Proceed? [n/Y] yKey for minion lb01 accepted. [root@lb01 ~]#
查看所有认证:
[root@lb01 ~]# salt-key Accepted Keys: lb01 lb02 Denied Keys: Unaccepted Keys: Rejected Keys: [root@lb01 ~]#
五、saltstack远程执行命令
salt '*' test.ping:*表示已经认证的机子,此命令用来测试机子是否存活
[root@lb01 ~]# salt '*' --async test.ping Executed command with job ID: 20180830193658081299 [root@lb01 ~]# salt '*' test.pinglb02: True lb01: True [root@lb01 ~]#
salt '*' cmd.run "命令":可以执行系统的命令。
[root@lb01 ~]# salt '*' cmd.run "hostname"lb02: lb02 lb01: lb01 [root@lb01 ~]# [root@lb01 ~]# salt 'lb02' cmd.run "ip addr" lb02: 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:d4:7b:3e brd ff:ff:ff:ff:ff:ff inet 192.168.10.102/24 brd 192.168.10.255 scope global noprefixroute ens33 valid_lft forever preferred_lft forever inet6 fe80::6bd4:c078:46e0:e301/64 scope link noprefixroute valid_lft forever preferred_lft forever [root@lb01 ~]#
salt -L 'lb01,lb02' cmd.run "ls"
-L:表示一个列表
[root@lb01 ~]# salt -L 'lb01,lb02' cmd.run "ls" lb02: anaconda-ks.cfg keepalived-2.0.6 keepalived-2.0.6.tar.gz myproject nginx-1.14.0 nginx-1.14.0.tar.gz sample lb01: anaconda-ks.cfg centos-7-x86_64-minimal.tar.gz keepalived-2.0.6 keepalived-2.0.6.tar.gz my-cetnos7.tar nginx-1.14.0 nginx-1.14.0.tar.gz [root@lb01 ~]#
salt -E 'lb0[0-9]+' cmd.run "ls"
-E:支持正则
[root@lb01 ~]# salt -E 'lb0[0-9]+' cmd.run "ls"lb02: anaconda-ks.cfg keepalived-2.0.6 keepalived-2.0.6.tar.gz myproject nginx-1.14.0 nginx-1.14.0.tar.gz sample lb01: anaconda-ks.cfg centos-7-x86_64-minimal.tar.gz keepalived-2.0.6 keepalived-2.0.6.tar.gz my-cetnos7.tar nginx-1.14.0 nginx-1.14.0.tar.gz [root@lb01 ~]#
六、grains
grains在minion启动时会收集一些信息,比如操作系统类型、网卡ip、内核版本、CPU架构等。
1、列出所有的grains:
这里列出lb02的grains
[root@lb01 ~]# salt 'lb02' grains.lslb02: - 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 - lsb_distrib_release - 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 [root@lb01 ~]#
2、列出所有的grains项目以及值
[root@lb01 ~]# salt 'lb02' grains.itemslb02: ---------- SSDs: biosreleasedate: 05/19/2017 biosversion: 6.00 cpu_flags: - fpu - vme - de 。。。。
grains的信息不是动态的,并不会实时更新。它是在minion启动时收集的。
3、自定义信息
在minion上编辑/etc/salt/grains文件可以自定义信息,比如:
[root@lb02 ~]# vim /etc/salt/grainsrole: nginxenv: test
重启minion
[root@lb02 ~]# systemctl restart salt-minion
最后在master上获取自定义的grains:
[root@lb01 ~]# salt 'lb02' grains.item role envlb02: ---------- env: test role: nginx [root@lb01 ~]# [root@lb01 ~]# salt '*' grains.item role envlb02: ---------- env: test role: nginx lb01: ---------- env: role: [root@lb01 ~]#
可以使用-G选项:用grains去匹配主机
[root@lb01 ~]# salt -G role:nginx cmd.run 'hostname'lb02: lb02 [root@lb01 ~]# salt -G env:test cmd.run 'hostname'lb02: lb02 [root@lb01 ~]#
七、pillar
pillar跟grains不一样,pillar是在master上定义的,并且是针对minion定义的一些信息,像一些比较重要的数据(密码)可以存在pillar,还可以定义变量等。
1、配置自定义的pillar
在/etc/salt/master文件中找到以下内容:
#pillar_roots:
# base:
# – /srv/pillar
把上面的#号去掉。pillar_roots:
base:
– /srv/pillar
注意:base前面有2个空格,- /srv/pillar前面有4个空格。
修改完/etc/salt/master文件后,创建/srv/pillar目录
[root@lb01 ~]# mkdir /srv/pillar[root@lb01 ~]#
创建/srv/pillar/test.sls,dir.sls文件,此文件用于自定义pillar,文件名称可以可定义。后缀名.sls
[root@lb01 ~]# vim /srv/pillar/test.slsconf: /etc/123.conf [root@lb01 ~]# vim /srv/pillar/dir.slsdir: /etc/haha
定义top.sls文件,此文件为主入口,用于告诉master到哪里读取配置文件。
[root@lb01 ~]# vim /srv/pillar/top.slsbase: 'lb01': - test 'lb02': - dir
重启master:
[root@lb01 ~]# systemctl restart salt-master
验证:
先刷新:salt '*' saltutil.refresh_pillar
[root@lb01 ~]# salt '*' saltutil.refresh_pillarlb02: Truelb01: True [root@lb01 ~]# salt '*' pillar.item conf dirlb02: ---------- conf: dir: /etc/hahalb01: ---------- conf: /etc/123.conf dir: [root@lb01 ~]#
OK,成功。
用pillar去匹配主机:
[root@lb01 ~]# salt -I 'dir:/etc/haha' test.pinglb02: True [root@lb01 ~]# salt -I 'conf:/etc/123.conf' cmd.run 'ls'lb01: anaconda-ks.cfg centos-7-x86_64-minimal.tar.gz keepalived-2.0.6 keepalived-2.0.6.tar.gz my-cetnos7.tar nginx-1.14.0 nginx-1.14.0.tar.gz [root@lb01 ~]#
八、安装配置httpd
1、在/etc/salt/master文件中找到以下内容:
# file_roots:
# base:
# – /srv/salt/把上面的#好去掉
注意:base前面有2个空格,-的前面有4个空格,-与/srv/salt/之间有1个空格, file_roots顶格
2、创建/srv/salt,创建/srv/salt/top.sls文件
[root@lb01 ~]# mkdir /srv/salt[root@lb01 ~]# vim /srv/salt/top.slsbase: '*': - httpd
配置文件解释:
base:
'*':
– httpd注意:'*'前面有2个空格,-的前面有4个空格,-与httpd之间有1个空格,httpd表示在客户端执行httpd模块。
base要顶格
*:表示全部客户端
3、重启master服务
[root@lb01 ~]# systemctl restart salt-master
4、创建/srv/salt/httpd.sls文件
[root@lb01 ~]# vim /srv/salt/httpd.slshttpd-service: pkg.installed: - names: - httpd - httpd-devel service.running: - name: httpd - enable: True
解释:
httpd-service: #id的名字,自定义,要顶格写,:不能省略
pkg.installed: # pkg.installed是一个模块,包安装函数,前面有2个空格
– names: # 前面有4个空格,-前面4个空格,-后面1个空格
– httpd #安装包的名字,-前面6个空格,-后面1个空格
– httpd-devel #安装包的名字,-前面6个空格,-后面1个空格
service.running: #模块函数名,前面有2个空格
– name: httpd -前面4个空格,-后面1个空格,:后面1个空格
– enable: True -前面4个空格,-后面1个空格,:后面1个空格,enable: True表示开机启动
5、执行安装命令
[root@lb01 ~]# salt '*' state.highstate[root@lb01 ~]# salt '*' state.highstatelb02: ---------- ID: httpd-service Function: pkg.installed Name: httpd Result: True Comment: The following packages were installed/updated: httpd Started: 21:04:22.872488 Duration: 54650.692 ms Changes: ---------- httpd: ---------- new: 2.4.6-80.el7.centos.1 old: httpd-tools: ---------- new: 2.4.6-80.el7.centos.1 old: mailcap: 。。。
执行此命令会卡一阵子。
九、配置管理文件
1、在master上创建/srv/salt/test.sls文件
[root@lb01 ~]# vim /srv/salt/test.slsfile_test: file.managed: - name: /tmp/test.com - source: salt://test/123/1.txt - user: root - group: root - mode: 600
解释:
file_test: # 自定义的名字,顶格写,表示给配置段的名字,可以在别的配置段中引用它
file.managed: #模块名称,前面有2个空格
– name: /tmp/test.com #文件的名称,也就是拷贝文件后的名称。比如拷贝1.txt为/tmp/test.com。
– source: salt://test/123/1.txt #指定文件从哪里拷贝,这里的salt://test/123/1.txt相当于是/srv/salt/test/123/1.txt
– user: root
– group: root
– mode: 600
2、创建/srv/salt/test/123/1.txt文件
[root@lb01 ~]# mkdir /srv/salt/test/123 -p[root@lb01 ~]# echo haha > /srv/salt/test/123/1.txt[root@lb01 ~]#
3、修改top文件
修改 /srv/salt/top.sls
[root@lb01 ~]# vim /srv/salt/top.sls base: '*': - test
4、执行命令
执行:salt '*' state.highstate
[root@lb01 ~]# salt '*' state.highstatelb02: ---------- ID: file_test Function: file.managed Name: /tmp/test.com Result: True Comment: File /tmp/test.com updated Started: 21:26:07.022296 Duration: 368.138 ms Changes: ---------- diff: New file Summary for lb02 ------------ Succeeded: 1 (changed=1) Failed: 0------------ Total states run: 1Total run time: 368.138 ms lb01: ---------- ID: file_test Function: file.managed Name: /tmp/test.com Result: True Comment: File /tmp/test.com updated Started: 21:26:07.399940 Duration: 344.535 ms Changes: ---------- diff: New file Summary for lb01 ------------ Succeeded: 1 (changed=1) Failed: 0------------ Total states run: 1Total run time: 344.535 ms [root@lb01 ~]#
查看一下:
[root@lb01 ~]# ls /tmp/test.com /tmp/test.com [root@lb01 ~]# cat /tmp/test.com haha [root@lb01 ~]#
OK,拷贝成功。
十、配置管理目录
1、创建/srv/salt/test_dir.sls文件
[root@lb01 ~]# vim /srv/salt/test_dir.slsfile_dir: file.recurse: - name: /tmp/testdir - source: salt://test/123 - user: root - group: root - file_mode: 640 - dir_modr: 750 - mkdir: True - clean: False
– clean: True,删除源文件,则目标也会跟着删除,否则不会删除。
2、修改/srv/salt/top.sls文件
[root@lb01 ~]# vim /srv/salt/top.slsbase: '*': - test_dir
3、测试
[root@lb01 ~]# salt '*' state.highstatelb01:---------- ID: file_dir Function: file.recurse Name: /tmp/testdir Result: True Comment: Recursively updated /tmp/testdir Started: 21:34:32.148605 Duration: 532.356 ms Changes: ---------- /tmp/testdir/1.txt: ---------- diff: New file mode: 0640 Summary for lb01 ------------Succeeded: 1 (changed=1)Failed: 0------------ Total states run: 1 Total run time: 532.356 mslb02:---------- ID: file_dir Function: file.recurse Name: /tmp/testdir Result: True Comment: Recursively updated /tmp/testdir Started: 21:34:32.137997 Duration: 503.8 ms Changes: ---------- /tmp/testdir/1.txt: ---------- diff: New file mode: 0640 Summary for lb02 ------------Succeeded: 1 (changed=1)Failed: 0------------ Total states run: 1 Total run time: 503.800 ms [root@lb01 ~]#
查看一下:
[root@lb01 ~]# ls /tmp/testdir/1.txt [root@lb01 ~]#
注意如果源目录为空,则不会同步到minion端。
比如:在/srv/salt/test/123/目录中创建一个空目录aaa
[root@lb01 salt]# mkdir test/123/aaa[root@lb01 salt]# salt 'lb01' state.highstatelb01: ---------- ID: file_dir Function: file.recurse Name: /tmp/testdir Result: True Comment: The directory /tmp/testdir is in the correct state Started: 21:46:22.208133 Duration: 131.133 ms Changes: Summary for lb01 ------------ Succeeded: 1Failed: 0------------ Total states run: 1Total run time: 131.133 ms [root@lb01 salt]# pwd/srv/salt [root@lb01 salt]#
查看一下:
[root@lb01 salt]# ls /tmp/testdir/[root@lb01 salt]#
空目录aaa不会同步到客户端。
十一、配置管理远程命令
1、创建/srv/salt/shell_test.sls文件
[root@lb01 ~]# vim /srv/salt/shell_test.slsshell_test: cmd.script: - source: salt://test/1.sh - user: root
2、修改top.sls文件
[root@lb01 ~]# vim /srv/salt/top.slsbase: '*': - shell_test
3、创建 /srv/salt/test/1.sh脚本文件
[root@lb01 ~]# vim /srv/salt/test/1.sh#!/bin/bashtouch /tmp/111.txt [ -f /tmp/111.txt ] && echo "OK" || echo "file not found"
4、执行
[root@lb01 ~]# salt 'lb02' state.highstatelb02: ---------- ID: shell_test Function: cmd.script Result: True Comment: Command 'shell_test' run Started: 22:15:50.171486 Duration: 171.451 ms Changes: ---------- pid: 6397 retcode: 0 stderr: stdout: OK Summary for lb02 ------------ Succeeded: 1 (changed=1) Failed: 0------------ Total states run: 1Total run time: 171.451 ms [root@lb01 ~]#
十二、配置管理计划任务
1、创建/srv/salt/cron_test.sls文件
[root@lb01 ~]# vim /srv/salt/cron_test.slscron_test: cron.present: - name: /bin/touch /tmp/111.txt - user: root - minute: '*' - hour: 20 - daymonth: '*' - month: '*' - dayweek: '*'
解释:
cron_test:
cron.present:
– name: /bin/touch /tmp/111.txt
– user: root
– minute: '*'
– hour: 20
– daymonth: '*'
– month: '*'
– dayweek: '*'注意:*要用单引号引起来,当然 也可以使用file.managed模块来管理cron,因为系统的cron都是以配置文件的形式存在的。想要删除该cron,需要添加:
cron.absent:
– name: /bin/touch /tmp/111.txt
2、修改top文件
[root@lb01 ~]# vim /srv/salt/top.slsbase: '*': - cron_test
3、执行
[root@lb01 ~]# salt 'lb02' state.highstatelb02:---------- ID: cron_test Function: cron.present Name: /bin/touch /tmp/111.txt Result: True Comment: Cron /bin/touch /tmp/111.txt added to root's crontab Started: 23:46:43.517355 Duration: 1526.816 ms Changes: ---------- root: /bin/touch /tmp/111.txt Summary for lb02 ------------Succeeded: 1 (changed=1)Failed: 0------------ Total states run: 1 Total run time: 1.527 s [root@lb01 ~]#
到lb02机子上查看任务计划:
[root@lb02 ~]# crontab -l# Lines below here are managed by Salt, do not edit# SALT_CRON_IDENTIFIER:/bin/touch /tmp/111.txt* 20 * * * /bin/touch /tmp/111.txt [root@lb02 ~]#
OK,成功。
4、删除cron
前面已经创建了cron,如何删除呢?修改/srv/salt/cron_test.sls文件
[root@lb01 ~]# vim /srv/salt/cron_test.slscron_test: cron.absent: - name: /bin/touch /tmp/111.txt
然后执行即可:
[root@lb01 ~]# salt '*' state.highstate
注意:不能通过crontab -e手动修改salt的任务计划。
十三、其他命令
1、cp.get_file拷贝master上的文件到客户端
[root@lb01 ~]# salt 'lb02' cp.get_file salt://test/1.sh /tmp/123.shlb02: /tmp/123.sh [root@lb01 ~]#
2、cp.get_dir拷贝目录
[root@lb01 ~]# salt 'lb02' cp.get_dir salt://test/123 /tmp/lb02: - /tmp//123/aaa[root@lb01 ~]#
3、显示存活的minion
[root@lb01 ~]# salt-run manage.up- lb01 - lb02 [root@lb01 ~]#
4、在命令行执行master上的脚本
[root@lb01 ~]# salt '*' cmd.script salt://test/1.shlb02: ---------- pid: 7752 retcode: 0 stderr: stdout: OK lb01: ---------- pid: 41838 retcode: 0 stderr: stdout: OK [root@lb01 ~]#
十四、salt-ssh使用
salt-ssh不需要对客户端做认证,客户端也不用安装salt-minion。
1、安装salt-ssh
[root@lb01 ~]# yum install -y salt-ssh
2、修改roster配置文件
[root@lb01 ~]# vim /etc/salt/rosterlb01: host: 192.168.10.101 user: root password: 123456lb02: host: 192.168.10.102 user: root password: 123456
3、执行
先发送公钥:salt-ssh '*' test.ping -i
[root@lb01 ~]# salt-ssh '*' test.ping -iPermission denied for host lb01, do you want to deploy the salt-ssh key? (password required): [Y/n] y Password for root@lb01: lb01: True Permission denied for host lb02, do you want to deploy the salt-ssh key? (password required): [Y/n] y Password for root@lb02: lb02: True [root@lb01 ~]#
再执行:salt-ssh –key-deploy '*' -r 'w'
格式说明:salt-ssh –key-deploy '*' -r '要执行的命令'
[root@lb01 ~]# salt-ssh --key-deploy '*' -r 'w'lb01: ---------- retcode: 0 stderr: stdout: 00:20:40 up 5:13, 1 user, load average: 0.09, 0.09, 0.06 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 192.168.10.1 19:33 8.00s 4.79s 0.01s /usr/bin/python /usr/bin/salt-ssh --key-deploy * -r w lb02: ---------- retcode: 0 stderr: stdout: 00:20:40 up 5:13, 1 user, load average: 0.05, 0.03, 0.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 192.168.10.1 19:34 18:40 0.75s 0.75s -bash [root@lb01 ~]#
查看lb02的磁盘使用情况:
[root@lb01 ~]# salt-ssh --key-deploy 'lb02' -r 'df -h'lb02: ---------- retcode: 0 stderr: stdout: Filesystem Size Used Avail Use% Mounted on /dev/mapper/rhel-root 17G 1.6G 16G 10% / devtmpfs 224M 0 224M 0% /dev tmpfs 236M 12K 236M 1% /dev/shm tmpfs 236M 5.7M 230M 3% /run tmpfs 236M 0 236M 0% /sys/fs/cgroup /dev/sda1 1014M 130M 885M 13% /boot tmpfs 48M 0 48M 0% /run/user/0[root@lb01 ~]#