Ansible整理

[root@ansible ~]# yum -y install ansible
[root@ansible ~]# yum remove ansible
[root@ansible ~]# ansible-doc cron     #查看cron模块详细帮助信息
[root@ansible ~]# ansible-doc -s cron     #查看cron模块简要信息
[root@ansible ~]# ansible hostname|ip -m setup     #获取ansible内置变量(内置变量调用方式:ansible_eth0.ipv4.address)
[root@ansible ~]# ansible-playbook -i /root/hosts.txt test.yaml    #ansible执行自定义主机文件
#hosts.txt文件格式

192.168.1.2  ansible_ssh_user=root    ansible_ssh_pass='PASSWORLD'
192.168.1.3  ansible_ssh_user=root    ansible_ssh_pass='PASSWORLD'

[web]
192.168.1.2

[db]
192.168.1.3

[hosts:children]
web
db

#定义变量
[hosts:vars]
domain="www.test.com"

#test.yaml文件格式

- name: Initalize system
  hosts: hosts
  remote_user: root
  gather_facts: True
  roles:
    - role: web
      tags: init

在ansible-playbook中打印变量内容

- name: 打印多个变量(写法一),debug必须用 msg: 或 var: 不能直接传列表
  debug:
    var: "stat_results = {{ stat_results }}, item = {{ item }}"

- name: 打印多个变量(写法二)
  debug:
    msg:
      - "stat_results: {{ stat_results }}"
      - "item: {{ item }}"
- name: 打印变量并立即停止执行,强制整个剧本失败退出 → 使用 fail
  fail:
    msg:
      - "stat_results: {{ stat_results }}"
      - "item: {{ item }}"
- name: 打印变量并结束当前主机执行(方式一)
  meta: end_host
  debug:
    msg:
      - "stat_results: {{ stat_results }}"
      - "item: {{ item }}"

- name: 调试输出变量(方式二)
  debug:
    msg: "{{ stat_results }} --- {{ item }}"

- name: 立即停止
  meta: end_host

ansible-playbook中多条件判断

#  when: item.stat.exists or item.item | regex_search('\.gz$')   # 多个条件写成一行,两个条件“或”的关系直接用英文关键字 or 表示,也可以用符号 or / ||(两种写法效果完全一样)
#  when: (env == "test" or env == "dev") and ansible_system == "Linux"  # 如果有与,或混合,必须用括号分组,且关系:and / && 表示都可以,推荐 and
- name: when条件为”或“关系
  shell: echo "hello world"
  with_items: "{{ stat_results.results }}"
  when:
    - item.stat.exists or
      item.item | regex_search('\.gz$')
  tags:
    - webserver

- name: when条件为”与“关系
  shell: echo "hello world"
  with_items: "{{ stat_results.results }}"
  when:
    - item.stat.exists
    - item.item | regex_search('\.gz$')
  tags:
    - webserver

示例

# 在ansible服务器上执行:mkdir /opt/data && touch /opt/data/a.txt /opt/data/b.sh /opt/data/c.py,创建测试环境然后运行:ansible-playbook test.yaml
- name: Copy file To webserver
  hosts: webserver
  gather_facts: no
#  vars_files:
#    - vars.yaml
  vars:
    file_root: /opt
    file_path: data
    file_name: 
      - a.txt
      - b.sh
      - c.py
  tasks:
    - name: Create target directory on remote
      file:
        path: "{{ file_root }}/{{ file_path }}"
        state: directory
        recurse: yes
      tags:
        - webserver

    - name: Copy file To webserver
      synchronize:
        src: '{{ file_root }}/{{ file_path }}/{{ item }}'
        dest: '{{ file_root }}/{{ file_path }}/{{ item }}'
        mode: push
      with_items: "{{ file_name }}"
      when: item | regex_search('\.txt$|\.sh$')
      tags:
        - webserver

    - name: Check file
      stat:
        path: "{{ file_root }}/{{ file_path }}/{{ item }}"
      register: stat_results
      with_items: "{{ file_name }}"
      tags:
        - webserver

