[关闭]
@zhangyy 2021-09-18T00:36:35.000000Z 字数 9203 阅读 208

ansible的Playbook

ansible系列


一: playbook介绍

image_1ffpi9bemrclkcv1ajn9g4174u9.png-425.9kB

  1. playbook 剧本是由一个或多个"play"组成的列表
  2. play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。Task
  3. 实际是调用ansible的一个module,将多个play组织在一个playbook中,即可以让它们联合起
  4. 来,按事先编排的机制执行预定义的动作
  5. Playbook 文件是采用YAML语言编写的

二: yaml 语言

2.1 yaml的语言介绍

  1. YAMLYAML Ain't Markup Language,即YAML不是标记语言。不过,在开发的这种语言时,YAML
  2. 的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)
  3. YAML是一个可读性高的用来表达资料序列的格式。YAML参考了其他多种语言,包括:XML、C语言、
  4. Python、Perl以及电子邮件格式RFC2822等。Clark Evans在2001年在首次发表了这种语言,另外Ingy
  5. döt Net与Oren Ben-Kiki也是这语言的共同设计者,目前很多最新的软件比较流行采用此格式的文件存放
  6. 配置信息,如:ubuntu,anisble,docker,kubernetes等
  7. YAML 官方网站:http://www.yaml.org
  8. ansible 官网: https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html

2.2 YAML 语言特性

  1. YAML的可读性好
  2. YAML和脚本语言的交互性好
  3. YAML使用实现语言的数据类型
  4. YAML有一个一致的信息模型
  5. YAML易于实现
  6. YAML可以基于流来处理
  7. YAML表达能力强,扩展性好

2.3 yaml 语言简介

  1. YAML语法简介
  2. 在单一文件第一行,用连续三个连字号"-" 开始,还有选择性的连续三个点号( ... )用来表示文件的
  3. 结尾
  4. 次行开始正常写Playbook的内容,一般建议写明该Playbook的功能
  5. 使用#号注释代码
  6. 缩进必须是统一的,不能空格和tab混用
  7. 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换
  8. 行来实现的
  9. YAML文件内容是区别大小写的,key/value的值均需大小写敏感
  10. 多个key/value可同行写也可换行写,同行使用,分隔
  11. key后面冒号要加一个空格 比如: key: value
  12. value可是个字符串,也可是另一个列表
  13. YAML文件扩展名通常为 yml yaml

