• 【ansible】自动化运维ansible之playbook剧本编写与运行


    目录

    一、ansible剧本playbook的组成

    二、palybook的基础应用:

    实操1:通过palybooks完成nginx的安装

    第一种:通过yum安装nginx

    第二种:通过编译安装nginx

    实操2:playbook定义、引用变量​​​​​​​

    实操3:通过playbook完成普通账户权限提权为root用户

    实操4:通过when条件判断指定主机完成相应的任务

    实操5:通过with_items循环实现在远程主机上关闭服务、创建文件和目录

    实操6:基于templates模块,完成nginx服务的配置模板

    实操7:基于tags标签,指定完成特定的任务模块

    合并:综合多模块

    三、关于playbook的知识点总结


    一、ansible剧本playbook的组成

    (1)Tasks:任务,即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行
    (2)Variables:变量
    (3)Templates:模板
    (4)Handlers:处理器,当changed状态条件满足时,(notify)触发执行的操作
    (5)Roles:角色

    二、palybook的基础应用:

    实操1:通过palybooks完成nginx的安装

    第一种:通过yum安装nginx

    完成playbook剧本的编写,并完成语法检查

    1. #定义剧本名称为nginx安装
    2. - name: install nginx
    3. #表示捕收剂facts信息
    4. gather_facts: false
    5. #指定指定此play的远程主机组
    6. hosts: webservers
    7. #指定运行此play的用户
    8. remote_user: root
    9. #指定当前play的任务列表
    10. tasks:
    11. #关闭防火墙和selinux
    12. - name: disabled firewalld
    13. service: name=firewalld state=stopped enabled=no
    14. - name: disable selinux
    15. command: '/sbin/setenforce 0'
    16. ignore_errors: yes
    17. - name: disabled selinux forever
    18. replace: path=/etc/selinux/config regexp=enforcing replace=disabled after=loaded
    19. #将nginx的repo文件传输给远程主机
    20. - name: copy nginx repo
    21. copy: src=/etc/yum.repos.d/nginx.repo dest=/etc/yum.repos.d/nginx.repo
    22. #通过yum安装nginx
    23. - name: install nginx by yum
    24. yum: name=nginx state=latest
    25. #安装nginx
    26. - name: start nginx service
    27. systemd: name=nginx state=started enabled=yes

     

    验证

     

    第二种:通过编译安装nginx

    1. ---
    2. - name: second play for install httpd
    3. gather_facts: false
    4. hosts: webservers:dbservers
    5. remote_user: root
    6. tasks:
    7. #关闭防火墙
    8. - name: disabled firewalld
    9. service: name=firewalld state=stopped enabled=no
    10. #关闭 selinux
    11. - name: disable selinux
    12. command: '/sbin/setenforce 0'
    13. ignore_errors: yes
    14. - name: disabled selinux forever
    15. replace: path=/etc/selinux/config regexp=enforcing replace=disabled after=loaded
    16. #关闭和删除yum安装的nginx
    17. - name: disabled nginx
    18. service: name=nginx state=stopped enabled=no
    19. ignore_errors: yes
    20. - name: remove nginx
    21. yum: name=nginx state=absent
    22. #准备本地yum仓库
    23. yum: name=nginx state=absent
    24. #准备本地yum仓库
    25. - name: archive yum online repo
    26. archive: path=/etc/yum.repos.d/*.repo dest=/etc/yum.repos.d/yum_bak.repo.tar.gz format=gz remove=yes
    27. - name: copy local yum repo
    28. copy: src=nginx/local.repo dest=/etc/yum.repos.d/local.repo
    29. - name: mount cdrom
    30. mount: src=/dev/sr0 path=/mnt fstype=iso9660 state=mounted
    31. #安装nginx的依赖环境包
    32. - name: install pkgs
    33. yum: name=pcre-devel,zlib-devel,openssl-devel,gcc,gcc-c++,make state=latest
    34. #创建nginx用户
    35. - name: create user nginx
    36. user: name=nginx create_home=no shell=/sbin/nologin
    37. #解压软件包并安装
    38. - name: unarchive nginx package
    39. unarchive: copy=yes src=nginx/nginx-1.24.0.tar.gz dest=/opt/
    40. - name: install nginx with source
    41. shell: chdir=/opt/nginx-1.24.0/ ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module && make && make install
    42. #创建软连接
    43. - name: create nginx link
    44. file: src=/usr/local/nginx/sbin/nginx path=/usr/sbin/nginx state=link
    45. #创建nginx的service文件
    46. - name: create nginx service file
    47. copy: src=nginx/nginx.service dest=/lib/systemd/system/nginx.service
    48. - name: start nginx
    49. service: name=nginx state=started enabled=yes

    实操2:playbook定义、引用变量​​​​​​​

    1. ---
    2. - name: stop firewalld nfs crond
    3. gather_facts: true
    4. hosts: webservers:dbservers
    5. remote_user: root
    6. #定义变量名为servername值为firewalld
    7. vars:
    8. - servername: firewalld
    9. tasks:
    10. - name: stop firewalld
    11. #调用vars定义的变量
    12. systemd: name={{servername}} state=stopped enabled=no
    13. - name: copy ipv4 info
    14. #通过调用收集的facts信息做变量值
    15. copy: content={{ansible_default_ipv4.address}} dest=/opt/ip.txt

    纵向写法

    [root@localhost playbook]#ansible-playbook demo3.yaml -e "servername=crond"
    

     

    实操3:通过playbook完成普通账户权限提权为root用户

    1. ---
    2. - name: stop firewalld nfs crond
    3. gather_facts: true
    4. hosts: dbservers
    5. remote_user: xueyin
    6. become: yes
    7. become_user: root
    8. #定义变量名为servername值为firewalld
    9. vars:
    10. - servername: firewalld
    11. tasks:
    12. - name: stop firewalld
    13. #调用vars定义的变量
    14. systemd:
    15. name: "{{servername}}"
    16. state: stopped
    17. enabled: no
    18. - name: copy ipv4 info
    19. #通过调用收集的facts信息做变量值
    20. copy:
    21. content: "{{ansible_default_ipv4.address}}"
    22. dest: /opt/ip.txt

    1. [root@localhost ~]#vim /etc/sudoers
    2. 不仅在playbook文件中设置sudo提权 还需要在对应的主机上实现sudo提权

    1. [root@localhost playbook]#ansible-playbook demo3.yaml -k -K
    2. -k 指定ssh的登录密码
    3. -K 大写需要输入用户的登录密码

     

    实操4:通过when条件判断指定主机完成相应的任务

    when一个比较常见的应用场景是实现跳过某个主机不执行任务或者只有满足条件的主机执行任务

    1. vim test2.yaml
    2. ---
    3. - hosts: all
    4. remote_user: root
    5. tasks:
    6. - name: shutdown host
    7. command: /sbin/shutdown -r now
    8. when: ansible_default_ipv4.address == "192.168.80.12" #when指令中的变量名不需要手动加上 {{}}
    9. when: inventory_hostname == "<主机名>"
    10. ansible-playbook test2.yaml

    实操5:通过with_items循环实现在远程主机上关闭服务、创建文件和目录

    no1:关闭firewalld、nfs、crond

    1. ---
    2. - name: stop firewalld nfs crond
    3. gather_facts: true
    4. hosts: webservers:dbservers
    5. remote_user: root
    6. #定义变量名为servername,值分别为firewalld,nfs,crond
    7. vars:
    8. - servername: [firewalld, nfs, crond]
    9. tasks:
    10. - name: stop firewalld nfs crond
    11. #通过with_items实现循环关闭服务
    12. with_items: "{{servername}}"
    13. systemd: name={{item}} state=stopped enabled=no

     no2:批量创建多个用户,并加入指定的组

    1. ---
    2. - name: create user
    3. gather_facts: false
    4. hosts: dbservers
    5. remote_user: root
    6. vars:
    7. myusers:
    8. - {myname: xyc, mygroup: ky33}
    9. - {myname: wwy, mygroup: ky34}
    10. - {myname: wx, mygroup: ky35}
    11. tasks:
    12. - name: create groups
    13. with_items: [ky33, ky34, ky35]
    14. group: name={{item}}
    15. - name: create users and join into group
    16. with_items: "{{myusers}}"
    17. user: name={{item.myname}} groups={{item.mygroup}} state=present

    实操6:基于templates模块,完成nginx服务的配置模板

    1. Templates 模块
    2. Jinja是基于Python的模板引擎。Template类是Jinja的一个重要组件,可以看作是一个编译过的模板文件,用来产生目标文本,传递Python的变量给模板去替换模板中的标记。
    3. 1.先准备一个以 .j2 为后缀的 template 模板文件,设置引用的变量
    4. cp /etc/httpd/conf/httpd.conf /opt/httpd.conf.j2
    5. vim /opt/httpd.conf.j2
    6. Listen {{http_port}} #42行,修改
    7. ServerName {{server_name}} #95行,修改
    8. DocumentRoot "{{root_dir}}" #119行,修改

    实操7:基于tags标签,指定完成特定的任务模块

    ​​​​​​​可以在一个playbook中为某个或某些任务定义“标签”,在执行此playbook时通过ansible-playbook命令使用--tags选项能实现仅运行指定的tasks。
    playbook还提供了一个特殊的tags为always。作用就是当使用always作为tags的task时,无论执行哪一个tags时,定义有always的tags都会执行。

    1. tags 模块
    2. 可以在一个playbook中为某个或某些任务定义“标签”,在执行此playbook时通过ansible-playbook命令使用--tags选项能实现仅运行指定的tasks。
    3. playbook还提供了一个特殊的tags为always。作用就是当使用always作为tags的task时,无论执行哪一个tags时,定义有always的tags都会执行。
    4. vim webhosts.yaml
    5. ---
    6. - hosts: webservers
    7. remote_user: root
    8. tasks:
    9. - name: Copy hosts file
    10. copy: src=/etc/hosts dest=/opt/hosts
    11. tags:
    12. - only #可自定义
    13. - name: touch file
    14. file: path=/opt/testhost state=touch
    15. tags:
    16. - always #表示始终要运行的代码
    17. ansible-playbook webhosts.yaml --tags="only"
    18. vim dbhosts.yaml
    19. ---
    20. - hosts: dbservers
    21. remote_user: root
    22. tasks:
    23. - name: Copy hosts file
    24. copy: src=/etc/hosts dest=/opt/hosts
    25. tags:
    26. - only
    27. - name: touch file
    28. file: path=/opt/testhost state=touch
    29. ansible-playbook dbhosts.yaml --tags="only"
    30. //分别去两台被管理主机上去查看文件创建情况

    合并:综合多模块

    1. ---
    2. - name: serventh play for install nginx with source
    3. gather_facts: yes
    4. hosts: webservers
    5. remote_user: root
    6. vars:
    7. - root_dir: /var/www/html
    8. tasks:
    9. #关闭防火墙和selinux
    10. - name: disabled firewalld
    11. service: name=firewalld state=stopped enabled=no
    12. - name: disable selinux
    13. command: '/sbin/setenforce 0'
    14. ignore_errors: yes
    15. - name: disabled selinux forever
    16. replace: path=/etc/selinux/config regexp=enforcing replace=disabled after=loaded
    17. #安装依赖包
    18. - name: mount cdrom
    19. mount: src=/dev/sr0 path=/mnt fstype=iso9660 state=mounted
    20. - name: install pkgs
    21. with_items: [pcre-devel, zlib-devel, openssl-devel, gcc, gcc-c++, make]
    22. yum: name={{item}} state=latest
    23. #创建运行用户
    24. - name: create nginx user
    25. user: name=nginx create_home=no shell=/sbin/nologin
    26. #解压软件包并安装
    27. - name: unarchive nginx package
    28. unarchive: copy=yes src=/etc/ansible/playbook/nginx-1.24.0.tar.gz dest=/opt/
    29. - name: install nginx with source
    30. shell: chdir=/opt/nginx-1.24.0/ ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module && make && make install
    31. #创建软链接并启动服务
    32. - name: create link file for nginx
    33. file: state=link src=/usr/local/nginx/sbin/nginx path=/usr/local/sbin/nginx
    34. - name: create nginx service file
    35. copy: src=nginx.service dest=/lib/systemd/system/nginx.service
    36. - name: start nginx
    37. service: name=nginx state=started enabled=yes
    38. #创建网页根目录
    39. - name: create root dir
    40. file: path={{root_dir}} state=directory
    41. #创建网页文件
    42. - name: create index.html for accp.com
    43. copy: content="

      this is accp test web page

      "
      dest={{root_dir}}/index.html
    44. when: ansible_default_ipv4.address == "192.168.20.17"
    45. - name: create index.html for benet.com
    46. copy: content="

      this is benet test web page

      "
      dest={{root_dir}}/index.html
    47. when: ansible_default_ipv4.address == "192.168.20.12"
    48. #生成配置文件
    49. - name: copy nginx config file with template
    50. template: src=/etc/ansible/playbook/nginx.conf.j2 dest=/usr/local/nginx/conf/nginx.conf
    51. notify: "reload nginx"
    52. handlers:
    53. - name: reload nginx
    54. service: name=nginx state=reloaded

    三、关于playbook的知识点总结

    1. inventory主机清单管理
    2. 主机清单配置文件 /etc/ansible/hosts
    3. 格式:
    4. [组名]
    5. 主机IP[:ssh端口] #默认是 22 端口
    6. 主机名[:ssh端口]
    7. 主机IP[0:255] #设置连续的主机列表范围
    8. 主机名[a:z] ansible_port= ansible_user= ansible_password= #设置主机变量
    9. [组名:vars] #设置组变量
    10. ansible_port=
    11. ansible_user=
    12. ansible_password=
    13. [大组名:children] #设置嵌套组
    14. 组名1
    15. 组名2
    16. 组名3
    17. playbook剧本
    18. vim XXX.yaml XXX.yml
    19. ---
    20. - name: #设置play的名称
    21. hosts: #指定执行此play的远程主机组
    22. remote_user: #指定执行此play的用户
    23. #become: #设置是否sudo切换
    24. #become_user: #指定sudo切换的用户
    25. gather_facts: #设置是否收集facts信息 yes|no|true|false
    26. vars: #设置自定义变量
    27. tasks: #指定此play的任务列表
    28. - name: #定义任务的名称
    29. 模块名: 模块参数 #定义任务要使用的模块和参数(键值对格式)
    30. - name:
    31. 模块名: 模块参数
    32. ignore_errors: true #忽略此任务的失败
    33. - name:
    34. 模块名: 模块参数
    35. notify: '任务名' #定义此任务执行结果为changed状态时要触发的handlers任务
    36. - name:
    37. 模块名: 模块参数
    38. when: #定义条件表达式(== != > >= < <=),条件成立时执行此task任务,否则不执行此任务
    39. - name:
    40. 模块名: 模块参数={{item}}
    41. with_items: #定义循环列表
    42. - name:
    43. 模块名: 模块参数
    44. tags: #定义任务的标签,ansible-playbook --tags="标签" 可实现仅执行拥有指定标签的任务(拥有always标签的任务总是执行)
    45. - 标签1
    46. - 标签2
    47. ....
    48. handlers:
    49. - name: 任务名
    50. 模块名: 模块参数
    51. ansible-playbook XXX.yaml -u -k -K
    52. --syntax-check
    53. --list-task
    54. --list-hosts
    55. --start-at-task="任务名称"
    56. --tags="标签"
    57. tasks任务的模块语法格式:
    58. 纵向格式:
    59. 模块名:
    60. 参数1: 值
    61. 参数2: "{{变量名}}"
    62. ....
    63. 横向格式:
    64. 模块名: 参数1=值 参数2={{变量名}} ....
    65. with_items 和 vars 的语法格式
    66. 纵向格式:
    67. - name:
    68. with_items:
    69. - 1
    70. - 2
    71. ....
    72. 模块名: 参数={{item}}
    73. vars:
    74. 变量名:
    75. - 值1
    76. - 值2
    77. ....
    78. tasks:
    79. - name:
    80. 模块名: 参数={{item}}
    81. with_items: "{{变量名}}"
    82. #值为对象类型(键值对字段)时:
    83. with_items:
    84. - key1: 值1
    85. key2: 值2
    86. - key1: 值3
    87. key2: 值4
    88. ....
    89. vars:
    90. 变量名:
    91. - key1: 值1
    92. key2: 值2
    93. - key1: 值3
    94. key2: 值4
    95. ....
    96. 横向格式:
    97. #值为纯量类型时:
    98. with_items: [值1, 值2, ....]
    99. vars:
    100. 变量名: [值1, 值2, ....]
    101. #值为对象类型(键值对字段)时:
    102. with_items:
    103. - {key1: 值1, key2: 值2}
    104. - {key1: 值3, key2: 值4}
    105. ....
    106. template配置模板模块
    107. 1)先准备一个 XXX.j2 配置模板文件,在模板文件中使用 {{变量名}} 格式引用主机变量、组变量、facts信息字段变量或vars字段自定义的变量的值
    108. 2)编辑 playbook 文件,在文件中的 tasks 任务中定义 template 模块配置(template: src=XXX.j2文件路径 dest=远程主机文件路径)
    109. roles角色的作用?
    110. 可以把playbook剧本里的各个play看作为一个角色,将各个角色的tasks任务、vars变量、template模板和copy、script模块使用的相关文件等内容放置在指定角色的目录里统一管理,在需要的时候可在playbook中使用roles角色直接调用即可。也就是说roles角色可以在playbook中实现代码的复用。
    111. roles/ #角色总目录,其每个子目录就是一个角色目录
    112. nginx/ #相当于playbook中的每一个play主题,目录名就是角色名
    113. files/ #存放copy、script模块调用的文件
    114. templates/ #存放template模块调用的 XXX.j2 模板文件
    115. tasks/main.yml #定义此角色的tasks普通任务列表
    116. handlers/main.yml #定义此角色通过notify触发时执行的handlers处理器任务列表
    117. vars/main.yml #定义此角色用的自定义变量
    118. defaults/main.yml #定义此角色用的默认变量(一般不用)
    119. meta/main.yml #定义此角色的元数据信息和依赖关系
    120. mysql/
    121. ....
    122. php/
    123. ....
    124. vim XXX.yaml
    125. - name:
    126. hosts:
    127. remote_user:
    128. roles:
    129. - nginx
    130. - mysql
    131. - php
    132. ansible-playbook XXX.yaml

  • 相关阅读:
    springboot 多线程实现
    论文解读(LA-GNN)《Local Augmentation for Graph Neural Networks》
    备战数学建模45-粒子群算法优化BP神经网络(攻坚站10)
    GAIN的代码实现(4)——基于GAN的Spam数据集缺失数据填补(序)【改进版】
    这次把怎么做好一个PPT讲清-动画篇
    球面距离计算方式(杭州到各城市的球面距离&计算球面距离)
    echarts+DateV.GeoAtlas 绘制地图
    Direct Sparse Mapping reading notes -- Initialization
    华为云云耀云服务器L实例评测|使用宝塔面板管理服务器,并搭建个人博客网站
    前端 JavaScript 与 HTML 怎么实现交互?
  • 原文地址:https://blog.csdn.net/liu_xueyin/article/details/136160210