YAML 语言
YAML 官方网站:
http://www.yaml.org
YAML语言特性
YAML的可读性好
YAML和脚本语言的交互性好
YAML使用实现语言的数据类型
YAML有一个一致的信息模型
YAML易于实现
YAML可以基于流来处理
YAML表达能力强,扩展性好
YAML语法简介
在单一文件第一行,用连续三个连字号“-” 开始,还有选择性的连续三个点号( … )用来表示文件的
结尾
次行开始正常写Playbook的内容,一般建议写明该Playbook的功能
使用#号注释代码
缩进必须是统一的,不能空格和tab混用
缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换
行来实现的 YAML文件内容是区别大小写的,key/value的值均需大小写敏感
多个k/v可同行写也可换行写,同行使用,分隔
v可是个字符串,也可是另一个列表
一个完整的代码块功能需最少元素需包括 name 和 task
一个name只能包括一个task
YAML文件扩展名通常为yml或yaml
YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构
(Structure)通过空格来展示,序列(Sequence)里的项用"-“来代表,Map里的键值对用”:"分隔,下
面介绍常见的数据结构。
List列表
列表由多个元素组成,且所有元素前均使用“-”打头 范例:
# A list of tasty fruits
- Apple
- Orange
- Strawberry
- Mango
#[Apple,Orange,Strawberry,Mango]
Dictionary字典
字典通常由多个key与value构成
# An employee record
name: Example Developer
job: Developer
skill: Elite
也可以将key:value放置于{}中进行表示,用,分隔多个key:value
# An employee record
{name: Example Developer, job: Developer, skill: Elite}
范例:
name: John Smith
age: 41
gender: Male
spouse:
name: Jane Smith
age: 37
gender: Female
children:
- name: Jimmy Smith
age: 17
gender: Male
- name: Jenny Smith
age 13
gender: Female
Playbook核心元素
Hosts 执行的远程主机列表
Tasks ,任务集
Variables,内置变量或自定义变量在playbook中调用
Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此
会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地
长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断
hosts 组件
Hosts:playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts
用于指定要执行指定任务的主机,须事先定义在主机清单中
one.example.com
one.example.com:two.example.com
192.168.1.50
192.168.1.*
Websrvs:dbsrvs #或者,两个组的并集
Websrvs:&dbsrvs #与,两个组的交集
webservers:!phoenix #在websrvs组,但不在dbsrvs组
范例:
- hosts: websrvs:appsrvs
remote_user 组件
remote_user: 可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可
用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户
- hosts: websrvs
remote_user: root
tasks:
- name: test connection
ping:
remote_user: magedu
sudo: yes #默认sudo为root
sudo_user:kaivi #sudo为kaivi
task列表和action组件
play的主体部分是task list,task list中有一个或多个task,各个task 按次序逐个在hosts中指定的所有主
机上执行,即在所有主机上完成第一个task后,再开始第二个task task的目的是使用指定的参数执行模
块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一
致 每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步
骤。如果未提供name,则action的结果将用于输出
task两种格式:
(1) action: module arguments
(2) module: arguments 建议使用
注意:shell和command模块后面跟命令,而非key=value
范例:
---
- hosts: websrvs
remote_user: root
tasks:
- name: install httpd
yum: name=httpd
- name: start httpd
service: name=httpd state=started enabled=yes
其它组件
某任务的状态在运行后为changed时,可通过“notify”通知给相应的handlers 任务可以通过"tags“打标
签,可在ansible-playbook命令上使用-t指定进行调用
ShellScripts VS Playbook 案例
#SHELL脚本实现
#!/bin/bash
# 安装Apache
yum install --quiet -y httpd
# 复制配置文件
cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
cp/tmp/vhosts.conf /etc/httpd/conf.d/
# 启动Apache,并设置开机启动
systemctl enable --now httpd
#Playbook实现
---
- hosts: websrvs
remote_user: root
tasks:
- name: "安装Apache"
yum: name=httpd
- name: "复制配置文件"
copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
- name: "复制配置文件"
copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/
- name: "启动Apache,并设置开机启动"
service: name=httpd state=started enabled=yes
playbook 命令
格式
常见选项
--check -C #只检测可能会发生的改变,但不真正执行操作
--list-hosts #列出运行任务的主机
--list-tags #列出tag
--list-tasks #列出task
--limit 主机列表 #只针对主机列表中的主机执行
-v -vv -vvv #显示过程
范例:
ansible-playbook file.yml --check #只检测
ansible-playbook file.yml
ansible-playbook file.yml --limit websrvs
实验一:二进制安装数据库
在centos8中,在主机centos8 192.168.32.8 中yum安装ansible,被控远程机器为192.168.32.18和192.168.32.28
[[email protected] ~]yum install ansible -y
[[email protected] ~]#ansible --version
ansible 2.8.5
config file = /etc/ansible/ansible.cfg
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible
python version = 3.6.8 (default, May 21 2019, 23:51:36) [GCC 8.2.1 20180905 (Red Hat 8.2.1-3)]
[[email protected] ~]#vi /etc/ansible/hosts
[websrvs]
192.168.32.18
192.168.32.28
[appsrvs]
192.168.32.28
基于SSH key验证
[[email protected] ~]#ssh-keygen
[[email protected] ~]#vim /etc/ssh/ssh_config
StrictHostKeyChecking no
[[email protected] ~]#ET=192.168.32; for i in 18 28;do sshpass -p centos ssh-copy-id $NET.$i ;done
把下好的安装数据库二进制包上传到新建的文件夹中
[[email protected] ~]#cd /data/ansible/
[[email protected] ansible]#cd /data/ansible/
[[email protected] ansible]#ls
mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz
编写planbook
---
#install mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz
- hosts: websrvs
remote_user: root
tasks:
- name: install packages
yum: name=libaio,perl-Data-Dumper,perl-Getopt-Long
- name: create mysql group
group: name=mysql gid=306
- name: create mysql user
user: name=mysql uid=306 group=mysql shell=/sbin/nologin system=yes create_home=no home=/data/mysql
- name: copy tar to remote host and modifity file mode
unarchive: src=/data/ansible/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz dest=/usr/local/ owner=root group=root
- name: mkdir /usr/local/mysql
file: src=/usr/local/mysql-5.6.46-linux-glibc2.12-x86_64 dest=/usr/local/mysql state=link
- name: data dir
shell: chdir=/usr/local/mysql ./scripts/mysql_install_db --datadir=/data/mysql --user=mysql
tags: data
- name: config my.cnf
copy: src=/data/ansible/my.cnf dest=/etc/my.cnf
- name: service script
shell: /bin/cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
- name: enable serbice
shell: /etc/init.d/mysqld start;chkconfig --add mysqld;chkconfig mysqld on
tags: service
- name: PATH variable
copy: content='PATH=/usr/local/mysql/bin:$PATH' dest=/etc/profile.d/mysql.sh
# - name: copy script
# script: /data/ansible/secure_mysql.sh
# tags: script
编辑配置文件:
[[email protected] ansible]#vim my.cnf
[mysqld]
socket=/tmp/mysql.sock
user=mysql
symbolic-links=0
datadir=/data/mysql
innodb_file_per_table=1
log-bin
pid-file=/tmp/mysql.pid
[client]
port=3306
socket=/tmp/mysql.sock
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/tmp/mysql.pid
如果需要数据库安全加固的话。需要编写安装加固回答脚本:
[[email protected] ansible]#vim secure_mysql.sh
#!/bin/bash
#
#********************************************************************
#Author: KAIVI
#Date: 2019-12-05
#FileName: /data/ansible/secure_mysql.sh
#Description: The test script
#Copyright (C): 2019 All rights reserved
#********************************************************************
/usr/local/mysql/bin/mysql_secure_installation <<EOF
#回车
centos
centos
y
y
y
y
EOF
运行ansible-playbook
[[email protected] ansible]#ansible-playbook install_mysql.yml
PLAY [websrvs] ****************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************
ok: [192.168.32.18]
ok: [192.168.32.28]
TASK [install packages] *******************************************************************************************
ok: [192.168.32.28]
ok: [192.168.32.18]
TASK [create mysql group] *****************************************************************************************
changed: [192.168.32.28]
changed: [192.168.32.18]
TASK [create mysql user] ******************************************************************************************
changed: [192.168.32.28]
changed: [192.168.32.18]
TASK [copy tar to remote host and modifity file mode] *************************************************************
changed: [192.168.32.28]
changed: [192.168.32.18]
TASK [mkdir /usr/local/mysql] *************************************************************************************
changed: [192.168.32.28]
changed: [192.168.32.18]
TASK [data dir] ***************************************************************************************************
changed: [192.168.32.28]
changed: [192.168.32.18]
TASK [config my.cnf] **********************************************************************************************
changed: [192.168.32.28]
changed: [192.168.32.18]
TASK [service script] *********************************************************************************************
changed: [192.168.32.18]
changed: [192.168.32.28]
TASK [enable serbice] *********************************************************************************************
changed: [192.168.32.28]
changed: [192.168.32.18]
TASK [PATH variable] **********************************************************************************************
changed: [192.168.32.18]
changed: [192.168.32.28]
PLAY RECAP ********************************************************************************************************
192.168.32.18 : ok=11 changed=9 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.32.28 : ok=11 changed=9 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
查看数据库端口3306是否起来:
[[email protected] ansible]#ansible all -m shell -a 'ss -ntl'
192.168.32.28 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 32 192.168.122.1:53 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 5 127.0.0.1:631 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6010 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6011 0.0.0.0:*
LISTEN 0 128 0.0.0.0:111 0.0.0.0:*
LISTEN 0 128 0.0.0.0:42707 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 5 [::1]:631 [::]:*
LISTEN 0 128 [::1]:6010 [::]:*
LISTEN 0 128 [::1]:6011 [::]:*
LISTEN 0 80 *:3306 *:*
LISTEN 0 128 [::]:35053 [::]:*
LISTEN 0 128 [::]:111 [::]:*
192.168.32.18 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 32 192.168.122.1:53 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 5 127.0.0.1:631 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6010 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6011 0.0.0.0:*
LISTEN 0 128 0.0.0.0:47467 0.0.0.0:*
LISTEN 0 128 0.0.0.0:111 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 5 [::1]:631 [::]:*
LISTEN 0 128 [::1]:6010 [::]:*
LISTEN 0 128 [::1]:6011 [::]:*
LISTEN 0 80 *:3306 *:*
LISTEN 0 128 [::]:35375 [::]:*
LISTEN 0 128 [::]:111 [::]:*
[[email protected] ansible]#
出现问题小结:
1.代码书写不规范
2.远程运行脚本时候的路径问题 可能需要先进入文件夹中然后才能执行
3.注意配置文件中数据库中PID的问题
4.安全加固脚本交互式回答问题
Playbook 初步小实验范例
范例:install_httpd.yml
---
#install httpd
- hosts: websrvs
remote_user: root
tasks:
- name: Install httpd
yum: name=httpd state=present
- name: Install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
- name: start service
service: name=httpd state=started enaled=yes
范例:remove_httpd.yml
#remove_httpd.yml
---
- hosts: websrvs
remote_user: root
tasks:
- name: remove httpd package
yum: name=httpd state=absent
- name: remove apache user
user: name=apache state=absent
- name: remove data file
file: name=/etc/httpd state=absent
范例:mysql_user.yml
---
- hosts: dbsrvs
remote_user: root
tasks:
- {name: create group, group: name=mysql system=yes gid=306}
- name: create user
user: name=mysql shell=/sbin/nologin system=yes group=mysql uid=306 home=/data/mysql create_home=no
范例:install_nginx.yml
---
# install nginx
- hosts: websrvs
remote_user: root
tasks:
- name: add group nginx
user: name=nginx state=present
- name: add user nginx
user: name=nginx state=present group=nginx
- name: Install Nginx
yum: name=nginx state=present
- name: Start Nginx
service: name=nginx state=started enabled=yes
Playbook中使用handlers和notify
Handlers本质是task list ,其中的task与前述的task并没有本质上的不同,用于当关注的资源发生变化
时,才会采取一定的操作.Notify对应的action可用于在每个play的最后被触发,这样可避免多次有改变
发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的
操作称为handler,也即notify中调用handler中定义的操作
案例:
---
- hosts: websrvs
remote_user: root
tasks:
- name: Install httpd
yum: name=httpd state=present
- name: Install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
notify: restart httpd
- name: ensure apache is running
service: name=httpd state=started enabled=yes
handlers:
- name: restart httpd
service: name=httpd state=restarted
案例:
---
- hosts: websrvs
remote_user: root
tasks:
- name: add group nginx
user: name=nginx state=present
- name: add user nginx
user: name=nginx state=present group=nginx
- name: Install Nginx
yum: name=nginx state=present
- name: config
copy: src=/root/config.txt dest=/etc/nginx/nginx.conf
notify:
- Restart Nginx
- Check Nginx Process
handlers:
- name: Restart Nginx
service: name=nginx state=restarted enabled=yes
- name: Check Nginx process
shell: killall -0 nginx &> /tmp/nginx.log
Playbook中使用tags组件
在playbook文件中,可以利用tags组件,为特定 task 指定标签,当在执行playbook时,可以只执行特
定tags的task,而非整个playbook文件
范例:
vim httpd.yml
---
# tags example
- hosts: websrvs
remote_user: root
tasks:
- name: Install httpd
yum: name=httpd state=present
- name: Install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
tags: conf
- name: start httpd service
tags: service
service: name=httpd state=started enabled=yes
ansible-playbook –t conf,service httpd.yml #可以同时执行多个tags