美文网首页
Linux - 04-ansible

Linux - 04-ansible

作者: 找呀找提莫 | 来源:发表于2020-03-06 13:29 被阅读0次

[toc]

0. pssh

1.ansible基础

1.1 ansible主要组成部分

ANSIBLE PLAYBOOKS:任务剧本(任务集),编排定义ansible任务集的配置文件,由ansible顺序依次执行,通常是HSON格式的YML文件;
INVENTORY:ansible管理主机的清单/etc/ansible/hosts;
MODULES:ansible执行命令的功能模块,多数为内置核心模块,也可自定义;
PLUGINS:模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用;
API:供第三方程序调用的应用程序编程接口;
ANSIBLE:组合INVENTORY、MODULES、PLUGINS、API的窗口,可以理解为是ansible命令工具,其为核心执行工具;


ansible命令执行来源:
    USER, 普通用户,即SYSTEM ADMINISTRATOR;
    CMDB(配置管理数据库) API调用;
    PUBLIC/PRIVATE CLOUD API调用;
    USER -> ansible playbook -> ansible
    
利用ansible实现管理方式:
    ad-hoc即ansible命令,主要用于临时命令场景使用;
    ansible-playbook主要用于长期规划好的,大型项目的场景,需要有前提的规划;

ansible-playbook执行过程:
    将已有编排好的任务集写入ansible-playbook;
    通过ansible-playbook命令分拆任务集至逐条ansible命令,按预定规则逐条执行;

ansible主要造作对象:
    HOSTS主机
    NETWORKING网络设备

注意事项:
    执行ansible的主机一般成为u主控端,中控,master或堡垒机;
    主控端Python版本需要2.6以上;
    被控端Python版本小于2.4需要安装python-simplejson;
    被控端如开启selinux需要安装libselinux-python;
    windows不能作为主控端;

1.2 安装

rpm包安装(epel源):
    yum install -y ansible
    
