ansible

ansible简介

推荐文章https://www.cnblogs.com/clsn/p/7743792.html#auto_id_59

ansible 是一款强大的开源的自动化运维管理工具,底层代码主要用python编写,结合了paramiko jinjia2 yaml 三个模块

官网图片讲解

ansible:ansible的核心程序

host lnventory:记录了每一个由ansible管理的主机信息,包括:ssh端口,用户及密码,等

playbooks:任务剧本,yaml格式的文件,用来储存多任务,方便统一调用

core modules:ansible执行任何管理任务,都不是ansible自身完成的,而是由ansible的核心模块完成的;ansible在管理主机之前,先调用core modules中的模块,然后指明host lnventory中的主机中的主机,就可以完成管理主机,

custom modules:自定义模块,完成ansible核心模块无法完成的任务,此模块支持任何语言编写;

connection plugins:连接插件,ansible和host之间通信

ansible优点

  1. No client 不需要在被管控主机上安装任何软件
  2. No server 不用单独启用服务,能使用直接运行,使用时直接运行命令
  3. 支持sudo
  4. 基于ssh工作,安全
  5. 幂等性:无改变重复操作自动跳过机制
  6. 提供一个功能强大、操作性强的Web管理界面和REST API接口——AWX平台
  7. 配置简单、功能强大、扩展性强
  8. 支持API及自定义模块,可通过Python轻松扩展

ansible主要生成文件

/etc/ansible/ansible.cfg   #主配置文件
/etc/ansible/hosts   #管理的主机库
/usr/bin/ansible  #主程序
/usr/bin/ansible-doc   #文档
/usr/bin/ansible-playbook   #剧本

设置管理主机库

控制客户端主机的两种方式:

  1. 免密钥:ssh-keygen 可参考:https://www.cnblogs.com/du-z/p/10901774.html
  2. 参数形式:ansble_ssh_user=root ansible_ssh_pass=123456 ansible_ssh_port=22

编写host inventory

╭─root@localhost.localdomain ~  
╰─➤  vim /etc/ansible/hosts

#参数形式
[testhosts]
192.168.137.4 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=123456
192.168.137.5 ansible_ssh_user=root ansible_ssh_poet=22 ansible_ssh_pass=123456

.............................................................................
#免密钥模式
[testhosts]
192.168.137.4
192.168.137.5

ansible常用命令及模块

ansible-doc命令:

ansible-doc -l   #查看ansible支持的模块
ansible-doc -s model_name  #查看model_name模块的用法

ansible 常用模块

  • ping 模块 :ping查看客户端能否管理通信
  • command 模块 :命令
  • shell 模块 : shell命令(支持正则等)
  • copy 模块 : 远程复制相当于scp
  • cron 模块 : 计划任务模块
  • mail 模块 :邮件模块

ansible命令行模式

ansible <host-pattern> [options]
-f forks :启动并发线程数
-m model_name :要使用模块
-a args:特有的参数
ansible all -m ping #查看client端是否正常连通,即可管理
ansible testhosts -m setup #查看客户端信息
ansible testhosts -m copy -a 'src=/root/test.txt dest=/root/test1.txt' #copy文件到client端
ansible testhosts -m user -a "name=user1 state=present" #创建user1用户
ansible testhosts -m user -a "name=user1 state=absent" #删除user1用户
ansible testhosts -m yum -a "name=hpptd state=installed" #yum 安装apache
ansible testhosts -m service -a "name=httpd state=stoped encable=no" #停止httpd服务,开机不自起
ansible -m command -a "date" #查看时间

playbook

包括:

  1. tasks :一个tasks相当于一个play
  2. variables :变量,一次定义,多处调用
  3. templates :模板,可以区分不同主机的特点
  4. handlers :触发器,依赖于前一个任务,前一个任务如果执行改变,就会触发handlers

基础

╭─root@localhost.localdomain ~  
╰─➤  vim test.yaml
........................................... #文件内容
- hosts: testhosts
  remote_user: root
  tasks:
  - name: copy cjk
    copy: src=/root/cjk dest=/root/cjk