2.4 支持的数据类型

  1. YAML 支持以下常用几种数据类型:
  2. 标量:单个的、不可再分的值
  3. 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes / 字典(dictionary
  4. 数组:一组按次序排列的值,又称为序列(sequence / 列表(list

2.5 scalar 标量

  1. key对应value
  2. name: wang
  3. age: 18
  4. 使用缩进的方式
  5. name:
  6. wang
  7. age:
  8. 18
  9. 标量是最基本的,不可再分的值,包括:
  10. 字符串
  11. 布尔值
  12. 整数
  13. 浮点数
  14. Null
  15. 时间
  16. 日期

  1. 字典由多个keyvalue构成,keyvalue之间用 :分隔, 并且 : 后面有一个空格,所有k/v可以放在一
  2. 行,或者每个 k/v 分别放在不同行
  3. 格式
  4. account: { name: wang, age: 18 }
  5. 使用缩进方式
  6. account:
  7. name: wang
  8. age: 18
  9. 范例:
  10. #不同行
  11. # An employee record
  12. name: Example Developer
  13. job: Developer
  14. skill: Elite(社会精英) #同一行,也可以将key:value放置于{}中进行表示,用,分隔多个key:value
  15. # An employee record
  16. {name: "Example Developer", job: "Developer", skill: "Elite"}

  1. List 列表
  2. 列表由多个元素组成,每个元素放在不同行,且元素前均使用"-"打头,并且 - 后有一个空格, 或者将所
  3. 有元素用 [ ] 括起来放在同一行
  4. 格式
  5. course: [ linux, golang, python ]

  1. 也可以写成以 - 开头的多行
  2. course:
  3. - linux
  4. - golang
  5. - python
  6. 数据里面也可以包含字典
  7. course:
  8. - linux: manjaro
  9. - golang: gin
  10. - python: django
  11. 范例:
  12. #不同行,行以-开头,后面有一个空格
  13. # A list of tasty fruits
  14. - Apple
  15. - Orange
  16. - Strawberry
  17. - Mango
  18. #同一行
  19. [Apple,Orange,Strawberry,Mango]
  20. 范例:YAML 表示一个家庭
  21. name: John Smith
  22. age: 41
  23. gender: Male
  24. spouse: { name: Jane Smith, age: 37, gender: Female } # 写在一行里
  25. name: Jane Smith #也可以写成多行
  26. age: 37
  27. gender: Female
  28. children: [ {name: Jimmy Smith,age: 17, gender: Male}, {name: Jenny Smith, age:
  29. 13, gender: Female}, {name: hao Smith, age: 20, gender: Male } ] #写在一行
  30. - name: Jimmy Smith #写在多行,更为推荐的写法
  31. age: 17
  32. gender: Male
  33. - {name: Jenny Smith, age: 13, gender: Female}
  34. - {name: hao Smith, age: 20, gender: Male }

2.6 三种常见的数据格式

  1. XMLExtensible Markup Language,可扩展标记语言,可用于数据交换和配置
  2. JSONJavaScript Object Notation, JavaScript 对象表记法,主要用来数据交换或配置,不支持注
  3. YAMLYAML Ain't Markup Language YAML 不是一种标记语言, 主要用来配置,大小写敏感,
  4. 不支持tab

image_1ffpj7vna1lg0urafjcv2s1a5j16.png-396kB

  1. 可以用工具互相转换,参考网站:
  2. https://www.json2yaml.com/
  3. http://www.bejson.com/json/json2yaml/

2.7 Playbook 核心组件

  1. 官方文档
  2. https://docs.ansible.com/ansible/latest/reference_appendices/playbooks_keywords.html#playbook-keywords
  3. 一个playbook 中由多个组件组成,其中所用到的常见组件类型如下:
  4. Hosts 执行的远程主机列表
  5. Tasks 任务集,由多个task的元素组成的列表实现,每个task是一个字典,一个完整的代码块功能需最少元素需包括 name task,一个name只能包括一个task
  6. Variables 内置变量或自定义变量在playbook中调用
  7. Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
  8. Handlers notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
  9. tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断

2.8 hosts 组件

  1. Hostsplaybook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts
  2. 用于指定要执行指定任务的主机,须事先定义在主机清单中
  3. one.example.com
  4. one.example.com:two.example.com
  5. 192.168.1.50
  6. 192.168.1.*
  7. Websrvs:dbsrvs #或者,两个组的并集
  8. Websrvs:&dbsrvs #与,两个组的交集
  9. webservers:!dbsrvs #在websrvs组,但不在dbsrvs组
  10. 案例:
  11. - hosts: websrvs:appsrvs

2.9 remote_user 组件

  1. remote_user: 可用于Hosttask中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可
  2. 用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户
  3. - hosts: websrvs
  4. remote_user: root
  5. tasks:
  6. - name: test connection
  7.     ping:
  8.     remote_user: magedu
  9.     sudo: yes #默认sudo为root
  10.     sudo_user:wang #sudo为wang

2.10 task列表和action组件

  1. play的主体部分是task listtask list中有一个或多个task,各个task 按次序逐个在hosts中指定的所有主
  2. 机上执行,即在所有主机上完成第一个task后,再开始第二个task
  3. task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着
  4. 多次执行是安全的,因为其结果均一致
  5. 每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。
  6. 如果未提供name,则action的结果将用于输出
  7. task两种格式:
  8. action: module arguments #示例: action: shell wall hello
  9. module: arguments #建议使用 #示例: shell: wall hello
  10. 注意:shellcommand模块后面跟命令,而非key=value
  11. 范例:
  12. [root@ansible ansible]#cat hello.yaml
  13. ---
  14. # first yaml file
  15. - hosts: websrvs
  16. remote_user: root
  17. gather_facts: no #不收集系统信息,提高执行效率
  18. tasks:
  19. - name: test network connection
  20.     ping:
  21. - name: excute command
  22.     command: wall "hello world!"

  1. 范例:
  2. ---
  3. - hosts: websrvs
  4. remote_user: root
  5. gather_facts: no
  6. tasks:
  7. - name: install httpd
  8.     yum: name=httpd
  9. - name: start httpd
  10.     service: name=httpd state=started enabled=yes

2.11 其它组件说明

  1. 某任务的状态在运行后为changed时,可通过"notify"通知给相应的handlers任务
  2. 还可以通过"tags"task 打标签,可在ansible-playbook命令上使用-t指定进行调用
  3. #SHELL脚本实现
  4. #!/bin/bash
  5. # 安装Apache
  6. yum install --quiet -y httpd
  7. # 复制配置文件
  8. cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
  9. cp/tmp/vhosts.conf /etc/httpd/conf.d/
  10. # 启动Apache,并设置开机启动
  11. systemctl enable --now httpd
  12. #Playbook实现
  13. ---
  14. - hosts: websrvs
  15. remote_user: root
  16. gather_facts: no
  17. tasks:
  18. - name: "安装Apache"
  19.     yum: name=httpd
  20. - name: "复制配置文件"
  21.     copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
  22. - name: "复制配置文件"
  23.     copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/
  24. - name: "启动Apache,并设置开机启动"
  25.     service: name=httpd state=started enabled=yes

2.12 playbook 命令

  1. 格式
  2. ansible-playbook <filename.yml> ... [options]
  3. 常见选项:
  4. --syntax-check #语法检查,可缩写成--syntax, 相当于bash -n
  5. -C --check #模拟执行,只检测可能会发生的改变,但不真正执行操作,dry run
  6. --list-hosts #列出运行任务的主机
  7. --list-tags #列出tag
  8. --list-tasks #列出task
  9. --limit 主机列表 #只针对主机列表中的特定主机执行
  10. -i INVENTORY #指定主机清单文件,通常一个项对应一个主机清单文件
  11. --start-at-task START_AT_TASK #从指定task开始执行,而非从头开始,START_AT_TASK为任务的
  12. name
  13. -v -vv -vvv #显示过程

2.12.1 利用playbook 创建用户

  1. - hosts: dbsrvs
  2. remote_user: root
  3. gather_facts: no
  4. tasks:
  5. - name: create group,
  6. group: name=mysql system=yes gid=306
  7. - name: create user
  8. user: name=mysql shell=/sbin/nologin system=yes group=mysql uid=306 home=/data/mysql create_home=no

image_1ffpmt36afes1pdhrs0a1h1idq1j.png-86kB

  1. ansible-playbook -C create-mysql.yaml

image_1ffpmuk3t94ca7j53o19mj1b5o20.png-147kB

  1. ansible-playbook create-mysql.yaml

image_1ffpmv980951cic1ar61en1el2d.png-139.6kB

  1. ansible dbsrvs -m shell -a "finger mysql"

image_1ffpn0t9o1s8911031jcp163s1r252q.png-93.8kB

2.12.2 利用ansible 安装nginx

  1. ---
  2. - hosts: dbsrvs
  3. remote_user: root
  4. gather_facts: no
  5. tasks:
  6. - name: install nginx
  7. yum: name=nginx state=present
  8. - name: started nginx
  9. service: name=nginx state=started enabled=yes

image_1ffpngtji1ng01dd38cb17di1fh337.png-144.5kB

image_1ffpnhbt06ef1nv41mbur19cf13k.png-142.6kB


  1. nginx1.yml:
  2. ---
  3. # install nginx
  4. - hosts: websrvs
  5. remote_user: root
  6. gather_facts: no
  7. tasks:
  8. - name: add group nginx
  9. group: name=nginx state=present
  10. - name: add user nginx
  11. user: name=nginx state=present group=nginx
  12. - name: Install Nginx
  13. yum: name=nginx state=present
  14. - name: web page
  15. copy: src=/root/files/index.html dest=/usr/share/nginx/html/index.html
  16. - name: Start Nginx
  17. service: name=nginx state=started enabled=yes
  1. ansible-playbook -C nginx1.yaml
  2. ansbile-playbook nginx1.yaml --limit 192.168.100.12 [只针对其中某一台]

image_1ffq58hshrq0k0o67b383s1541.png-134.7kB

image_1ffq58uqqvr21ulm1ptc7qejdf4e.png-155.1kB


2.12.3 利用 playbook 安装和卸载 httpd

  1. 范例:
  2. httpd1.yml
  3. ---
  4. #install httpd
  5. - hosts: websrvs
  6. remote_user: root
  7. gather_facts: no
  8. tasks:
  9. - name: install httpd
  10. yum: name=httpd state=present
  11. - name: Modify config list port
  12. lineinfile:
  13. path: /etc/httpd/conf/httpd.conf
  14. regexp: '^Listen'
  15. line: 'Listen 8080'
  16. - name: Modify config data1
  17. lineinfile:
  18. path: /etc/httpd/conf/httpd.conf
  19. regexp: '^DocumentRoot "/var/www/html"'
  20. line: 'DocumentRoot "/data/html"'
  21. - name: Modify config data2
  22. lineinfile:
  23. path: /etc/httpd/conf/httpd.conf
  24. regexp: '^<Directory "/var/www/html">'
  25. line: '<Directory "/data/html">'
  26. - name: Mkdir website dir
  27. file: path=/data/html state=directory
  28. - name: Web html
  29. copy: src=/root/files/index.html dest=/data/html/
  30. - name: Start service
  31. service: name=httpd state=started enabled=yes

  1. ansible-playbook -C httpd1.yaml
  2. ansible-playbook httpd1.yaml --limit 192.168.100.13

image_1ffq6j58po52hjv7p8pkl1mko4r.png-243.2kB

image_1ffq6jkp5k9s11st141t1jc41l6j5b.png-161.7kB

  1. 卸载:httpd
  2. remove_httpd.yml
  3. ---
  4. - hosts: websrvs
  5. remote_user: root
  6. gather_facts: no
  7. tasks:
  8. - name: remove httpd package
  9. yum: name=httpd state=absent
  10. - name: remove apache user
  11. user: name=apache state=absent
  12. - name: remove config file
  13. file: name=/etc/httpd state=absent
  14. - name: remove web html
  15. file: name=/data/html/ state=absent

  1. ansible-playbook -C remove-httpd.yml
  2. ansible-playbook remove-httpd.yml --limit 192.168.100.13

image_1ffq6tg0u1jiv1ldp8toib83p5o.png-128.3kB

image_1ffq6tvlf6eg2joll91evd19dc65.png-137.8kB

2.12.4 利用 playbook 安装二进制的 MySQL 5.6

  1. vim my.cnf
  2. ---
  3. [mysqld]
  4. socket=/tmp/mysql.sock
  5. user=mysql
  6. symbolic-links=0
  7. datadir=/data/mysql
  8. innodb_file_per_table=1
  9. log-bin
  10. pid-file=/data/mysql/mysqld.pid
  11. [client]
  12. port=3306
  13. socket=/tmp/mysql.sock
  14. [mysqld_safe]
  15. log-error=/var/log/mysqld.log
  16. ---
  17. vim secure_mysql.sh
  18. ---
  19. #!/bin/bash
  20. /usr/local/mysql/bin/mysql_secure_installation <<EOF
  21. y
  22. magedu
  23. magedu
  24. y
  25. y
  26. y
  27. y
  28. EOF
  29. ---
  30. vim install_mysql.yaml
  31. ----
  32. # install mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz
  33. - hosts: websrvs
  34. remote_user: root
  35. gather_facts: no
  36. tasks:
  37. - name: install packages
  38. yum: name=libaio,perl-Data-Dumper,perl-Getopt-Long
  39. - name: create mysql group
  40. group: name=mysql gid=306
  41. - name: create mysql user
  42. user: name=mysql uid=306 group=mysql shell=/sbin/nologin system=yes create_home=no home=/data/mysql
  43. - name: copy tar to remote host and file mode
  44. unarchive: src=/data/ansible/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz dest=/usr/local/ owner=root group=root
  45. - name: create linkfile /usr/local/mysql
  46. file: src=/usr/local/mysql-5.6.46-linux-glibc2.12-x86_64 dest=/usr/local/mysql state=link
  47. - name: data dir
  48. shell: chdir=/usr/local/mysql/ ./scripts/mysql_install_db --datadir=/data/mysql --user=mysql
  49. tags: data
  50. - name: config my.cnf
  51. copy: src=/data/ansible/files/my.cnf dest=/etc/my.cnf
  52. - name: service script
  53. shell: /bin/cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
  54. - name: enable service
  55. shell: /etc/init.d/mysqld start;chkconfig --add mysqld;chkconfig mysqld on
  56. tags: service
  57. - name: PATH variable
  58. copy: content='PATH=/usr/local/mysql/bin:$PATH' dest=/etc/profile.d/mysql.sh
  59. - name: secure script
  60. script: /data/ansible/files/secure_mysql.sh
  61. tags: script
  62. ----

  1. ansible-playbook -C install_mysql.yaml
  2. ansible-playbook install_mysql.yaml --limit 192.168.100.12

image_1ffq9al7ec445pm1ikd177nui96i.png-149.8kB

image_1ffq9bekb8b2kd41td6jhm1q9m6v.png-167.3kB

image_1ffq9c550e1k18lvvfl143p14oj7c.png-110kB


添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注