• DO447学习笔记


    DO447----高级自动化:可靠的最佳实践

    课程内容摘要
           • 了解高效实用地使用 Ansible 实现自动化的推荐做法。
           • 借助 Ansible 自动化操作执行滚动更新。
           • 使用 Ansible 的高级功能来处理数据,包括过滤器和插件。
           • 借助 Ansible Playbook,通过 REST API 控制应用。
           • 实施红帽 Ansible Tower,以集中协调和扩展红帽 Ansible 自动化。
           • 利用红帽 Ansible Tower 的功能来管理复杂的自动化工作流。
           • 借助 Git 和红帽 Ansible Tower,实现 CI/CD 业务流程自动化。

    ******借助 Ansible Playbook,通过 REST API 控制应用******

    在Firefox浏览器中,访问https://tower.lab.example.com/api/。你应该看到你的Ansible Tower服务器的可浏览API。

    【 job_templates": "/api/v2/job_templates/" 】

    JSON-PP必须安装:

    [student@workstation ~]$ sudo yum install perl-JSON-PP

    [student@workstation ~]$ curl -X GET --user admin:redhat https://tower.lab.example.com/api/v2/job_templates/?name="Demo Job Template" -k -s |json_pp

    用python3:

     [student@workstation ~]$ curl -X GET --user admin:redhat https://tower.lab.example.com/api/v2/job_templates/?name="Demo Job Template" -k -s |python3 -m json.tool  

     对于这个命令,-k(--insecure)选项指示curl操作,即使它不能验证SSL证书。使用 -s(--silent)选项,curl只显示返回的数据,而不显示进度状态或错误消息。

    切换分支:

    [student@workstation my_webservers_DEV]$ git branch
    * master
    [student@workstation my_webservers_DEV]$ git branch development
    [student@workstation my_webservers_DEV]$ git branch
      development
    * master
    [student@workstation my_webservers_DEV]$ git checkout development
    Switched to branch 'development'
    [student@workstation my_webservers_DEV]$ git branch
    * development
      master
    大多数清单插件在默认情况下是禁用的。你可以在你的ansible.cfg配置文件中启用特定的插件,在inventory部分的enable_plugins指令中:

    [inventory]
    enable_plugins = host_list, script, auto, yaml, ini, toml
    [lb_servers]
        servera.lab.example.com
    [web_servers]
       serverb.lab.example.com
       serverc.lab.example.com
    [backend_server_pool]
       server[b:f].lab.example.com

    转换成yml文件格式

    lb_servers:
       hosts:
         servera.lab.example.com:
    web_servers:
      hosts:
        serverb.lab.example.com:
        serverc.lab.example.com:
    backend_server_pool:
      hosts:
        server[b:f].lab.example.com:

    清单变量:

     基于yaml的清单文件中直接设置清单变量,就像在基于inil的清单文件中一样。

    变量及其值存储在清单的host_vars或group_vars文件中。

    在一个基于ini的静态清单文件中,可以将主机localhost的ansible_connection变量设置为local,如下所示:

     基于yaml的静态清单文件:

     -------------------设置变量-----------------

    * 在角色的defaults和vars目录中。
    * 在清单文件中,可以作为主机变量或组变量。
    * 在playbook或inventory的group_vars或host_vars子目录下的变量文件中。
    * 在play, role, task中

    --------------变量的精确优先级列表从低到高:---------

    1 直接设置在清单文件或动态清单脚本中的组变量。
    2 在清单的group_vars/all文件或子目录中设置所有变量组。
    3 对剧本的group_vars/all文件或子目录中的所有设置的变量进行分组。
    4 为清单的group_vars子目录中设置的其他组的变量分组。
    5 为剧本的group_vars子目录中设置的其他组的变量分组。
    6 主机变量直接设置在清单文件或由一个动态清单脚本。
    7 主机变量设置在清单的host_vars子目录中。
    8 在playbook的host_vars子目录中设置主机变量。
    9 宿主事实和缓存事实。

    -----------------------剧本变量的优先级列表从低到高:-------

    1 剧本的vars部分设定的。
    2 通过在剧本中使用vars_prompt部分提示用户来设置。
    3 通过剧本的vars_files部分从外部文件列表中设置。
    4 通过角色的rolename/vars/子目录中的文件设置。
    5 为当前块设置一个vars部分。
    6 设置当前任务的vars部分。
    7 用include_vars模块动态加载。
    8 通过使用set_fact模块或使用register来记录任务在主机上执行的结果来为特定的主机设置。
    9 在剧本中的角色部分或使用include_role模块加载时为剧本中的角色设置的参数。
    10 由include_tasks模块中包含的任务的vars部分设置。

    * include_vars加载的变量具有较高的优先级,可以覆盖为角色和特定块和任务设置的变量。在许多情况下,如果不希望用外部变量文件覆盖这些值,则可能希望使用vars_files代替。

    * set_fact模块和register指令都设置了特定于主机的信息,要么是一个事实,要么是任务在该主机上执行的结果。

    * Extra变量使用ansible-playbook命令的-e选项设置的额外变量总是具有最高的优先级

    ##### ansibl变量的优先级 #####

    1. extra vars变量(在命令行中使用 -e);优先级最高

    2. 在inventory中定义的连接变量(比如ansible_ssh_user);优先级第二

    3. 大多数的其他变量(命令行转换,play中的变量,include的变量,role的变量等);优先级第三

    4. 在inventory定义的其他变量;优先级第四

    5. 有系统发现的facts;优先级第五

    6. "role默认变量",这个是最默认的值,很容易丧失优先权。优先级最小。

    ##### inventory清单列表里定义变量:单个主机定义的变量优先级高于主机组定义的变量 #####

    ansible使用inventory定义变量的优先级顺序从高到低为:

    1. host_vars下定义变量

    2. inventory中单个主机定义变量

    3. group_vars下定义变量

    4. inventory中组定义变量

    --------------------官网中的定义:----------(从低到高)

    1. command line values (for example, -u my_user, these are not variables)
    2. role defaults (defined in role/defaults/main.yml)
    3. inventory file or script group vars
    4. inventory group_vars/all
    5. playbook group_vars/all
    6. inventory group_vars/*
    7. playbook group_vars/*
    8. inventory file or script host vars
    9. inventory host_vars/*
    10. playbook host_vars/*
    11. host facts / cached set_facts
    12. play vars
    13. play vars_prompt
    14. play vars_files
    15. role vars (defined in role/vars/main.yml)
    16. block vars (only for tasks in block)
    17. task vars (only for the task)
    18. include_vars
    19. set_facts / registered vars
    20. role (and include_role) params
    21. include params
    22. extra vars (for example, -e "user=my_user")(always win precedence)

    ---> 更好的方法是将变量定义从清单文件移动到单独的变量文件中,每个主机组一个变量文件。每个变量文件以主机组命名,包含主机组的变量定义:

     ---> 一种更好的方法是在group_vars目录下为每个主机组创建子目录。Ansible解析这些子目录中的任何YAML,并根据父目录将变量与主机组关联:

    2.2.4 特殊清单变量

     ansible_connection: 用于访问托管主机的连接插件。缺省情况下,除了使用local的localhost,所有主机都使用ssh。

     ansible_host: 连接到托管主机时要使用的实际IP地址或完全限定域名,而不是使用清单文件中的名称(inventory_hostname)。默认情况下,这个变量的值与清单主机名相同。

    ansible_port: Ansible用于连接被管理主机。对于(默认的)SSH连接插件,值默认为22。

    ansible_user: Ansible以这个用户连接到被管理的主机。Ansible的默认行为是使用与在控制节点上运行Ansible Playbook的用户相同的用户名连接到托管主机。

    ansible_become_user: Ansible连接到托管主机,它将使用ansible_become_method(默认为sudo)切换到该用户。您可能需要以某种方式提供身份验证凭据。

    ansible_python_interpreter: Ansible应该在托管主机上使用的Python可执行文件的路径。在Ansible2.8及以后版本,默认为auto,

    2.2.5 使用变量识别当前主机

    inventory_hostname:  当前正在处理的托管主机的名称,从清单中获取。

    ansible_host:   用于连接受管理主机的实际IP地址或主机名。

    ansible_facts['hostname'] :   作为事实从托管主机收集的短主机名。

    ansible_facts['fqdn'] :   作为事实从托管主机收集的完全合格域名(FQDN)。

    -----------------------管理任务执行---------------------------

    提权升级指令::

    become、become_user、become_method、become_flags。

    配置特权升级::
    如果将Ansible配置文件的[privilege_escalation]部分中的become布尔值设置为yes(或true),那么剧本中的所有剧本将默认使用privileqe_escalation。当运行在被管理的主机上时,这些play将使用当前的become_method方法切换到当前的become_user。

    CONFIGURATION DIRECTIVE COMMAND-LINE OPTION
    become --become or -b
    become_method --become-method=BECOME_METHOD
    become_user --become-user=BECOME_USER
    become_password --ask-become-pass or -k

    剧本的特权升级:

    第一个play中使用:become:true

    连接变量的特权升级:

    连接变量来配置特权升级。这些连接变量可以作为组或单个主机上的清单变量应用。

    configuration or playbook directive CONNECTION VARIABLE
    become ansible_become
    become_method ansible_become_method
    become_user ansible_become_user
    become_password ansible_become_pass

    --------------特权升级方法----------

    . 让你的剧本保持简单(Ansible最佳实践的关键原则)是首要的考虑。
    . 其次要考虑的是,在可能的情况下以最小权限运行任务(以避免由于playbook错误而导致托管主机的意外损害)。

    -------------控制任务执行-----------

    ---
    - name: Ensure Apache is deployed    
      hosts: localhost
      gather_facts: no
      tasks:
        - name: Open the firewall     *******Ansible 会在打开防火墙之前执行角色的任务,
    即使任务部分是先定义
    firewalld: service: http permanent: yes state: enabled roles:
    - role: apache

     pre_tasks :是在roles部分之前运行的tasks部分

     post_tasks: 是在一个tasks部分之后运行的

    ------------------------执行顺序----------------------
    Ansible按以下顺序运行play部分:
    1    pre_tasks
    2    pre_tasks部分中通知的处理程序
    3    角色
    4    任务
    5    角色和任务部分中通知的处理程序
    6    post_tasks
    7    post_tasks 部分中通知的处理程序

    ---
    - name: Testing host order
      hosts: localhost
      order: sorted                       ********order指令接受以下值****
      tasks:
        - name: Createing a test file in /tmp
          copy:
            content: "This is a sample file"
            dest: /tmp/test.out

    order指令接受的值:

    1、inventory :清单order 这是默认值

    2、reverse_inventory: 清单order的倒序

    3、 sorted: 主机按字母顺序倒序排列

    4、 revers_sorted: 主机按字母顺序

    5、shuffle: 每次运行play时都是随机顺序

    -----------标签ANSIBLE资源------------------

    当使用ansible-playbook运行一个playbook时,

    ---->使用 --tags选项来过滤这个playbook,并只执行特定的带标签的play或任务。

    ---->使用 --skip-tags选项跳过带有特定标记的任务。

    ---
    - name: Example play using tagging
      hosts:
        - servera.lab.example.com
        - serverb.lab.example.com
      tasks:
        - name: httpd is installed
          yum:
            name: httpd
            state: latest
          tags: webserver     <----tags标签
    
        - name: postfix is installed
          yum:
            name: postfix
            state: latest

    [student@workstation yuan]$ ansible-playbook t1.yml --tags webserver   <----运行标签处

    [student@workstation yuan]$ ansible-playbook t1.yml --list-tags  <----列出剧本中所有的标签

    特殊标签:

    (1) Ansible有一个特殊的方法,可以在剧本中分配:always.。标记了always的资源将始终运行,即使它与传递给 --tags的标签列表不匹配。唯一的例外是使用 --skip-tags always选项显式跳过它。

    (2)  never特殊标记标记的任务不会运行,除非您将 --tags选项设置为never或与该任务关联的另一个tag运行playbook。

    三个额外的特殊tag
    (1) tagged的标记将使用显式标记运行任何资源。
    (2) 未标记的tag将运行任何没有显式tag的资源,并排除所有标记的资源。
    (3) all tag将包含play中的所有任务,无论他们是否有tag。这是Ansible的默认行为。

    ------------------变量类型----------------

     字符串(字符序列)
     数字(数值)
     布尔值(真/假)
     日期(ISO-8601日历日期)
     Null(设置变量为未定义的变量)
     列表或数组(值的排序集合)
     字典(键值对的集合)

    YAML格式允许定义多行字符串,使用pipe操作符(|)来保留换行符,

    使用大于操作符(>)来抑制换行符。

      string_with_breaks: |
                 This string
                 has several
                 line breaks
      string_without_breaks: >
                This string will not

                contain any line breaks.
                Separated lines are joined
                by a space character.

    字典:也称为映射或散列,是一种将字符串键与值链接起来以便直接访问的结构

    my_dict: { Douglas: Human, Marvin: Robot, Arthur: Human }

    my_dict:
        Douglas: Human
        Marvin: Robot
        Arthur: Human

    通过键来访问字典中的项,在字典名后面立即提供键,并用方括号括起来:

    assert:
        that:
            - my_dict['Marvin'] == 'Robot'

    -------------用过滤器处理数据-------------

    下面的表达式对变量myname的值进行过滤,通过使用标准的Jinja2过滤器确保值的第一个字母大写:
    {{ myname | capitalize }}

    - name: Test to see if the assertion        
      assert:
        that:
          - "{{ [1,4,2,2] | unique | sort }} is eq([1,2,4])"

    Jinja2中正式可用的过滤器:

      http://jinja.pocoo.org/docs/2.10/templates/#builtinfilters上记录的Jinja2过滤器提供了大量有用的实用函数。(https://jinja.palletsprojects.com/en/2.10.x/templates/#builtinfilters)(http://docs.jinkan.org/docs/jinja2/templates.html#id2)

    mandatory:
    如果变量没有定义值,则会失败并中止Ansible剧本。
    {{ my_value | mandatory }}

    default
    如果变量没有定义值,那么这个过滤器将把它设置为括号中指定的值。如果括号中的第二个参数是True,那么如果变量的初始值是空字符串或布尔值False,过滤器也会将该变量设置为默认值。
    {{ my_value | default(my_default, True) }}

    提起列表元素:

     

    - name: All three of these assertions are true
    assert:
    that:
    - "{{ [ 2, 4, 6, 8, 10, 12 ] | length }} is eq( 6 )"  ---length 列表长度
    - "{{ [ 2, 4, 6, 8, 10, 12 ] | first }} is eq( 2 )"   ---first 列表第一个
    - "{{ [ 2, 4, 6, 8, 10, 12 ] | last }} is eq( 12 )"   ---last 列表的最后一个

    random(随机)过滤器从列表中返回一个随机元素:
    {{ ['Douglas', 'Marvin', 'Arthur'] | random }}

    - name: reversion and sorting lists
      assert:
        that: 
          - "{{[2,4,6,8,10] | reverse |list }}is eq([10,8,6,4,2])"  ---把列表颠倒过来
          - "{{[4,8,10,6,2] | sort|list}} is eq([2,4,6,8,10])"      ---把列表顺序排列

    合并列表:flatten过滤器递归地接受输入列表值中的任何内部列表

    - name: Flatten turns nested lists on the left to list on the right
      assert:
        that:
          - "{{ [2,[4,[6,8]],10] | flatten }} is eq([2,4,6,8,10])"   ---flatten合并列表

    将列表作为集合进行操作:unique 唯一过滤器,

    - name: unique leaves unique elements
      assert:
        that:     --unique保证唯一,---list列表转成集合
          - "{{ [1,1,2,2,2,3,4,4]|unique|list }}is eq([1,2,3,4])"

    如果两个列表没有重复的元素,那么你可以对它们使用集合理论操作。
      union联合过滤器返回一个集合,其中包含来自两个输入集合的元素。
      intersect过滤器返回一个集合,该集合具有两个集合共有的元素。
      difference过滤器返回一个集合,其中包含第一个集合中不存在于第二个集合中的元素。

    - name: difference
      assert:
        that:   -----difference 第一个集合中有的,第二个集合中没有的
          - "{{[2,4,6,8,10] | difference([2,4,6,16])}} is eq([8,10])"

     操纵字典:

    字典是没有任何顺序的。它们只是键值对的集合。但是您可以使用过滤器来构造字典,并且您可以将它们转换为列表,或者将列表转换为字典。

    - name: combine
      vars:
        expected:
          a: 234
          b: 456
          c: 890
      assert:
        that:      ----combine 字典联合起来
          - "{{ {'a':234,'b':456} | combine({'b':456,'c':109 }) }} is eq(expected)"

    重塑字典:
    使用dict2items过滤器可以将一个字典重新塑造成一个条目列表,使用items2dict过滤器也可以将一个条目列表重新塑造成一个字典

    - name: converting
      vars:
        c1:   
          do1: Human
          do2: Robot
          do3: Human
        c2:  
          - key: d1
            value: Human      
          - key: d3
            value: Human          ---dict2items 把列表转换成字典
      assert:                     ---items2dict 把字典转换成列表
        that:      
          - "{{ c1 | dict2items }} is eq(c2)"
          - "{{ c2 | items2dict }} is eq(c1)"

    对字符串进行哈希、编码和操作:hash哈希过滤器使用提供的哈希算法返回输入字符串的哈希值:

    - name: SHA-1 hash
      vars:
        e1: '9ka0ka0akdfj912klkjasd334cal'
      assert:  
        that:
          - "'{{ 'Arthur' | hash('sha1')}}' is eq(e1)"

    使用password_hash过滤器来生成密码散列:

    {{ 'secret_password'| password_hash('sha512')}}

    编码的字符串
    二进制数据可以通过b64encode过滤器转换成base64,再通过b64decode过滤器转换回二进制格式。

    - name: Base64
      assert:
        that: 
          - "'{{ 'asdfkl'| b64encode }}'is eq('w8LDkkjj==')"
          - "'{{ 'w8kjsjd==' | b64encode }}'is eq('asdfkl')"

    格式化文本
    使用lower、upper或capitalize过滤器来强制输入字符串的大小写:

    - name: cc
      assert:
        that: 
          - "'{{ 'Marvin' | lower }}'is eq('marvin')"         --全部转换为小写
          - "'{{ 'Marvin' | upper }}'is eq('MARVIN')"         --全部转换为大写
          - "'{{ 'marvin' | capitalize }}'is eq('Marvin')"    --首字母转换为大写

    替换文本
    当你需要替换输入字符串中出现的所有子字符串时,replace过滤器很有用:

    - name: Replace
      assert:
        that:        ---replace 替换
          - "'{{ 'marvin, arthur' | replace('ar','**')}}'is eq('m**vin,**thur')"

    更复杂的搜索和替换可以通过使用正则表达式和regex_search和regex_replace过滤器来实现。

    解析和编码数据结构

    数据结构通过to_json和to_yaml过滤器序列化为JSON或YAML格式。使用to_nice_json和to_nice_yaml过滤器来获得格式化的人类可读输出。

    - name: Convert JSON and YAML format
      vars:
        hosts:
          - name: bastion
            ip:
              - 172.25.250.254
              - 172.25.252.1
        hosts_json: '[{"name":"bastion","ip":["172.25.250.254","172.25.252.1"]}]'
      assert:
        that:
          - "'{{ hosts | to_json}}'is eq(hosts_json)"

     4.3 实现高级循环

       使用循环迭代任务可以帮助简化您的Ansible Playbooks。loop关键字在项目的平面列表上循环。当与查找插件一起使用时,可以在循环列表中构造更复杂的数据。

    loop关键字代替with_*样式循环有以下好处:
     不需要记忆或找到一个with * style关键字来适应您的迭代场景。相反,使用插件和过滤器来使循环关键字任务适应您的用例。
     重点学习Ansible中可用的插件和过滤器,它们的适用性比迭代更广泛。
     可以通过ansible-doc -t lookup命令对查找插件文档进行命令行访问。这将帮助发现查找插件并使用它们设计自定义迭代场景。

     

  • 相关阅读:
    Android笔记(ImageView、BaseLine、进度条ProgressBar)
    Android笔记(dp、sp、px、多选按钮CheckBox、单选按钮RadioButton)
    Android笔记(简介)
    Android Studio安装后Fetching android sdk component information超时的解决方案
    解决The environment variable JAVA_HOME does not point to a valid JVM installation
    使用Genymotiont调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATIBLE解决办法
    Android Studio导入第三方jar包及.so动态库
    数据库知识记录
    CentOS7.5下yum安装MySQL8.0.11笔记
    MyBatis的mapper.xml中判断集合的size
  • 原文地址:https://www.cnblogs.com/yyuuee/p/15319348.html
Copyright © 2020-2023  润新知