...........................................................
╭─root@localhost.localdomain ~  
╰─➤  ansible-playbook test.yaml 

PLAY [testhosts] ****************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************
ok: [192.168.137.4]
ok: [192.168.137.5]

TASK [copy httpd.conf] **********************************************************************************************************
changed: [192.168.137.4]
changed: [192.168.137.5]

PLAY RECAP **********************************************************************************************************************
192.168.137.4              : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.137.5              : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

变量

╭─root@localhost.localdomain ~  
╰─➤  vim test.yaml
.................................................................#文件内容
- hosts: testhosts
  remote_user: root
  vars:
  - file: cjk
  tasks:
  - name: copy cjk
    copy: src=/root/{{ file }} dest=/root/{{ file }}
  - name: write cjk
    command: echo "hello world!" >> /root/{{ file }}
....................................................................................

╭─root@localhost.localdomain ~  
╰─➤  ansible-playbook test.yaml   

PLAY [testhosts] ********************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [192.168.137.4]
ok: [192.168.137.5]

TASK [copy cjk] *********************************************************************************************************************
ok: [192.168.137.4]
ok: [192.168.137.5]

TASK [weite cjk] ********************************************************************************************************************
changed: [192.168.137.5]
changed: [192.168.137.4]

PLAY RECAP **************************************************************************************************************************
192.168.137.4              : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.137.5              : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

注册变量

╭─root@localhost.localdomain ~  
╰─➤  vim test.yaml 
.......................................................#文件内容
- hosts: testhosts
  remote_user: root
  tasks:
  - name: get date
    command: date '+%F %T'
    register: date_output       #相当于date_output=$(date)
  - name: echo date_output
    shell: echo {{ date_output.stdout }} >> /root/cjk     #.stdout  把内容标准输出
..................................................................................

迭代1

类似于python中的for 循环,可灵活运用

╭─root@localhost.localdomain ~  
╰─➤  vim test.yaml 
..........................................................#文件内容
- hosts: testhosts
  remote_user: root
  tasks:
  - name: create users
    user: name={{ item }} state=absent
    with_items:
    - user1
    - user2
    - user3
....................................................................
╭─root@localhost.localdomain ~  
╰─➤  ansible-playbook test.yaml 

PLAY [testhosts] *******************************************************************

TASK [Gathering Facts] *************************************************************
ok: [192.168.137.4]
ok: [192.168.137.5]

TASK [create users] ****************************************************************
ok: [192.168.137.5] => (item=user1)
ok: [192.168.137.4] => (item=user1)
ok: [192.168.137.5] => (item=user2)
ok: [192.168.137.4] => (item=user2)
ok: [192.168.137.5] => (item=user3)
ok: [192.168.137.4] => (item=user3)

PLAY RECAP *************************************************************************
192.168.137.4              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.137.5              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

迭代2

╭─root@localhost.localdomain ~  
╰─➤  vim test.yaml 
..........................................................#文件内容
- hosts: testhosts
  remote_user: root
  tasks:
  - name: create users
    user: name={{ item.name }} state=absent groups={{ item.groups }}
    with_items:
    - { name: 'testuser1', groups: 'group1' }
    - { name: 'testuser2', groups: 'group2' }
....................................................................

触发器

notify:如果执行的任务被改变,会触发handlers任务

╭─root@localhost.localdomain ~  
╰─➤  vim test.yaml

................................................#文件内容
- hosts: testhosts
  remote_user: root
  tasks:
  - name: copy cjk
    copy: src=/root/cjk dest=/root/cjk
    notify:
    - back cjk
  handlers:
  - name: back cjk
    command: cp /root/cjk /home/cjk.back
  - name: test
    command: rm -rf /root/cjk
.....................................................................
╭─root@localhost.localdomain ~  
╰─➤  ansible-playbook test.yaml

PLAY [testhosts] *******************************************************************

TASK [Gathering Facts] *************************************************************
ok: [192.168.137.4]
ok: [192.168.137.5]

TASK [copy cjk] ********************************************************************
changed: [192.168.137.4]
changed: [192.168.137.5]

