ansible是由 Python 编写的强大的配置管理解决方案,ansible 的特点就在于它的简洁与高效率
ansible与其他的配置管理工具不同点在于:不需要你在想要配置的每个节点上安装自己的组件,也就是说,ansible管理各个节点不需要依赖于agent端
ansible是基于模块工作的,实现了批量系统配置、批量程序部署、批量运行命令等功能。ansible本身没有批量部署的能力,真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架
(一)Ansible 入门
官网:https://www.ansible.com
官方文档:http://docs.ansible.com/ansible/latest/index.html
1:Puppet 由Ruby语言所研发
2:Saltstack 由Python语言研发
3:Ansible 由Python语言研发
Ansible 工具并不使用agent端守护进程,它也不需要任何额外的自定义安全架构,因此它的部署可以说是十分容易。你需要的全部东西便是 SSH 客户端和服务器了。
①:
192.168
.1
.100 - 在你本地的工作站或服务器上安装 Ansible。
②:文件服务器
1到代理服务器
3 - 使用
192.168
.1
.100 和 Ansible 来自动管理所有的服务器。
③:SSH - 在
192.168
.1
.100 和本地/远程的服务器之间设置 SSH 密钥。
(二)Ansible 安装
(也可以使用pip3进行安装)
1: 在ansible主机上安装ansible
yum install -y ansible
2:由于ansible支持ssh协议,因此使用ssh协议实现对被管理节点的管理是ansible的常用做法,且将对于的hosts文件分发下去
ssh-keygen -t rsa -P
""
ssh-copy-id -i .ssh/id_rsa.pub root
@192.
168.23.
10
ssh-copy-id -i .ssh/id_rsa.pub root
@192.
168.23.
11
ssh-copy-id -i .ssh/id_rsa.pub root
@192.
168.23.
12
3:配置文件介绍
主配置文件:/etc/ansible/ansible.cfg
主程序:
ansible
ansible-playbook
ansible-doc -l 可以列出所有的ansible所支持的模块
4:在ansible的配置目录中一共有三个文件
[root
@centos ansible]# ll
总用量
24
-rw-r--r--
1 root root
18066
6月
2
05:
49 ansible.cfg
-rw-r--r--
1 root root
1016
6月
2
05:
49 hosts
drwxr-xr-x
2 root root
6
6月
2
05:
49 roles
hosts文件是用来指定被ansible管理的主机,也就是资产清单
roles是用来指定每一个节点的角色
编辑hosts文件(hosts文件有些注释的说明,可以先删除)。只要是hosts文件中定义的主机都可被ansible管理
# 指定web服务的主机
[webservers]
192.168.
23.9
192.168.
23.10
# 指定db服务的主机
[dbservers]
192.168.
23.10
192.168.
23.11
5:ansible不需要启动,就像一个脚本程序一样,可以直接的运行
ansible all -m ping # 这里的all指的是所有在hosts文件中定义的主机 -m:表示调用ansible自带的模块ping,对所有被管控的主机执行ping操作
6:获取所有的ansible的模块列表,模块的使用
ansible-doc -l 查看哪些模块可以用
ansible-doc -s 模块名 查看如何只用模块
(三)ansible主要模块介绍
1: 显示ansible自身可调用的模块
ansible-doc -
l
2:显示指定模块ping的功能
ansible-doc -s ping
3:
command模块介绍
command模块就是在远程主机上执行命令,执行
shell命令的模块,例如下面的 -
a:指的是运行命令。而 -
m:
command可以省略掉,默认就是 -
m
command,就是执行
shell命令。 下面两条命令是一样的结果
ansible webservers -
m
command -
a
"ifconfig"
ansible webservers -
a
"ifconfig"
4:
shell模块介绍
-
m
command模块是不支持管道的,如果要支持管道的话,需要使用
shell模块
下面是通过
shell模块给被管理主机的yhy用户创建密码
ansible webservers -
m
command -
a
"useradd yhy"
ansible webservers -
m
shell -
a
"echo '123' | passwd --stdin yhy"
5:
copy模块介绍
将ansible主机上的文件复制到指定的远程节点上
ansible
all -
m
copy -
a
"src=/etc/hosts dest=/tmp/hosts"
当然在复制过程中也可以指定 owner=,group= ,
mode= , 例如:
ansible
all -
m
copy -
a
"src=/etc/fstab dest=/tmp owner=yhy group=yhy mode=644"
同样的也可以将内容复制过去。例如
ansible
all -
m
copy -
a
"content='hello i will come back ' dest=/tmp/hello owner=yhy group=yhy mode=644"
6:cron模块
设置远程节点的cron定时任务,这里的minute指的是时间,job指的是定时任务,name指的是这个定时任务的名称,其实这里隐含了一个state参数,默认的state参数是present,表示是创建名称为synctime的任务
ansible
all -
m cron -
a
"minute=*/30 job='/usr/sbin/ntpdate time.nist.gov $> /dev/null' name=time_async"
既然有创建任务也有删除任务,指定absent就是删除任务
ansible
all -
m cron -
a
"state=absent name=time_async"
7:fetch模块(基本不用)
从远端节点拉取文件到本地,将/etc/fstab拷贝到本机的/tmp目录下
ansible
192.168.
43.13 -
m fetch -
a
"src=/etc/fstab dest=/tmp"
[root@
7 ansible]#
ll /tmp/
192.168.
43.13/etc/fstab
-rw-r--r--
1 root root
501
9月
27
19:
30 /tmp/
192.168.
43.13/etc/fstab
8:
file模块
设定被管控主机的文件的属性
创建链接文件
创建目录
ansible
all -
m
file -
a
"src=/tmp/fstab path=/tmp/fstab.link state=link" 给管控主机的文件创建链接文件
ansible
192.168.
43.13 -
m
file -
a
"path=/root/anaconda-ks.cfg owner=root group=root mode=777" 给被管控主机的文件修改权限和属主
ansible
all -
m
file -
a
"path=/tmp/tmpdir state=directory" 给被管控主机创建目录
9:
hostname模块
管理远程节点的
hostname
ansible
192.168.
23.10 -
m
hostname -
a
"name=nginx"
10:pip模块
管理Python库依赖(首先确保pip2已经安装,如果没有安装,需要先安装python2-pip)
ansible
192.168.
43.11 -
m pip -
a
"name=Jinja2"
11:yum模块:
基于yum管理程序包
ansible
all -
m yum -
a
"name=httpd state=latest" 安装httpd程序包,latest表示安装最新的包
ansible
all -
m yum -
a
"name=httpd state=absent" 卸载httpd程序包
12:service模块
管理被监控主机的服务
ansible
all -
m service -
a
"name=httpd state=stopped"
ansible
all -
m service -
a
"name=httpd enabled=1 runlevel=3"
13:user模块
管理用户账号,创建用户
ansible
all -
m user -
a
"name=user2 system=yes uid=306"
还可以指定这么多参数:name=
system= yes|
no uid=
shell= group= groups= comment= home=
13:group模块
创建用户组,且指定gid
ansible
192.168.
23.10 -
m group -
a
"name=apache gid=48"
14: setup模块:
获取被管控主机的系统指标,拿到这些指标后,ansible就可以直接调用这些系统指标了,就像采集系统数据一样的
ansible
192.168.
23.10 -
m setup
15: script模块:
将ansible主机的脚本传递到被管控的主机上执行
ansible
192.168.
43.11 -
m script -
a
"/root/useradd.sh" 将本地的/root/useradd.
sh脚本在
192.168.
43.11中执行
16: template模块:
基于模板的方式生成一个文件复制到被管理的主机,这样就可以在模板语言中判断,不同的系统复制不同的配置文件,这就是template模块区别与
copy模块的地方
17:unarchive模块
将本地的归档文件拷贝到被管控的主机上,解压归档文件
ansible
all -
m unarchive -
a
"src=/files/wordpress.tar dest=/data/dynamic/"
18:mount模块
挂载和卸载模块,path指定本地挂载点,src指定需要挂载的设备
ansible
192.168.
23.12 -
m mount -
a
"path=/var/www/html src=192.168.23.25:/data/static fstype=nfs state=mounted"
小结:这里列举了
18个常用的模块,当然,远远不止这
18个模块,可以通过ansible-doc -
l 查看其他模块,也可以使用ansible-doc -s moduels_name 查看模块的使用方式,还有官方文档
(四)YAML文件格式介绍
1:YAML文件的格式介绍
YAML文件的格式与其他的高级语言中的字典嵌套类似,就是一层一层的,如:
- hosts: webservers
remote_user: root
tasks:
- name: install httpd
yum: name=httpd
state=present
- name: distribute configuration file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
- name: start httpd service
service: name=httpd
state=started
- name:
port
shell: netstat -lntup | grep httpd
上面这个就是一个YAML的文件格式,横杠就表示列表,冒号表示字典。任务执行的顺序一般都是列表写明
(五)ansible-playbook详解
示例:http://docs.ansible.com/ansible/latest/playbooks.html
1:Playbook的实质就是运行YAML配置文件:将多个相关的任务,通过读取YAML格式的配置文件一次性完成
2:playbook运行的核心元素有:
Hosts:指明运行在哪个主机上
Remote_user:以哪个用户的身份运行任务
Tasks:任务
Variables:变量
Templates:包含了模板语法的文本文件
Handlers:由特定条件出发的任务
Roles:
3:playbook的元素
Hosts:运行指定任务的目标主机,这些主机必须是定义在hosts文件中的主机
remoute_user:在远程主机上执行任务的用户
sudo_user:sudo到哪个用户的身份运行
tasks:任务列表,调用模块和指明参数
格式:
action动作形式:module
(新版本支持)
module模块形式:arguments (通用格式)
注意:shell和command模块后面加的是命令,而非key=value类的参数列表
(1)测试(只检测可能会发生的改变,但不真正执行操作)
ansible-playbook
ansible-playbook
列出运行任务的被管控的主机
ansible-playbook
测试
(2)运行
ansible-playbook
YAML示例文件(最好是确保webservers的主机的系统版本一样,因为配置文件的格式不一样会导致服务无法启动)
- hosts: webservers
remote_user: root
tasks:
- name: install httpd
yum: name=httpd
state=present
- name: distribute configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
- name: start httpd service
service: name=httpd
state=started
- name:
port
shell: netstat -lntup|grep httpd
handlers 详解
任务在特定条件下被触发,接收到其他任务的通知时被触发,某任务的状态在运行后为changed时,可通过notify通知给相应的handlers
- hosts: webservers
remote_user: root
tasks:
- name: install httpd
yum: name=httpd
state=present
- name: distribute configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
notify: restart httpd
- name: start httpd service
service: name=httpd
state=started
- name:
port
shell: netstat -lntup | grep httpd
handlers:
- name: restart httpd
service: name=httpd
state=restarted
tags详解
(用来标记指定执行的任务,在执行playbook的时候,如果指定tags所标记的任务,那么其他定义的任务将不会再执行)
- hosts: webservers
remote_user: root
tasks:
- name: install httpd
yum: name=httpd
state=present
- name: distribute configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
tags: distributeConfig
notify: restart httpd
- name: start httpd service
service: name=httpd
state=started
- name:
port
shell: netstat -lntup|grep httpd
handlers:
- name: restart httpd
service: name=httpd
state=restarted
例如:ansible-playbook -t distributeConfig http.yaml 这里指定运行的是
copy
任务 (在执行tags对应的任务时,如果被notify检查到了发生改变,那么也会调用handlers中的任务进行执行的)
(1)facts: 可以直接调用,有setup模块提供的
(2)ansible-playbook命令行中自定义的变量
-
e VARS : 指定需要传递给playbook的变量的名称
(3)通过roles角色传递变量
(4)Host inventory (/etc/ansible/hosts文件):向不同的主机传递不同的变量 , 这样就不需要在ansible-playbook命令行中给变量赋值了
(5)在playbook中定义变量
vars:
-
username: testuser1
-
groupname: testgroup1
- hosts:
all
remote_user: root
vars:
- username: home
- groupname: uplooking
tasks:
- name: create
group
group: name={{ groupname }}
state=present
- name: create
user
user: name={{ username }}
state=present
- hosts: webservers
remote_user: root
tasks:
- name: install {{ service }}
yum: name={{ service }}
state=present
ansible-playbook -e service=memcached second.yaml
[webservers]
192.168
.23
.20
host_name=www1
192.168
.23
.21
host_name=www2
[webservers:vars]
service=httpd
- hosts:
webservers
remote_user:
root
tasks:
- name:
set
hostname
{{
host_name
}}
hostname:
name={{
host_name
}}
- name:
install
{{
service
}}
yum:
name={{
service
}}
state=present
(六)ansible 模板template使用
1:首先通过ansible在被管控的主机上安装Nginx
2:再在ansible的主机上安装Nginx,拿到配置文件。且配置文件是centos
7安装Nginx的配置文件,在配置文件中有一个参数叫worker_processes,是设置Nginx的进程的数量的参数,使得模板复制过去之后,就会使得系统的CPU的数量为多少,Nginx的worker_processes进程数就是多少。
Nginx的配置文件中,worker_processes的数量是这样定义的,在模板中引用ansible_processor_vcpus变量名,这个变量名是ansible通过setup模块自带的参数,因此可以直接获取。
worker_processes {{ ansible_processor_vcpus }};
3:那么在ansible主机就可以编写YAML文件了
- hosts: webservers
remote_user: root
tasks:
- name: install nginx
yum: name=nginx
state=present
- name: install configure file
template: src=files/nginx.conf dest=/etc/nginx/nginx.conf
notify: restart nginx
tags: instconf
- name: start nginx service
service: name=nginx
state=started
handlers:
- name: restart nginx
service: name=nginx
state=restarted
4:执行ansible-playbook
ansible-playbook third.yaml
5:在被管控主机上检查:不同的CPU核心数的Nginx的配置文件中的worker_processes的数量不一样
- 也可以在template需要拷贝的文件中,使用运算符
worker_processes {{ ansible_processor_vcpus-
1 }};
- hosts: webservers
remote_user: root
tasks:
- name: install nginx
yum: name=nginx
state=present
- name: install configure file
template: src=files/nginx.conf dest=/etc/nginx/nginx.conf
notify: restart nginx
tags: distributeConf
- name: start nginx service
service: name=nginx
state=started
handlers:
- name: restart nginx
service: name=nginx
state=restarted
Playbook的条件判断机制
(在tasks中使用)
task
s:
- name: distribute config
file
to centos7
template: src=
files/nginx.
conf.centos7 dest=/etc/nginx/nginx.
conf
# 这里指定只有在主版本号为
7的时候,才会复制这个文件
when: ansible_distribution_major_version ==
"7"
- name: distribute config
file
to centos6
template: src=
files/nginx.
conf.centos6 dest=/etc/nginx/nginx.
conf
# 这里指定只有在主版本号为
6的时候,才会复制这个文件
when: ansible_distribution_major_version ==
"6"
-
- 要在task中使用with_items给定要迭代的元素列表
with_items的表示方式
1:使用
list
2:使用dictionary
这就是item实现的循环,让yum安装不同的软件的时候,可以使用列表的形式,然后使用一个yum任务就安装了所有在列表中需要安装的软件
tasks:
-
name: install some packages
yum: name={{item}} state=present
with_items:
-
nginx
-
memcached
-
php-fpm
-
name: add some groups
# 这是用列表存储变量
group: name={{ item }} state=present
with_items:
-
group11
-
group12
-
group13
-
name: add somen users
# 这是用字典存储变量
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
-
{ name: 'user11',group: 'group11' }
-
{ name: 'user12',group: 'group12' }
-
{ name: 'user13',group: 'group13' }
(七)roles角色 定义服务名
详解
前言:roles角色定义在ansible自动化过程中非常重要,这里必须牢记,通过定义不同的角色,那么在通过ansible-playbook执行一个YAML文件的时候,就可以通过指定不同的主机安装什么角色,这里的角色就是服务,比如haproxy。
[root@
7 roles]# tree -L
1
/etc/ansible
/roles/
/etc/ansible
/roles/
├── mysql
├── nginx
└── php-fpm
[root@
7 roles]# tree -L
2
/etc/ansible
/roles/
/etc/ansible
/roles/
├── mysql
├── nginx
│ ├──
default :设定默认变量时使用此目录中的main.yml文件
│ ├── files :存放由
copy或script模块等调用的文件
│ ├── handlers:至少包含一个名为main.yml的文件,其他的文件需要在此文件中通过
include进行包含
│ ├── meta:至少包含一个名为main.yml的文件,定义当前角色的特殊设定及其依赖关系,其他的文件需要在此文件中通过
include进行包含
│ ├── tasks:至少包含一个名为main.yml的文件,其他的文件需要在此文件中通过
include进行包含
│ ├── templates:template模块查找所需的模板文件目录
│ └── vars:至少包含一个名为main.yml的文件,其他的文件需要在此文件中通过
include进行包含
└── php-fpm
hosts:webservers
remote_user:root
rolse:
-
mysql
-
php-fpm
-
nginx
# 在
playbook调用角色方法2:可以传递变量给角色 ,可以在模板中使用这个变量
hosts:
webservers
remote_user:
root
rolse:
-{
role: nginx, username: nginx }
1: roles的目录结构所示
[root@
7 ansible]
/etc/ansible
[root@
7 ansible]
.
├── ansible.cfg
├── hosts
├── hosts.backup
└── roles
└── nginx
├──
default
├── files
├── handlers
│ └── main.yml - name: restart nginx
service: name=nginx
state=restarted
├── meta
├── tasks
│ └── main.yml - name: install nginx package
yum: name=nginx
state=present
- name: install config file
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart nginx
tags: instconf
- name: start nginx
service: name=nginx
state=started enabled=true
├── templates
│ └── nginx.conf.j2
└── vars
└── main.yml username: daemon
2:
[root@
7 ansible]
- hosts: webservers
remote_user: root
roles:
- nginx
3:ansible-playbook运行nginx.yml文件
ansible-playbook --check nginx.yml
ansible-playbook nginx.yml
- hosts:
webservers
remote_user:
root
roles:
-
{
role:
nginx,
username:
nginx,
when:
"ansible_distribution_major_version"
==
"7"
}
- hosts:
all
remote_user:
root
roles:
-
{
role:
nginx,
when:
ansible_distribution_major_version
==
'7'
}
-
{
role:
php-fpm,
when:
ansible_hostname
==
'6'
}