编译安装:
    yum install python-jinja2 PyYAML python-paramiko python-babel python-crypto
    tar -xf ansible-1.5.4.tar.gz
    cd ansible-1.5.4
    python setup.py build
    python setup.py install
    mkdir /etc/ansible
    cp -r examples/* /etc/ansible

git安装:
    git clone git://github.com/ansible/ansible.git --recursive
    cd ./ansible
    source ./hacking/env-setup

pip安装:
    yum install -y python-pip python-devel
    yum install -y gcc glibc-devel zlib-devel rpm-build openssl-devel
    pip install --upgrade pip
    pip install ansible --upgrade

确认安装:
    ansible -version

1.3 ansibel文件

配置文件:
    /etc/ansible/ansible.cfg    主配置文件,配置ansible工作特性;
    /etc/ansible/hosts  主机清单;
    /etc/ansible/roles/  存放角色的目录;

程序:
    /usr/bin/ansbile  主程序,临时命令执行工具;
    /usr/bin/ansbile-doc  查看配置文档,模块更能查看工具;
    /usr/bin/ansbile-galaxy  下载/上传优秀代码或Roles模块的官网;
    /usr/bin/ansbile-playbook  定制自动化任务,编排剧本工具/usr/bin/ansible-pull远程执行命令的工具;
    /usr/bin/ansbile-vault  文件加密工具;
    /usr/bin/ansbile-console  基于Console界面于用户交互的执行工具;

主机清单inventory
    Inventory主机清单,ansible的主要功用在于批量主机操作,为了方便快捷的使用其中的部分主机,可以在inventory file中将其分组命名;
    默认的inventory file为/etc/ansible/hosts;
    inventory file可以有多个,且也可以通过Dynamic Inventory来动态生成;
    inventory文件遵循INI文件风格,中括号中的字符为组名。可以将同一个主机同时归并到多个不同的组中;此外,如果目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号来表明;

2. Ad-Hoc

2.1

ansible <主机> -m <模块>

3. playbook

3.1

3.2 变量

3.3 循环

3.3.1 普通循环 with_items

---
- hosts: localhost
  gather_facts: False
  tasks:
    - name: 普通循环
      debug: msg="{{ inventory_hostname }} ===> {{ item }}"
      with_items:
        - one
        - two
        - three
ok: [localhost] => (item=one) => {
    "msg": "localhost ===> one"
}
ok: [localhost] => (item=two) => {
    "msg": "localhost ===> two"
}
ok: [localhost] => (item=three) => {
    "msg": "localhost ===> three"
}

---
- hosts: localhost
  gather_facts: False
  tasks:
    - name: 普通循环2
      debug: msg="{{ inventory_hostname }} ===> item_key {{ item.key }} item_value {{item.value}}"
      with_items:
        - {key: "one", value: "value1"}
        - {key: "two", value: "value2"}
ok: [localhost] => (item={u'key': u'one', u'value': u'value1'}) => {
    "msg": "localhost ===> item_key one item_value value1"
}
ok: [localhost] => (item={u'key': u'two', u'value': u'value2'}) => {
    "msg": "localhost ===> item_key two item_value value2"
}

3.3.2 循环嵌套 with_nested

---
- hosts: localhost
  gather_facts: False
  tasks:
    - name: 循环嵌套
      debug: msg="{{ inventory_hostname }} ===> {{ item[0] }} {{item[1]}}"
      with_nested:
        - [1, 2]
        - ['a', 'b', 'c']

ok: [localhost] => (item=[1, u'a']) => {
    "msg": "localhost ===> 1 a"
}
ok: [localhost] => (item=[1, u'b']) => {
    "msg": "localhost ===> 1 b"
}
ok: [localhost] => (item=[1, u'c']) => {
    "msg": "localhost ===> 1 c"
}
ok: [localhost] => (item=[2, u'a']) => {
    "msg": "localhost ===> 2 a"
}
ok: [localhost] => (item=[2, u'b']) => {
    "msg": "localhost ===> 2 b"
}
ok: [localhost] => (item=[2, u'c']) => {
    "msg": "localhost ===> 2 c"
}

3.3.3 散列循环 with_dict

---
- hosts: localhost
  gather_facts: False
  vars:
    user:
      user1:
        name: user1
        shell: bash
      user2:
        name: user2
        shell: sh
  tasks:
    - name: 散列循环
      debug: msg="{{ inventory_hostname }} ===> {{ item.key }} ==> {{ item.value.name }} ==> {{ item.value.shell }}"
      with_dict: "{{ user }}"
ok: [localhost] => (item={'value': {u'shell': u'sh', u'name': u'user2'}, 'key': u'user2'}) => {
    "msg": "localhost ===> user2 ==> user2 ==> sh"
}
ok: [localhost] => (item={'value': {u'shell': u'bash', u'name': u'user1'}, 'key': u'user1'}) => {
    "msg": "localhost ===> user1 ==> user1 ==> bash"
}

3.3.4 文件匹配 with_fileglob

把路径下的所有匹配的文件(不包含子级目录中的文件)作为循环体;

---
- hosts: localhost
  gather_facts: False
  tasks: 
    - name: 文件匹配
      debug: msg="file ===> {{ item }}"
      with_fileglob:
        - /root/ansible/*yml
        - /etc/*
ok: [localhost] => (item=/root/ansible/01-ping.yml) => {
    "msg": "file ===> /root/ansible/01-ping.yml"
}
ok: [localhost] => (item=/root/ansible/02-variable.yml) => {
    "msg": "file ===> /root/ansible/02-variable.yml"
}
ok: [localhost] => (item=/root/ansible/03-vars.yml) => {
    "msg": "file ===> /root/ansible/03-vars.yml"
}
ok: [localhost] => (item=/root/ansible/04-task变量传递.yml) => {
    "msg": "file ===> /root/ansible/04-task变量传递.yml"
}
ok: [localhost] => (item=/root/ansible/05-loops.yml) => {
    "msg": "file ===> /root/ansible/05-loops.yml"
}
ok: [localhost] => (item=/root/ansible/test.yml) => {
    "msg": "file ===> /root/ansible/test.yml"
}

3.3.5 随机选择

在传入的list中随机选择一个

---
- hosts: localhost
  gather_facts: False
  tasks:
    name: 随机选择
    debug: msg="item ===> {{ item }}"
    with_random_choice:
      - 1
      - 2
      - 3
ok: [localhost] => (item=3) => {
    "msg": "item ===> 3"
}

3.3.6 条件判断

执行一次 cat /root/a.txt,讲结果register给host,然后判断 host.stdout 是否以Master开始,如果条件成立,则结束这个task;如果条件不成立,则2秒后重试,一共重试3次。

---
- hosts: localhost
  gather_facts: False
  tasks:
    - name: 条件选择
      shell: cat /root/a.txt
      register: host
      until: host.stdout.startswith("Master")
      retries: 3
      delay: 2

FAILED - RETRYING: 条件选择 (3 retries left).
FAILED - RETRYING: 条件选择 (2 retries left).
FAILED - RETRYING: 条件选择 (1 retries left).
fatal: [localhost]: FAILED! => {"attempts": 3, "changed": true, "cmd": "cat /root/a.txt", "delta": "0:00:00.002378", "end": "2019-09-26 16:42:52.311309", "rc": 0, "start": "2019-09-26 16:42:52.308931", "stderr": "", "stderr_lines": [], "stdout": "aaa\nbbb\nvvv", "stdout_lines": ["aaa", "bbb", "vvv"]}

3.3.7 文件优先匹配

根据传入的变量或者文件,从上往下匹配,如果匹配成功,则将这个对象当做 item 的值;

---
- hosts: localhost
  gather_facts: True
  tasks:
    - name: 文件优先匹配
      debug: msg="file ===> {{ item }} ===> {{ ansible_distribution }}"
      with_first_found:
        - "{{ ansible_distribution }}.yml"
        - "test.yml"
ok: [localhost] => (item=/root/ansible/test.yml) => {
    "msg": "file ===> /root/ansible/test.yml ===> CentOS"
}

3.3.8 register

register可以接受多个task的数据,每个返回的数据以列表的方式存储;

---
- hosts: localhost
  gather_facts: True
  tasks:
    - name: register接受多个task的结果当做变量临时存储
      shell: "{{ item }}"
      with_items:
        - hostname
        - uname
      register: ret
    - name: 打印循环
      debug: msg="{% for i in ret.results %} {{ i.stdout }} {% endfor %}"
    - name: 打印result
      debug: msg="{{ ret.results }}"

TASK [register接受多个task的结果当做变量临时存储] *********************************************************************************************************
changed: [localhost] => (item=hostname) => {"ansible_loop_var": "item", "changed": true, "cmd": "hostname", "delta": "0:00:00.002495", "end": "2019-09-26 17:04:38.308502", "item": "hostname", "rc": 0, "start": "2019-09-26 17:04:38.306007", "stderr": "", "stderr_lines": [], "stdout": "node1", "stdout_lines": ["node1"]}
changed: [localhost] => (item=uname) => {"ansible_loop_var": "item", "changed": true, "cmd": "uname", "delta": "0:00:00.002603", "end": "2019-09-26 17:04:38.418331", "item": "uname", "rc": 0, "start": "2019-09-26 17:04:38.415728", "stderr": "", "stderr_lines": [], "stdout": "Linux", "stdout_lines": ["Linux"]}

TASK [打印循环] ********************************************************************************************************************************
ok: [localhost] => {
    "msg": " node1\n  Linux\n "
}

3.4 lookups

从外部数据拉取信息;

3.4.1 lookups file

从文件拉取;

--- 
- hosts: localhost
  gather_facts: True
  vars:
    contents: "{{ lookup('file', '/etc/networks') }}"
  tasks:
    - name: test
      debug: msg="{{ contents }}"

    - name: lookups file
      debug: msg="The contents is {% for i in contents.split("\n") %}{{ i+' - ' }}{% endfor %}"
TASK [test] ******************************************************************************
ok: [localhost] => {
    "msg": "default 0.0.0.0\nloopback 127.0.0.0\nlink-local 169.254.0.0"
}

TASK [lookups file] **********************************************************************
ok: [localhost] => {
    "msg": "The contents is default 0.0.0.0 - loopback 127.0.0.0 - link-local 169.254.0.0 - "
}

3.4.2 lookups password(不生效)

加密拉取到的内容;

---
- hosts: localhost
  gather_facts: False
  vars:
    contents: "{{ lookup('password', '/etc/networks') }}"
  tasks:
    - name: 打印contents
      debug: msg="{{ contents }}"
ok: [localhost] => {
    "msg": "default 0.0.0.0\nloopback 127.0.0.0\nlink-local 169.254.0.0"
}

3.4.3 lookups pipe

调用subpress.Popen执行命令,然后将结果传递给变量;

---
- hosts: localhost
  gather_facts: False
  vars:
    contents: "{{ lookup('pipe', 'date +%Y-%m-%d ') }}"
  tasks:
    - name: lookups pipe
      debug: msg="{{ contents }}"
TASK [lookups pipe] *************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "2019-09-27"
}

3.5 条件

---
- hosts: all
  tasks:
    - name: 只有 192.168.187.130 可以执行
      debug: msg="{{ ansible_default_ipv4.address }}"
      when: ansible_default_ipv4.address == '192.168.187.130'
    - name: 只有 内存 > 500M 且 核心数 == 1 可以执行
      debug: msg="{{ ansible_fqdn }}"
      when: ansible_memtotal_mb > 500 and ansible_processor_cores == 1
    - name: 所有主机执行
      shell: hostname
      register: info
    - name: 主机名是 node1 可以执行
      debug: msg="{{ ansible_fqdn }}"
      when: info["stdout"] == "node1"
    - name: 主机名以 n 开头可以执行
      debug: msg="{{ ansible_fqdn }}"
      when: info["stdout"].startswith('n')
TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.187.128]
ok: [192.168.187.129]
ok: [192.168.187.130]

TASK [只有 192.168.187.130 可以执行] **************************************************************************************************************************************************************
skipping: [192.168.187.128]
skipping: [192.168.187.129]
ok: [192.168.187.130] => {
    "msg": "192.168.187.130"
}

TASK [只有 内存 > 500M 且 核心数 == 1 可以执行] *********************************************************************************************************************************************************
ok: [192.168.187.128] => {
    "msg": "node1"
}
ok: [192.168.187.129] => {
    "msg": "localhost.localdomain"
}
ok: [192.168.187.130] => {
    "msg": "localhost.localdomain"
}

TASK [所有主机执行] *******************************************************************************************************************************************************************************
changed: [192.168.187.130]
changed: [192.168.187.129]
changed: [192.168.187.128]

TASK [主机名是 node1 可以执行] **********************************************************************************************************************************************************************
ok: [192.168.187.128] => {
    "msg": "node1"
}
skipping: [192.168.187.129]
skipping: [192.168.187.130]

TASK [主机名以 n 开头可以执行] ************************************************************************************************************************************************************************
ok: [192.168.187.128] => {
    "msg": "node1"
}
skipping: [192.168.187.129]
skipping: [192.168.187.130]

3.6 Jinja2 filter


相关文章

网友评论

      本文标题:Linux - 04-ansible

      本文链接:https://www.haomeiwen.com/subject/ojzbrhtx.html