RUNNING HANDLER [back cjk] *********************************************************
changed: [192.168.137.5]
changed: [192.168.137.4]

PLAY RECAP *************************************************************************
192.168.137.4              : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.137.5              : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

╭─root@localhost.localdomain ~  
╰─➤  ansible-playbook test.yaml

PLAY [testhosts] *******************************************************************

TASK [Gathering Facts] *************************************************************
ok: [192.168.137.5]
ok: [192.168.137.4]

TASK [copy cjk] ********************************************************************
ok: [192.168.137.4]
ok: [192.168.137.5]

PLAY RECAP *************************************************************************
192.168.137.4              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.137.5              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

when语句

when条件语句:可以根据setup模块显示出客户端信息为依据来判断

╭─root@localhost.localdomain ~  
╰─➤  vim test.yaml 
.............................................#文件内容
- hosts: testhosts
  remote_user: root
  tasks:
  - name: restart network
    service: name=network state=restarted
    when: ansible_distribution=='CentOS' and ansible_distribution_major_version=='8'
..................................................................
╭─root@localhost.localdomain ~  
╰─➤  ansible-playbook test.yaml

PLAY [testhosts] *******************************************************************

TASK [Gathering Facts] *************************************************************
ok: [192.168.137.4]
ok: [192.168.137.5]

TASK [restart network] *************************************************************
skipping: [192.168.137.4]
skipping: [192.168.137.5]

PLAY RECAP *************************************************************************
192.168.137.4              : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
192.168.137.5              : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

异常处理

ignore_errors:如果任务出错,直接跳过,不会影响其他任务

╭─root@localhost.localdomain ~  
╰─➤  vim test.yaml 
........................................#文件内容
- hosts: testhosts
  remote_user: root
  tasks:
  - name: restart httpd
    service: name=network state=restarted
    ignore_errors: yes
  - name: test
    command: echo 'hello' > /root/cjk
...........................................................................................
╭─root@localhost.localdomain ~  
╰─➤  ansible-playbook test.yaml

PLAY [testhosts] *******************************************************************

TASK [Gathering Facts] *************************************************************
ok: [192.168.137.4]
ok: [192.168.137.5]

