ansible是一个自动化批量部署工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。
paramiko
jinja2
yaml
Ansible:Ansible的核心程序
Host Lnventory:记录了每一个由Ansible管理的主机信息,信息包括ssh端口,root账号密码,ip地址等等。可以通过file来加载,可以通过CMDB加载
Playbooks:yaml格式文件,多个任务定义在一个文件中,使用时可以统一调用,“剧本”用来定义那些主机需要调用那些模块来完成的功能。
Core Modules:Ansible执行任何管理任务都不是由Ansible自己完成,而是由核心模块完成;Ansible管理主机之前,先调用core Modules中的模块,然后指明管理Host Lnventory中的主机,就可以完成管理主机。
Custom Modules:自定义模块,完成Ansible核心模块无法完成的功能,此模块支持任何语言编写。
Cinnection Plugins:连接插件,Ansible和Host通信使用
ansible加载hosts文件,通过免秘钥或配置文件参数来批量管理主机
agent:ansibel不需要客户端或agent(代理)
yum install epel-release -y
yum install ansible -y
ansible server :192.168.30.30
受管理的客户端1:192.68.30.149
受管理的客户端2:192.68.30.150
第一种方法:
ansible server :ssh-keygen
[root@c1 ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): id_rsa.pub
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_rsa.pub.
Your public key has been saved in id_rsa.pub.pub.
The key fingerprint is:
SHA256:8E0RUOqcAZCmrA0eyOaa9O8rLbyAe2IpfPv8R8xvIL0 root@c1
The key's randomart image is:
+---[RSA 2048]----+
| .o. .o+. |
| o . . . |
|o. o . o . |
|o+o = = |
|++. S . |
|o+. . * |
|=o+ . o + |
|==o*.. E o |
|+o.oO*o.. . |
+----[SHA256]-----+
scp id_rsa.pub root@client ip:/root/.ssh/authorized_keys
[root@c1 ~]# scp /root/.ssh/id_rsa.pub [email protected]:/root/.ssh/authorized_keys
[email protected]'s password:
id_rsa.pub 100% 389 411.2KB/s 00:00
[root@c1 ~]# scp /root/.ssh/id_rsa.pub [email protected]:/root/.ssh/authorized_keys
[email protected]'s password:
id_rsa.pub 100% 389 11.2KB/s 00:00
ansible配置
[root@c1 ~]# vim /etc/ansible/ansible.cfg
......
remote_port = 22 #ssh端口号默认22,如果改的话ssh配置的端口号也得改
......
private_key_file = /root/.ssh/id_rsa #私钥文件路径
......
配置受管理的客户端组
[root@c1 ~]# vim /etc/ansible/hosts
......
#在最后添加
[testhosts]
192.168.30.149
192.168.30.151
ansible连通性测试:
[root@c1 ~]# ansible testhosts -m ping
192.168.30.149 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.30.151 | SUCCESS => {
"changed": false,
"ping": "pong"
}
执行命令测试:
[root@c1 ~]# ansible testhosts -m command -a 'uptime'
注意:第一次执行,需要输入yes来验证公钥,后续无需再输入
再次执行
[root@c1 ~]# ansible testhosts -m command -a 'uptime'
192.168.30.151 | CHANGED | rc=0 >>
15:44:34 up 32 min, 3 users, load average: 0.00, 0.01, 0.05
192.168.30.149 | CHANGED | rc=0 >>
15:44:34 up 4:00, 4 users, load average: 0.00, 0.01, 0.05
第二种方法:
vim /etc/ansible/hosts
ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=root
在hosts文件的末尾添加
[testhosts]
192.168.30.149 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=root
192.168.30.151 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=root
保存退出进行ansible连通性测试
[root@c1 ~]# ansible testhosts -m ping
192.168.30.149 | FAILED! => {
"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host."
}
192.168.30.151 | FAILED! => {
"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host."
出现上面问题是因为启用了主机密钥检查,所以我们可以修改/etc/ansible/ansible.cfg配置文件来跳过这个检查
[root@c1 ~]# vim /etc/ansible/ansible.cfg
host_key_checking = False #默认是注释的,打开注释即可
保存退出再测试结果正常:
[root@c1 ~]# ansible testhosts -m ping
192.168.30.151 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.30.149 | SUCCESS => {
"changed": false,
"ping": "pong"
}
ansible-doc -l #查看支持的模块
ansible-doc -s MODEL_NAME #查看模块用法
ansible命令应用基础
ansible [options]
-f fork:启动并发 线程数
-m model_name:要使用的模块
-a args:特有的参数
ansible all -m ping #查看client端是否正常ping通
ansible webserver -m setup #查看客户端信息
ansible webserver -m copy -a 'src=/root/git_test/code.txt dest=/root/test' #copy文件到client端
ansible webserver -m user -a "name=test state=present" #创建test用户
ansible webserver -m user -a "name=test state=absent" #删除test用户
ansible webserver -m yum -a 'name=epel-relese state=latest' #yum安装
ansible webserver -m systemd -a 'name=httpd state=stopped enabled=no' #停止httpd服务
ansible webserver -m script -a '/tmp/test,sh' #运行脚本
ansible webserver -m command 'date' #查看时间
一个任务代表一个play,多个play组合成叫做playbooks
一个yaml或yml文件就是一个playbooks
yaml介绍
yaml是一个可读性高的用来表达资料序列的格式,yaml参考了其他多种语言,包括:xml,c语言,python,perl以及电子邮件格式RFC2822等,ClarkEvans在2001年在首次发表了这种语言。
yaml的可读性好
yaml和脚本语言的交互性好
yaml使用实现语言的数据类型
yaml有一个一致的信息模型
yaml易于实现
yaml可以基于流程来处理
yaml表达能力强,扩展性好
ansible执行yaml/yml文件格式:
ansible-playbook *.yml/*.yaml
例1:playbook基础语法比较严格
- hosts: testhosts #声明主机组
remote_user: root #声明以谁的身份执行
tasks: #任务组
- name: yum remove nginx #任务名
yum: name=nginx state=absent #模块:用法
- name: yum install httpd
yum: name=httpd state=latest
- name: systemctl start httpd
systemd: name=httpd state=started
[root@c1 ~]# ansible-playbook test.yml
PLAY [testhosts] ***********************************************************************
TASK [Gathering Facts] *****************************************************************
ok: [192.168.30.151]
ok: [192.168.30.149]
TASK [yum remove nginx] ****************************************************************
changed: [192.168.30.151]
changed: [192.168.30.149]
TASK [yum install httpd] ***************************************************************
changed: [192.168.30.151]
changed: [192.168.30.149]
TASK [systemctl start httpd] ***********************************************************
changed: [192.168.30.151]
changed: [192.168.30.149]
PLAY RECAP *****************************************************************************
192.168.30.149 : ok=4 changed=3 unreachable=0 failed=0
192.168.30.151 : ok=4 changed=3 unreachable=0 failed=0
例2:有变量的playbook
- hosts: testhosts
remote_user: root
vars:
- packages: tree
tasks:
- name: yum install tree
yum: name={{ packages }} state=latest
- name: yum install httpd
yum: name=httpd state=latest
- name: systemctl start httpd
systemd: name=httpd state=started
[root@c1 ~]# ansible-playbook test.yml
PLAY [testhosts] ***********************************************************************
TASK [Gathering Facts] *****************************************************************
ok: [192.168.30.151]
ok: [192.168.30.149]
TASK [yum install tree] ****************************************************************
changed: [192.168.30.151]
changed: [192.168.30.149]
TASK [yum install httpd] ***************************************************************
ok: [192.168.30.151]
ok: [192.168.30.149]
TASK [systemctl start httpd] ***********************************************************
ok: [192.168.30.151]
ok: [192.168.30.149]
PLAY RECAP *****************************************************************************
192.168.30.149 : ok=4 changed=1 unreachable=0 failed=0
192.168.30.151 : ok=4 changed=1 unreachable=0 failed=0
已经执行过的任务再次执行显示ok,这就是幂等性:一种操作重复多次结果相同
例3:迭代
- hosts: testhosts
remote_user: root
vars:
- packages: tree
tasks:
- name: yum install tree
yum: name={{ packages }} state=latest
- name: yum install httpd
yum: name=httpd state=latest
- name: create many user
user: name={{ item }}
with_items:
- test1
- test2
- test3
[root@c1 ~]# ansible-playbook test.yml
PLAY [testhosts] ***********************************************************************
TASK [Gathering Facts] *****************************************************************
ok: [192.168.30.149]
ok: [192.168.30.151]
TASK [yum install tree] ****************************************************************
ok: [192.168.30.151]
ok: [192.168.30.149]
TASK [yum install httpd] ***************************************************************
ok: [192.168.30.151]
ok: [192.168.30.149]
TASK [create many user] ****************************************************************
changed: [192.168.30.151] => (item=test1)
changed: [192.168.30.149] => (item=test1)
changed: [192.168.30.151] => (item=test2)
changed: [192.168.30.149] => (item=test2)
changed: [192.168.30.151] => (item=test3)
changed: [192.168.30.149] => (item=test3)
PLAY RECAP *****************************************************************************
192.168.30.149 : ok=4 changed=1 unreachable=0 failed=0
192.168.30.151 : ok=4 changed=1 unreachable=0 failed=0
例4:触发器notify
- hosts: testhosts
remote_user: root
vars:
- packages: tree
tasks:
- name: yum install tree
yum: name={{ packages }} state=latest
- name: create many user
user: name={{ item }}
with_items:
- test1
- test2
- test3
- name: cp testcp.txt
copy: src=/root/testcp.txt dest=/root/
notify:
- restart httpd
handlers:
- name: restart httpd
systemd: name=httpd state=restarted
[root@c1 ~]# ansible-playbook test.yml
PLAY [testhosts] ***********************************************************************
TASK [Gathering Facts] *****************************************************************
ok: [192.168.30.151]
ok: [192.168.30.149]
TASK [yum install tree] ****************************************************************
ok: [192.168.30.151]
ok: [192.168.30.149]
TASK [create many user] ****************************************************************
ok: [192.168.30.149] => (item=test1)
ok: [192.168.30.151] => (item=test1)
ok: [192.168.30.151] => (item=test2)
ok: [192.168.30.149] => (item=test2)
ok: [192.168.30.149] => (item=test3)
ok: [192.168.30.151] => (item=test3)
TASK [cp testcp.txt] *******************************************************************
changed: [192.168.30.149]
changed: [192.168.30.151]
RUNNING HANDLER [restart httpd] ********************************************************
changed: [192.168.30.151]
changed: [192.168.30.149]
PLAY RECAP *****************************************************************************
192.168.30.149 : ok=5 changed=2 unreachable=0 failed=0
192.168.30.151 : ok=5 changed=2 unreachable=0 failed=0
template:模板
例5:模板templates
- hosts: testhosts
remote_user: root
vars:
- packages: tree
tasks:
- name: yum install tree
yum: name={{ packages }} state=latest
- name: create many user
user: name={{ item }}
with_items:
- test1
- test2
- test3
- name: cp httpd.conf
template: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify:
- restart httpd
handlers:
- name: restart httpd
systemd: name=httpd state=restarted
将ansible server端的httpd.conf配置文件LISTEN监听端口改为{{ port }}保存
......
Listen {{ port }}
......
修改ansible的hosts文件为主机组的主机添加变量
[testhosts]
192.168.30.149 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=root port=6500
192.168.30.151 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=root port=6600
[root@c1 ~]# ansible-playbook test.yml
PLAY [testhosts] ***********************************************************************
TASK [Gathering Facts] *****************************************************************
ok: [192.168.30.151]
ok: [192.168.30.149]
TASK [yum install tree] ****************************************************************
ok: [192.168.30.151]
ok: [192.168.30.149]
TASK [create many user] ****************************************************************
ok: [192.168.30.151] => (item=test1)
ok: [192.168.30.149] => (item=test1)
ok: [192.168.30.151] => (item=test2)
ok: [192.168.30.149] => (item=test2)
ok: [192.168.30.151] => (item=test3)
ok: [192.168.30.149] => (item=test3)
TASK [cp httpd.conf] *******************************************************************
changed: [192.168.30.151]
changed: [192.168.30.149]
RUNNING HANDLER [restart httpd] ********************************************************
changed: [192.168.30.151]
changed: [192.168.30.149]
PLAY RECAP *****************************************************************************
192.168.30.149 : ok=5 changed=2 unreachable=0 failed=0
192.168.30.151 : ok=5 changed=2 unreachable=0 failed=0
执行完毕之后查看客户端所有启用的端口号发现149客户端端口6500已启用,151客户端6600已启用
有这样的情景:有三台需要管理的主机安装了不同的软件httpd、php、mysql,现又有一台主机要安装httpd和php,如果再新定义playbook就会重复之前的代码比较麻烦,这时就要用到roles,创建后利于模块化调用,多次调用。
把每个play封装到角色里,调用时只需添加角色就行
hosts: 后可添加主机组,ip或多个ip
hosts: host1
role:
- webserver
hosts: host2
role:
- phpserver
hosts: host3
role:
-dbserver
hosts: host4
role:
-webserver
-phpserver
创建roles及角色目录
[root@c1 ~]# mkdir -pv ansible_playbooks/roles/{webserver,phpserver}/{files,handlers,tasks,templates,vars}
mkdir: 已创建目录 "ansible_playbooks"
mkdir: 已创建目录 "ansible_playbooks/roles"
mkdir: 已创建目录 "ansible_playbooks/roles/webserver"
mkdir: 已创建目录 "ansible_playbooks/roles/webserver/files"
mkdir: 已创建目录 "ansible_playbooks/roles/webserver/handlers"
mkdir: 已创建目录 "ansible_playbooks/roles/webserver/tasks"
mkdir: 已创建目录 "ansible_playbooks/roles/webserver/templates"
mkdir: 已创建目录 "ansible_playbooks/roles/webserver/vars"
mkdir: 已创建目录 "ansible_playbooks/roles/phpserver"
mkdir: 已创建目录 "ansible_playbooks/roles/phpserver/files"
mkdir: 已创建目录 "ansible_playbooks/roles/phpserver/handlers"
mkdir: 已创建目录 "ansible_playbooks/roles/phpserver/tasks"
mkdir: 已创建目录 "ansible_playbooks/roles/phpserver/templates"
mkdir: 已创建目录 "ansible_playbooks/roles/phpserver/vars"
用roles将testhosts主机组中主机配置相同的httpd服务
(1)配置roles同级yml文件,命名的名字一定为site.yml
- hosts: testhosts
remote_user: root
roles:
- webserver
(2)配置角色webserver
将httpd配置文件拷贝到files目录下,用files目录下的文件配置出的主机是一样的,如果用templates模板,修改监听端口号5000
[root@c1 ~]# cp /etc/httpd/conf/httpd.conf playbooks/roles/webserver/files/
(3)创建tasks的main.yml(文件名必须为main,后缀可以是yaml,yml)文件并编辑如下内容
[root@c1 ~]# vim playbooks/roles/webserver/tasks/main.yml
- name: yum install httpd
yum: name=httpd state=latest
- name: copy httpd conf
copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf
notify:
- start httpd
上述程序添加了notify触发器需要在handlers下编写触发操作写在main.yml中
[root@c1 ~]# vim playbooks/roles/webserver/handlers/main.yml
- name: start httpd
systemd: name=httpd state=started
(4)在roles同级目录里运行:
[root@c1 playbooks]# ansible-playbook site.yml
PLAY [testhosts] ***************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.30.151]
ok: [192.168.30.149]
TASK [webserver : yum install httpd] *******************************************
changed: [192.168.30.149]
changed: [192.168.30.151]
TASK [webserver : copy httpd conf] *********************************************
changed: [192.168.30.149]
changed: [192.168.30.151]
RUNNING HANDLER [webserver : start httpd] **************************************
changed: [192.168.30.151]
changed: [192.168.30.149]
PLAY RECAP *********************************************************************
192.168.30.149 : ok=4 changed=3 unreachable=0 failed=0
192.168.30.151 : ok=4 changed=3 unreachable=0 failed=0
在客户端看服务端口号已启动都为5000
配置不同端口的httpd服务就用到templates
(1)将httpd配置文件拷贝到templates目录下并将httpd的端口号改为如下格式的变量
......
Listen {{ port }}
......
(2)修改ansible的hosts文件为主机组的主机添加变量
[testhosts]
192.168.30.149 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=root port=6500
192.168.30.151 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=root port=6600
(3)在roles同级目录执行site.yml
[root@c1 playbooks]# ansible-playbook site.yml
PLAY [testhosts] ***************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.30.151]
ok: [192.168.30.149]
TASK [webserver : yum install httpd] *******************************************
changed: [192.168.30.149]
changed: [192.168.30.151]
TASK [webserver : copy httpd conf] *********************************************
changed: [192.168.30.149]
changed: [192.168.30.151]
RUNNING HANDLER [webserver : start httpd] **************************************
changed: [192.168.30.151]
changed: [192.168.30.149]
PLAY RECAP *********************************************************************
192.168.30.149 : ok=4 changed=3 unreachable=0 failed=0
192.168.30.151 : ok=4 changed=3 unreachable=0 failed=0
执行完毕之后查看客户端所有启用的端口号发现149客户端端口6500已启用,151客户端6600已启用