#    - name: 打印变量并立即停止执行,强制整个剧本失败退出 → 使用 fail
#      fail:
#        msg:
#          - "stat_results: {{ stat_results }}"
    
    - name: when条件为"或"关系
      shell: echo "hello world"
      register: echo_or
      with_items: "{{ stat_results.results }}"
      when:
        - item.stat.exists or
          item.item | regex_search('\.go$')
      tags:
        - webserver

    - name: 打印条件为"或"关系的变量
      debug:
        msg: "{{ echo_or }}"
    
    - name: when条件为"与"关系
      shell: echo "hello world"
      with_items: "{{ stat_results.results }}"
      when:
        - item.stat.exists
        - item.item | regex_search('\.txt$')
      register: echo_and
      tags:
        - webserver
     
    - name: 打印条件为"与"关系的变量
      debug:
        var: echo_and
- name: Copy image To k8s-all
  hosts: k8s-all
  gather_facts: no
#  vars_files:
#    - vars.yaml
  vars:
    patchrootdir: /app/data
    patchfiledir: 20260507-00000
    patch_filelist:
      - nginx-1.3.4.tar.gz
      - httpd-2.4.39-4.tar
      - mysql-2.19.0.tar.xz
      - mariadb-12.1.2.tar
    filetag:
      - {name: 'nginx', tag: '1.3.4'}
      - {name: 'httpd', tag: '2.4.39-4'}
      - {name: 'mysql', tag: '2.19.0'}
      - {name: 'mariadb', tag: '12.1.2'}
  tasks:
    - name: Create target directory on remote
      file:
        path: "{{ patchrootdir }}/{{ patchfiledir }}"
        state: directory
        recurse: yes
      tags:
        - k8s-all

    - name: Copy sql,conf file to k8s-all
      ansible.builtin.copy:
        src: "{{ item }}"
        dest: "{{ patchrootdir }}/{{ patchfiledir }}"
        owner: root       # 文件所属用户
        group: root       # 文件所属组
        mode: '0644'      # 权限(必须加引号)
        backup: yes       # 覆盖前备份原文件
        force: yes        # 远程文件不同则覆盖(默认yes)
      with_fileglob:
        - "{{ patchrootdir }}/{{ patchfiledir }}/*.sql"
        - "{{ patchrootdir }}/{{ patchfiledir }}/*.conf"
      # 或者使用loop标签(Ansible 2.5+)
      # loop: "{{ query('fileglob', '/local/path/*.sql', '/local/path/*.conf') }}"
      tags:
        - k8s-all

- name: Copy image To sql-k8s-all
  hosts: sql-k8s-all
  gather_facts: no
  vars_files:
    - vars.yaml
  tasks:
    - name: Synchronize image to sql-k8s
      synchronize:
        src: '{{ patchrootdir }}/{{ patchfiledir }}/{{ item }}'
        dest: '{{ patchrootdir }}/{{ patchfiledir }}/{{ item }}'
        mode: push
      with_items: "{{ patch_filelist }}"
      when: not ( item | regex_search('nginx|httpd') )
      tags:
        - sql-k8s-all

- name: Copy image To web-k8s-all
  hosts: web-k8s-all
  gather_facts: no
  vars_files:
    - vars.yaml
  tasks:
    - name: Synchronize image to web-k8s
      synchronize:
        src: '{{ patchrootdir }}/{{ patchfiledir }}/{{ item }}'
        dest: '{{ patchrootdir }}/{{ patchfiledir }}/{{ item }}'
        mode: push
      with_items: "{{ patch_filelist }}"
      when: item | regex_search('nginx|httpd')
      tags:
        - web-k8s-all

