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优点
- No client 不需要在被管控主机上安装任何软件
- No server 不用单独启用服务,能使用直接运行,使用时直接运行命令
- 支持sudo
- 基于ssh工作,安全
- 幂等性:无改变重复操作自动跳过机制
- 提供一个功能强大、操作性强的Web管理界面和REST API接口——AWX平台
- 配置简单、功能强大、扩展性强
- 支持API及自定义模块,可通过Python轻松扩展
ansible主要生成文件
/etc/ansible/ansible.cfg #主配置文件
/etc/ansible/hosts #管理的主机库
/usr/bin/ansible #主程序
/usr/bin/ansible-doc #文档
/usr/bin/ansible-playbook #剧本
设置管理主机库
控制客户端主机的两种方式:
- 免密钥:ssh-keygen 可参考:https://www.cnblogs.com/du-z/p/10901774.html
- 参数形式: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
包括:
- tasks :一个tasks相当于一个play
- variables :变量,一次定义,多处调用
- templates :模板,可以区分不同主机的特点
- 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 :::*