标签:案例 相关 mct eset ssh cin 习惯 hand command
相对Ad-Hoc模式下的命令方式,Playbook功能更灵活强大。使用playbook可以非常简单的配置管理多个主机系统,通过编写YAML格式文件来定制配置内容,配置内容可存储和长久使用。本节将通过案例逐步了解playbook使用方法。
本节内容都是在远程服务器sandboxMP(172.16.3.100)中完成,请使用CRT工具连接到sandboxMP(172.16.3.100)。同时需要开启server1和server2虚拟机。
Ansible playbook配置文件使用YAML格式,在文档前面章节已经使用过YAML配置文件,这里简单介绍下YAML的基本语法格式。
YAML列表内容:列表内的成员是以相同缩进开始,短线加空格开头(- ):
---
(sandboxMP) [root@sandboxmp ~]$ touch test.yaml
(sandboxMP) [root@sandboxmp ~]$ vim test.yaml
# 将下面内容写入test.yaml文件,保存退出vim
hosts: - 172.16.3.100 - 172.16.3.101 - 172.16.3.102 ...
在系统中做代码演示的时候,请注意命令提示符内容:
在python虚拟环境中使用yaml来读取test.yaml文件内容:
(sandboxMP) [root@sandboxmp ~]$ ipython Python 3.6.6 (default, Nov 26 2018, 20:00:58) Type ‘copyright‘, ‘credits‘ or ‘license‘ for more information IPython 7.1.1 -- An enhanced Interactive Python. Type ‘?‘ for help. In [1]: import yaml In [2]: f = open(‘/root/test.yaml‘) In [3]: yaml.load(f)Out[3]: {‘hosts‘: [‘172.16.3.100‘, ‘172.16.3.101‘, ‘172.16.3.102‘]}
可以看到从test.yaml文件中读取的hosts内容是一个列表。
YAML字典是使用key: value来表示,冒号后面必须加上一个空格:
(
sandboxMP) [root@sandboxmp ~]$ echo ‘‘ > test.yml (sandboxMP) [root@sandboxmp ~]$ vim test.yml # 将下面内容写入test.yaml文件,保存退出vim --- hosts: hostname: sandboxMP ipaddress: 172.16.3.100 username: root password: 1234@abcd.com ...
在python虚拟环境中使用yaml来读取test.yaml文件内容:
(sandboxMP) [root@sandboxmp ~]# ipython Python 3.6.6 (default, Nov 26 2018, 20:00:58) Type ‘copyright‘, ‘credits‘ or ‘license‘ for more information IPython 7.1.1 -- An enhanced Interactive Python. Type ‘?‘ for help. In [1]: import yaml In [2]: f = open(‘/root/test.yml‘) In [3]: yaml.load(f)Out[3]: {‘hosts‘: {‘hostname‘: ‘sandboxMP‘, ‘ipaddress‘: ‘172.16.3.100‘, ‘username‘: ‘root‘, ‘password‘: ‘1234@abcd.com‘}}
hosts内容是一个字典。
字典和列表是可以混合使用的:
(sandboxMP) [root@sandboxmp ~]$ echo ‘‘ > test.yml (sandboxMP) [root@sandboxmp ~]$ vim test.yml # 将下面内容写入test.yml文件,保存退出vim --- hosts: username: root password: 1234@abcd.com ipaddress: - 172.16.3.100 - 172.16.3.101 - 172.16.3.102 ...
读取test.yaml内容:
(sandboxMP) [root@sandboxmp ~]# ipython Python 3.6.6 (default, Nov 26 2018, 20:00:58) Type ‘copyright‘, ‘credits‘ or ‘license‘ for more information IPython 7.1.1 -- An enhanced Interactive Python. Type ‘?‘ for help. In [1]: import yaml In [2]: f = open(‘/root/test.yml‘) In [3]: yaml.load(f) {‘hosts‘: {‘username‘: ‘root‘, ‘password‘: ‘1234@abcd.com‘, ‘ipaddress‘: [‘172.16.3.100‘, ‘172.16.3.101‘, ‘172.16.3.102‘]}}
hosts是一个字典,字典中ipaddress是一个列表,除了上面用法外,列表中也是可以混合字典的。
在定义playbook任务时常会用到的一些基础组件如下:
接下来我们通过一些案例来理解一些组建的使用:
在sandboxMP(172.16.3.100)远程服务器上定义一个playbook文件用来重启远程服务:
(sandboxMP) [root@sandboxmp ~]$ mkdir tasks # 接下来测试用的文件都临时放在这个目录下 (sandboxMP) [root@sandboxmp ~]$ vim tasks/restart_sshd.yml # 写入如下内容,保存退出 ---- hosts: server # 指定远程执行主机,默认从/etc/ansible/hosts文件中读取server主机组内容 remote_user: root # 制定任务执行使用的用户 tasks: # 定义任务列表 - name: restart sshd # 任务名称 command: ‘systemctl restart sshd‘ # 调用command模块来执行ssd重启命令
在执行重启任务之前,先来登陆到server组中的远程主机,server是上一节在hosts中定义的主机组,包含了server01(172.16.3.101)和server02(172.16.3.102),使用CRT登陆server01,查看ssh服务状态:
[root@server01 ~]$ systemctl status sshd ● sshd.service - OpenSSH server daemon Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2019-02-13 10:28:18 CST; 11min ago Docs: man:sshd(8) man:sshd_config(5) Main PID: 1058 (sshd) CGroup: /system.slice/sshd.service └─1058 /usr/sbin/sshd -D
可以看到当前sshd服务启动时间是:2019-02-13 10:28:18
执行restart_sshd.yml:
ansible提供了一个命令行工具:ansible-playbook用来执行playbook,回到sandboxMP(172.16.3.100)远程服务器:
1 (sandboxMP) [root@sandboxmp ~]$ ansible-playbook --help # 查看帮助 2 ‘‘‘帮助内容省略‘‘‘ 3 4 (sandboxMP) [root@sandboxmp ~]$ ansible-playbook tasks/restart_sshd.yml 5 6 PLAY [server] *************************************************************************************************************************************************************************************** 7 8 TASK [Gathering Facts] ****************************************************************************************************************************************************************************** 9 10 ok: [192.168.31.101] 11 12 ok: [192.168.31.102] 13 14 TASK [restart sshd] ********************************************************************************************************************************************************************************* 15 16 changed: [192.168.31.101] 17 18 changed: [192.168.31.102] 19 20 PLAY RECAP ****************************************************************************************************************************************************************************************** 21 22 192.168.31.101 : ok=2 changed=1 unreachable=0 failed=0 23 24 192.168.31.102 : ok=2 changed=1 unreachable=0 failed=0 25 26 (sandboxMP) [root@sandboxmp ~]$
这时登陆server01(172.16.3.101)系统,使用systemctl status sshd查看服务状态,可以看到服务的启动时间已经发生了变化。
前面已经介绍了两个命令行工具:ansible 和 ansible-doc。ansible-playbook也是一个命令行工具,用来执行playbook文件。
ansible-playbook基本语法:nsible-playbook test.yml [options]
ansible-playbook常用命令参数:
参数 |
描述 |
-C, --check |
加上该参数后,模拟执行playbook文件,输出执行结果,不会在远程主机正真正执行 |
-e EXTRA_VARS, --extra-vars=EXTRA_VARS |
设置额外变量 |
-f FORKS, --forks=FORKS |
设置进程并发,默认5 |
-i INVENTORY, --inventory=INVENTORY |
指定hosts文件路径,默认/etc/ansible/hosts |
-l SUBSET, --limit=SUBSET |
对主机进行过滤 |
--list-hosts |
列出远程执行的主机列表 |
--list-tasks |
列出playbook文件中定义的task列表 |
--syntax-check |
检测playbook语法配置 |
--step |
同一时间只执行一个task,在执行前需要进行确认 |
-t TAGS, --tags=TAGS |
只有匹配tags内容的远程主机才会执行任务,多个tag用逗号分隔 |
除了上面介绍到的参数外还有一些认证相关设置的参数,具体内容可以通过ansible-playbook --help查看帮助。
你也可以使用上面参数来执行任务查看具体效果。
接下来再写一个playbook案例,来加深理解,这次使用file模块来创建一个文件:
(sandboxMP) [root@sandboxmp ~]$ vim tasks/touchfile.yml --- - hosts: server remote_user: root tasks: - name: touch file file: # 使用file模块 path: /tmp/touch_file.txt state: touch mode: 0600
保存文件后,先来检测下文件语法,并模拟运行下touchfile.yml:
(sandboxMP) [root@sandboxmp ~]$ ansible-playbook tasks/touchfile.yml --syntax-check
playbook: tasks/touchfile.yml # 语法检测通过,没有报错
(sandboxMP) [root@sandboxmp ~]$ ansible-playbook tasks/touchfile.yml --check
# 以下输出结果是模拟运行的结果,远程主机上并没有真正的创建文件
PLAY [server] *************************************************************************************************************************************************************************************** TASK [Gathering Facts] ****************************************************************************************************************************************************************************** ok: [172.16.3.102] ok: [172.16.3.101] TASK [touch file] *********************************************************************************************************************************************************************************** ok: [172.16.3.101] ok: [172.16.3.102] PLAY RECAP ****************************************************************************************************************************************************************************************** 192.168.31.101 : ok=2 changed=0 unreachable=0 failed=0 192.168.31.102 : ok=2 changed=0 unreachable=0 failed=0
这时候登陆到server01和server02上是没有/tmp/touch_file.txt这个文件的。 运行touchfile.yml来创建文件:
(sandboxMP) [root@sandboxmp ~]$ ansible-playbook tasks/touchfile.yml PLAY [server] *************************************************************************************************************************************************************************************** TASK [Gathering Facts] ****************************************************************************************************************************************************************************** ok: [192.168.31.101] ok: [192.168.31.102] TASK [touch file] *********************************************************************************************************************************************************************************** changed: [192.168.31.101] changed: [192.168.31.102] PLAY RECAP ****************************************************************************************************************************************************************************************** 192.168.31.101 : ok=2 changed=1 unreachable=0 failed=0 192.168.31.102 : ok=2 changed=1 unreachable=0 failed=0
登陆server01或者server02查看文件已经被创建:
[root@server02 ~]$ ls -l /tmp total 8 drwxr-xr-x 2 root root 4096 Feb 12 22:45 dir_test drwx------ 3 root root 4096 Feb 13 2019 systemd-private-5a409c6e1b194765b83da9cfb3756967-ntpd.service-39S38P -rw------- 1 root root 0 Feb 13 12:40 touch_file.txt
在task中使用模块时,可以通过使用key-value方式给模块复制,案例中使用的是冒号方式。也可以使用等号方式,多个参数用空格隔开:
--- - hosts: server remote_user: root tasks: - name: touch file file: path=/tmp/touch_file.txt state=touch mode=0600
利用playbook来给server01 和 server02安装nginx:
(sandboxMP) [root@sandboxmp ~]$ vim tasks/install_nginx.yml --- - hosts: server remote_user: root tasks: - name: add nginx repository yum: name=epel-release state=present # 确保扩展源已经安装 - name: ensure nginx is at the latest version yum: name=nginx state=latest # 确保当前安装的是最新版本 - name: ensure nginx is running service: name=nginx state=started # 确保服务已经启动
在上面的playbook中,定义了三个任务:
以上使用到的模块都可以通过命令行工具来获取帮助:
(sandboxMP) [root@sandboxmp ~]$ ansible-doc -s yum
以后写playbook使用到新的模块时,大家都可以通过命令行工具:ansible-doc来了解模块的用法,养成习惯。
运行playbook执行批量安装任务,运行结果,如下图:
细心的朋友可能会发现,在前面几个案例中,我都是直接复制的运行结果,为什么这次也放一张运行结果的截图?
这是因为ansible-playbook在任务运行的输出结果中,会用不同的颜色来标识运行结果状态:
除了要知道如何写playbook来完成自动化管理工作外,还要了解playbook的不同运行状态。
ansible还提供了一个模块:lineinfile,该模块可以用来确保某一行文本存在指定的文件中,或者用来从文件中删除指定的文本,当然可以通过正则表达式来替换某一行内容。
当我提到这个新的模块的时候你应该保持一个惯性思维,使用命令行工具ansible-doc -s lineinfile 查看下这个模块的基本用法和常用参数。因为任何一份文档都不可能面面俱到,详细介绍每一个知识点,所以你需要真正掌握的是如何在有需求的时候去自主学习。
在上一个案例中已经成功安装了nginx并运行了nginx服务,这时通过浏览器访问下面地址,可以看到nginx欢迎页面:
http://172.16.3.101 http://172.16.3.102
nginx服务默认配置实用的是80端口,登陆server01查看当前服务运行端口:
[root@server01 ~]# netstat -tnpl |grep nginx tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1591/nginx: master 接下来使用playbook利用lineinfile模块来批量修改nginx默认监听端口: (sandboxMP) [root@sandboxmp ~]$ vim tasks/modify_nginx.yml --- - hosts: server remote_user: root tasks: - name: Modify the default port lineinfile: path: /etc/nginx/nginx.conf # 指定需要修改的文件 regexp: "(.*)listen(.*) 80 (.*)" # 使用正则表达式查找需要修改的内容 line: ‘\1listen\2 8080 \3‘ # 替换后的内容,包含向后引用内容,注意这里是单引号 backrefs: yes # 启用向后引用 state: present # 使用 backrefs时需要设置state=present - name: restart nginx service: name=nginx state: restarted
playbook说明:
执行playbook:
(sandboxMP) [root@sandboxmp ~]$ ansible-playbook tasks/modify_nginx.yml PLAY [server] *************************************************************************************************************************************************************************************** TASK [Gathering Facts] ****************************************************************************************************************************************************************************** ok: [172.16.3.101] ok: [172.16.3.102] TASK [Modify the default port] ********************************************************************************************************************************************************************** changed: [172.16.3.101] changed: [172.16.3.102] TASK [restart nginx] ******************************************************************************************************************************************************************************** changed: [172.16.3.101] changed: [172.16.3.102] PLAY RECAP ****************************************************************************************************************************************************************************************** 172.16.3.101 : ok=3 changed=2 unreachable=0 failed=0 172.16.3.102 : ok=3 changed=2 unreachable=0 failed=0
任务执行完成,登陆server01 或server02查看当前nginx监听端口:
"/etc/nginx/nginx.conf" 90L, 2467C written [root@server01 ~]$ netstat -tnpl 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:8080 0.0.0.0:* LISTEN 3529/nginx: master
可以看到,nginx默认监听端口已经变成了8080,端口已经生效,这时候访问http://172.16.3.101:8080就可以看到nginx的欢迎页面了。
这个案例中实际上是存在一个问题的,由于相关的知识点还未介绍到,所以这里先预留一下问题,等到介绍到对应知识点的时候,再回过头来分析这个案例中的问题,聪明的你也可以思考下,想想是什么问题呢?
到这里你可以,根据实际工作需求,结合ansible提供的模块,多练习下playbook的编写。
使用tags标签处理任务,通过tags和任务对象进行捆绑,控制部分任务按照指定tags来执行;在执行任务的时候通过 -t 来指定使用的标签, 通过 --skip-tags 来排除使用的标签。
(sandboxMP) [root@sandboxmp ~]$ vim tasks/tag_test.yml# 新建一个playbook文件 tag_test.yml,写入下面内容保存退出 --- - hosts: server remote_user: root tasks: - name: touch file1 file: path=/tmp/file1.txt state=touch tags: tf1 - name: touch file2 file: path=/tmp/file2.txt state=touch tags: tf1 - name: touch file3 file: path=/tmp/file3.txt state=touch tags: tf3
在上面tag_test.yml文件中,定义了三个任务,分别创建了三个文件,同时给任务定义了tags,如果使用ansible-playbook /tmp/tag_test.yml执行playbook任务,三个任务都会被执行,如果只想执行第三个任务创建file3.txt,在执行playbook的时候制定tags即可:
(sandboxMP) [root@sandboxmp ~]# ansible-playbook tasks/tag_test.yml -t tf3 PLAY [server] *************************************************************************************************************************************************************************************** TASK [Gathering Facts] ****************************************************************************************************************************************************************************** ok: [192.168.31.101] ok: [192.168.31.102] # 在执行结果中可以看到只有 name为touch file3 的任务被执行了 TASK [touch file3] ********************************************************************************************************************************************************************************** changed: [192.168.31.102] changed: [192.168.31.101] PLAY RECAP ****************************************************************************************************************************************************************************************** 192.168.31.101 : ok=2 changed=1 unreachable=0 failed=0 192.168.31.102 : ok=2 changed=1 unreachable=0 failed=0
登陆server01 或者 server02可以看到/tmp/目录下只创建了一个file3.txt的文件。
标签:案例 相关 mct eset ssh cin 习惯 hand command
原文地址:https://www.cnblogs.com/jameslove/p/10927067.html