- name: Load image To k8s-all 
  hosts: k8s-all
  gather_facts: no
  vars_files:
    - vars.yaml
  tasks:
    - name: Check file
      stat:
        path: "{{ patchrootdir }}/{{ patchfiledir }}/{{ item }}"
      # register标签:在任务中注册一个变量,把任务执行结果保存到stat_results变量中。注册的变量只能在同一个task下引用
      register: stat_results
      with_items: "{{ patch_filelist }}"
      tags:
        - k8s-all

    - name: Load gz image To k8s-all
      shell: gzip -dc {{ patchrootdir }}/{{ patchfiledir }}/{{ item.item }} | ctr -n k8s.io images import -
      with_items: "{{ stat_results.results }}"
      when: 
        - item.stat.exists
        - item.item | regex_search('\.gz$')
      loop_control:
        label: "{{ item.item }} {{ '已导入' if (item.stat.exists and (item.item | regex_search('\\.gz$'))) else '未导入' }}"
      tags:
        - k8s-all

    - name: Load xz image To k8s-all
      shell: xzcat -T0 {{ patchrootdir }}/{{ patchfiledir }}/{{ item.item }} | ctr -n k8s.io images import -
      with_items: "{{ stat_results.results }}"
      when: 
         - item.stat.exists
         - item.item | regex_search('\.xz$')
      loop_control:
        label: "{{ item.item }} {{ '已导入' if (item.stat.exists and (item.item | regex_search('\\.xz$'))) else '未导入' }}"
      tags:
        - k8s-all

    - name: Load tar image To k8s-all
      shell: ctr -n k8s.io images import {{ patchrootdir }}/{{ patchfiledir }}/{{ item.item }}
      with_items: "{{ stat_results.results }}"
      when: 
         - item.stat.exists
         - item.item | regex_search('\.tar$')
      loop_control:
        label: >-
          "{{ item.item }} {{ (item.stat.exists and (item.item | regex_search('\.tar$'))) | ternary('已导入', '未导入') }}"
      tags:
        - k8s-all

    - name: Check images
      shell: crictl images | grep {{ item.0.name }} | grep {{ item.0.tag }} 
      register: returnimage
      # with_nested标签:双循环,获取第一层循环的值: {{ item.0 }}, 获取第二层循环的值: {{ item.1 }}
      with_nested:
        - "{{ filetag }}"
        - "{{ stat_results.results }}"
      when: 
        - item.0.name in item.1.item
        - item.1.stat.exists
      # loop_control标签作用:打印日志时只显示关心的部分(比如只显示文件名),而不是把整个巨大的 JSON 变量都打印出来
      loop_control:
        label: "Check {{ item.0.name }}:{{ item.0.tag }} in {{ item.1.item | basename }}" # basename作用:去掉前面的目录路径,只提取最后的纯文件名
    - debug:
        msg: "检查镜像 {{ item.item.0.name }}:{{ item.item.0.tag }} 的结果,退出码: {{ item.rc }}"
      with_items: "{{ returnimage.results }}"
      when: item.rc is defined
      loop_control:
        label: "{{ item.item.0.name }}:{{ item.item.0.tag }}"  # 对于skipping的动作日志中只显示这一项,隐藏 item 的完整 JSON
      tags:
        - k8s-all
patchrootdir: /app/data
patchfiledir: 265-20260507-00000

patch_filelist:
  - heat-dcn-1.1.22-452.tar
  - nf-controller-5.6.4-328.tar
  - nsp-apientry-dcn-5.6.4.ZYJK-1342.tar
  - nsp-msg-center-5.6.4-107.tar
  - toscana-dcn-1.1.22-452.tar

filetag:
  - {name: 'nf-controller', tag: '5.6.4-328'}
  - {name: 'heat', tag: 'dcn-1.1.22-452'}
  - {name: 'toscana', tag: 'dcn-1.1.22-452'}
  - {name: 'nsp-apientry-dcn', tag: '5.6.4.ZYJK-1342'}
  - {name: 'nsp-msg-center', tag: '5.6.4-107'}
vars.yaml文件内容

解决ansible cryptography模块告警
[root@ansible ~]# ansible 127.0.0.1 -m ping
/usr/local/python2.7/lib/python2.7/site-packages/ansible-2.9.18-py2.7.egg/ansible/parsing/vault/__init__.py:44: CryptographyDeprecationWarning: Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography, and will be removed in the next release.
from cryptography.exceptions import InvalidSignature
[root@ansible ~]# pip2.7 install cryptography==2.9

参考链接:
      https://blog.51cto.com/wujianwei/2082880      # ansible不配置ssh免密钥,使用密码登录
      http://www.ansible.com.cn/docs/playbooks_intro.html      # about-playbooks
      https://www.cnblogs.com/yanjieli/p/10969299.html
      https://www.cnblogs.com/coolops/p/12793640.html
      https://www.likecs.com/show-40538.html
      https://my.oschina.net/kangvcar/blog/1830155
      https://github.com/openstack/kolla-ansible

posted @ 2021-07-23 11:06  風£飛  阅读(136)  评论(0)    收藏  举报