TASK [restart httpd] ***************************************************************
fatal: [192.168.137.5]: FAILED! => {"changed": false, "msg": "Unable to start service network: Job for network.service failed because the control process exited with error code. See "systemctl status network.service" and "journalctl -xe" for details.
"}
...ignoring
changed: [192.168.137.4]

TASK [test] ************************************************************************
changed: [192.168.137.4]
changed: [192.168.137.5]

PLAY RECAP *************************************************************************
192.168.137.4              : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.137.5              : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=1   

template

第一步:编写.yaml文件将copy 换成template

╭─root@localhost.localdomain ~  
╰─➤  vim test.yaml   
.......................................#文件内容
- hosts: testhosts
  remote_user: root
  tasks:
  - name: copy cjk
    template: src=/root/cjk dest=/root/cjk
.............................................................

第二步:编辑要拷贝的文件cjk,把要区分的地方用用变量定义{{ 变量名 }}

╭─root@localhost.localdomain ~  
╰─➤  vim cjk

hello world!!!
this is {{ ip }}

第三步:vim /etc/ansible/hosts 在主机后面定义变量的值:变量名=变量值

╭─root@localhost.localdomain ~  
╰─➤  vim /etc/ansible/hosts 

[testhosts]
192.168.137.4 ansible_ssh_user=root ansible_ssh_pass=123456 ansible_ssh_port=22 ip=1
92.168.137.4
192.168.137.5 ansible_ssh_user=root ansible_ssh_pass=123456 ansible_ssh_port=22 ip=1
92.168.137.5

第四步:执行

╭─root@localhost.localdomain ~  
╰─➤  ansible-playbook test.yaml

第五步:验证

192.168.137.4 主机

╭─root@localhost.localdomain ~  
╰─➤  cat cjk
hello world!!!
this is 192.168.137.4

192.168.137.5 主机

╭─root@localhost.localdomain ~  
╰─➤  cat cjk    
hello world!!!
this is 192.168.137.5

roles

作用:定义角色,减少代码的复习

第一步:roles目录

╭─root@localhost.localdomain ~  
╰─➤  mkdir -pv playbookse/roles/{webservers,dbservers}/{files,tasks,vars,templates,handlers}

第二步:编写文件

#编写tasks文件

╭─root@localhost.localdomain ~  
╰─➤  vim /root/playbooks/roles/webservers/tasks/main.yaml
......................................................................
- name: yum httpd
  yum: name=httpd state=installed
- name: copy httpd.conf
  template: src={{ conf_file }} dest=/etc/httpd/conf/{{ conf_file }}
  notify:
  - restart httpd
.....................................................................

#编写vars文件

╭─root@localhost.localdomain ~  
╰─➤  vim /root/playbooks/roles/webservers/vars/main.yaml
..................................#定义变量
conf_file: httpd.conf
....................................

#编写handlers文件

╭─root@localhost.localdomain ~/playbooks  
╰─➤  vim roles/webservers/handlers/main.yaml 
....................................................#触发器
- name: restart httpd
  service: name=httpd state=restarted
........................................................

#复制文件到templates目录下

╭─root@localhost.localdomain ~  
╰─➤  cp /etc/httpd/conf/httpd.conf /root/playbooks/roles/webservers/templates/

#编写inventory文件

╭─root@localhost.localdomain ~  
╰─➤  mkdir /root/playbooks/inventory/ 
╭─root@localhost.localdomain ~  
╰─➤  vim  /root/playbooks/invnetoryinvnetory/testhosts 
.........................................#给文件中的变量赋值template
[testhosts]
192.168.137.4 ansible_ssh_user=root ansible_ssh_pass=123456 ansible_ssh_port=22 port=8888
192.168.137.5 ansible_ssh_user=root ansible_ssh_pass=123456 ansible_ssh_port=22 port=9999
...............................................................invnetory/testhosts

#编写文件中的变量内容

╭─root@localhost.localdomain ~  
╰─➤  vim /root/playbooks/roles/webservers/templates/httpd.conf
............................................#修改文件中的变量template
...

Listen {{ port }}

...
..................................................................

#编辑启动文件

╭─root@localhost.localdomain ~  
╰─➤  vim /root/playbooks/httpd.yaml
...............................................................
- hosts: testhosts
  remote_user: root
  roles:
  - webservers
.................................................................

第三步:查看playbooks目录

╭─root@localhost.localdomain ~  
╰─➤  tree playbooks
playbooks
├── httpd.yaml
├── inventory
│   └── testhosts
└── roles
    ├── dbservers
    │   ├── files
    │   ├── handlers
    │   ├── tasks
    │   ├── templates
    │   └── vars
    └── webservers
        ├── files
        │   └── httpd.conf
        ├── handlers
        │   └── main.yaml
        ├── tasks
        │   └── main.yaml
        ├── templates
        │   └── httpd.conf
        └── vars
            └── main.yaml

第四步:执行

╭─root@localhost.localdomain ~  
╰─➤  cd playbooks    #需要在有启动文件(.yaml)的目录中执行
╭─root@localhost.localdomain ~/playbooks  
╰─➤  ansible-playbook httpd.yaml 

第五步:检验

192.168.173.4主机

╭─root@localhost.localdomain ~  
╰─➤  ss -ntl
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128            *:22                         *:*                  
LISTEN     0      128            *:8888                       *:*                  
LISTEN     0      100    127.0.0.1:25                         *:*                  
LISTEN     0      128           :::22                        :::*                  
LISTEN     0      100          ::1:25                        :::*                  

192.168.173.5主机

╭─root@localhost.localdomain ~  
╰─➤  ss -ntl
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128            *:9999                       *:*                  
LISTEN     0      128            *:22                         *:*                  
LISTEN     0      100    127.0.0.1:25                         *:*                  
LISTEN     0      128           :::22                        :::*                  
LISTEN     0      100          ::1:25                        :::*                  

原文地址:https://www.cnblogs.com/du-z/p/11103559.html