ansible作为轻量级的运维管理工具,目前已被广泛使用,其已被redhat收购,
未来极为可能装入base仓库。
ansible的安装
目前由于ansible位于epel仓库,我们需要创建epel源。方法如下: 1.wget https://mirrors.tuna.tsinghua.edu.cn/epel/7/x86_64/e/epel-release-7-9.noarch.rpm(此地址每隔一段时间会发生变化,如果以后发现该地址不正确,进入https://mirrors.tuna.tsinghua.edu.cn/epel/7/x86_64/e/去查找相应的资源)
2.rpm -ivh epel-release-7-9.noarch.rpm
3.yum clean all
4.yum -y install ansible安装成功
基本信息查看
1.yum info ansible 查看ansible基本介绍
2.rpm -qi ansible 查看程序包的信息
3.rpm -ql ansible|less 查看支持的模块
配置文件解读
/etc/ansible/ansible.cfg 主配置文件,配置ansible程序的工作特性
/etc/ansible/hosts 主机清单,各主机的分类的及IP地址等信息
/etc/ansible/roles 存放角色的目录
/usr/bin/ansible 主程序
/usr/bin/ansible-doc 查看配置文档
/usr/bin/ansible-galaxy
/usr/bin/ansible-playbook 辅助工具:剧本
/usr/bin/ansible-pull 取配置
支持的模块的介绍
command模块----在被管理远程主机上执行的命令
shell模块------在被管理远程主机上执行的命令,但是为了调用shell进程,然后把命令在子进程中运行;在执行的命令中可使用管道符;
copy模块-------用来复制文件到远程主机
cron模块-------用来在远程主机定义计划任务
ping模块-------用来探测主机存活性
filesystem模块-制作文件系统,格式化分区
known_hosts模块-管理ssh的hosts文件
mysql_db模块----在远程管理数据库
mysql_user模块--在远程管理数据库中的用户
setup模块-------收集远程指定主机的变量
......
如果没有需要的模块,可自行编写模块,使用任何语言;
所以,要想使用ansible管理远程主机,就必须了解其中的模块,但前提是要把被管理主机纳入到管理列表中来;
ansible在哪个目录查找模块,在配置文件中/etc/ansible/ansible.cfg中定义。
]# vim /etc/ansible/ansible.cfg
显示部分内容:
inventory = /etc/ansible/hosts 定义主机清单;
pattern = * 默认匹配所有被管理主机;
forks = 5 默认对远程主机执行命令时,5台主机一批,一批批的执行命令;
module_lang = C 模块默认编程语言;
ansible的使用
一、工作模式
运维工具大体有两种模式
1、agent模式:基于ssl实现。代理工作在被监控端。如:puppet
2、agentless模式:基于ssh实现工作在被监控端。监控端是ssh的客户端。
ansible是工作在agentless模式下具有幂等性。ansible在控制端只需要告诉监控端的期望状态就可以实现批量部署。
二、基于密钥认证
现在有三台机器作为被管理服务器,其中两台为centos6(IP分别为172.20.52.199、172.20.53.21),一台为centos7(172.20.52.185).管理机也为centos7.(IP:172.20.52.160)
实现步骤:
1.在管理主机上使用命令: ssh-keygen -t rsa -P '' 直接回车即可生成。
2.把当前公钥复制到远程主机root用户的家目录下
ssh-copy-id -i .ssh/id_rsa.pub root@172.20.52.199
ssh-copy-id -i .ssh/id_rsa.pub root@172.20.52.185
ssh-copy-id -i .ssh/id_rsa.pub root@172.20.53.21
3.完成后最好使用ssh root@主机IP进行验证一下。
三、命令使用
1、通用格式 ansible <host-pattern> [options]
host-pattern:指明对哪些主机执行命令
options:多为要执行的管理命令
-a MODULE_ARGS指明模块参数
例如:ansible all -m ping 对所有管理主机发起ping模块命令
ansible-doc -s ping 查看ping模块使用参数,但ping没有参数;
运行结果:
[root@centos7 yum.repos.d]# ansible all -m ping
172.20.52.199 | SUCCESS => {
"changed": false,
"ping": "pong"
}
172.20.52.185 | SUCCESS => {
"changed": false,
"ping": "pong"
}
172.20.53.21 | SUCCESS => {
"changed": false,
"ping": "pong"
}
2、command模块
(1)ansible websrvs -m command -a 'ls /var'
(2)注意:ansible websrvs -a 'ls /var' 省略模块时,默认为command模块;
部分结果如下:
172.20.52.185 | SUCCESS | rc=0 >>
account
adm
cache
crash
db
empty
games
gopher
kerberos
lib
local
lock
log
nis
opt
preserve
run
(3) ansible websrvs -a 'useradd user1' 在websrvs主机组中执行命令添加user1用户;
(4)执行的命令中有管道符'|'时,发生如下报错
[root@centos7 ~]# ansible websrvs -m command -a 'ifconfig |head -3'
172.20.52.199 | FAILED | rc=1 >>
-3: Unknown host
ifconfig: `--help' gives usage information.
172.20.52.185 | FAILED | rc=1 >>
-3: Unknown host
ifconfig: `--help' gives usage information.
3、shell模块
在远程主机的shell进程下运行命令,支持shell特性,如管道,重定向等;
上述的(4)问题,即可利用shell模块来解决。
ansible websrvs -m shell -a 'echo user1 | passwd --stdin user1' 使用shell模块,在执行命令中能使用管道符;
4、copy模块
实现复制文件至远程主机
2种用法:
(1)src= dest=
(2)content= dest=
owner,group,mode 可同时指明文件的属主、组及权限;
一般有=号的选项为必有选项;
src=为本地文件或目录;
dest=为远程被管理主机文件或目录;
content=表示把此处的内容直接当做源文件;
(3)ansible dbsrvs -m copy "src=/etc/passwd dest=/tmp"
(4)ansible all -m copy -a "content='hello there\n' mode=600 owner=user1 dest=/tmp/testfile1"
指明了权限、属主及换行符;默认复制后的权限为644;
5、cron模块
管理计划任务
minute= 几分钟,范围0-59;
day= 一个月的那一天,范围1-31,例如,1-5,*,*/2等
month= 哪个月,范围1-12;
hour= 哪个小时,范围0-23;
weekday= 星期几,范围0-6;
job= 表示state为present时,要执行的命令;
*name= 必须指定计划任务条目;
state=
present:创建cron计划任务;默认;
absent:删除cron计划任务;
如:ansible all -m cron -a "minute=*/5 job='/sbin/ntpdate 172.20.52.160 &> /dev/null'name=synctime"
没有指明的时间默认为*,没有指明state默认为创建present;
表示每5分钟执行一次时间同步任务,任务名为synctime;
可在被管理主机查看计划任务;
再如:ansible all -m cron -a "state=absent name=synctime" 删除计划任务
6、fetch模块
从远程主机拉取文件到本地
src= 一般是目录
dest=只能是文件
7、file模块
设定文件特性(修改属主、组等属性)
用法:
(1)创建链接文件
*path=指明操作的文件
src=要链接的源文件
state-link
(2)修改属性
path= owner= mode= group=
(3) 创建目录:
path= state=directory
举例:ansible dbsrvs -m file -a "path=/tmp/ansible_tmp state=directory"
ansible all -m file -a "src=/tmp/fstab path=/tmp/fstab.link state=link"
8、hostname模块
设定远程主机名
name=
要使用变量方式,写个循环实现批量更改远程主机主机名;
9、pip模块
管理Python模块;即使用pip安装依赖Python依赖到的模块;
10、yum模块
name=指定程序包名称,可以带版本号,默认最新版本
state=
present,latest(最新版)安装程序;
absent卸载程序;
disablerepo 安装时,指定临时禁用的仓库;
enablerepo 安装时,指定临时启用的仓库。
conf_file 表示yum运行时,指定(临时)使用的配置文件,而不是默认的配置文件。
例如:ansible all -m yum -a "name=httpd state=latest" 在被管理上安装httpd程序
ansible all -m yum -a "name=httpd state=absent"在被管理上卸载httpd程序
使用了安装命令后,如果之前该系统为安装过,运行结果显示为黄色字体。如果已经安装过了,则显示为绿色。都会显示成功安装。由于幂等性的原因(),一个程序在成功安装过后再次使用安装命令不会再次安装。
11、service模块
管理远程主机的服务
*name=指定管理的服务
state=
started 启动服务
stopped停止服务
restarted重启服务
enabled=开机自动启动;1或0;
runlevel=在指定级别下为开机自动启动;默认为2345,或345级别;
举例:ansible all -m shell -a "ss -ntl|grep :80" 查看被管理主机是否启动web服务
ansible all -m service -a "name=httpd state=started" 启动被管理主机web服务
12、uri模块
直接向被管理主机请求一个url;
url=
method指明请求的方法
body如果请求方法是post,指明该body;
user请求的url要求输入的用户名;
password请求的url要求输入的密码;
HEADER_发送请求的header;
13、user模块
管理用户、组账号
*name=指定要管理的用户
state=为present|absent
system=是否创建系统账号
uid=指定UID
shell=默认shell类型
group=基本组
groups=额外(附加)组
comment=注释信息
home=用户家目录
move_home=移动已经存在用户的家目录
password添加密码,应该指定的是openssl加密后的密码;
remove当state=absent时,删除用户时同时删除家目录
举例:
ansible all -m user -a "name=user2 system=yes state=presnet uid=306"
在被管理机上添加用户user2,为系统用户,UID为306;系统用户不应该有家目录,但此模块也创建了;
14、setup模块
获取facts,即收集远程主机的变量
ansible 192.168.255.3 -m setup 手动收集指定远程主机的变量;
15、group模块
添加或者删除组
name=组名,必有参数
state={present|absent}
system=
gid=
16、script模块
一般为本地脚本,会自动复制到远程主机并执行;
命令行使用:-a "/PATH/TO/SCRIPT_FILE"
注意:是本地文件路径
removes如果脚本依赖的文件不存在,脚本不会运行
17、templates模块
就是文本文件,内部嵌套有脚本(这个脚本使用模板编程语言编写)
基于模板方式生成一个文件符合到远程主机
src=指定本地jinja2的模板文件路径
dest=远程主机
owner=
group=
mode=
python只有在实现web框架时进行嵌入,将自己基于模板编程语言嵌入到其它文本中的机制,它的模板编程语言叫jinja2嵌入式的编程语言;类似于playbook,在python中叫resource资源和清单facts;在清单中定义资源时或定义使用的模板时会用到rubby的模板编程语言;
jinja2模板编程语言所实现的功能是,可以在文本文件中,使用一个所谓的嵌入的标记语法,引入一段模板编程语言所编写的脚本;而这种脚本无法就是支持比较简单的编程元素,如条件判断、(迭代)循环、变量;
举例:演示模板应用
使用ansible在三台主机上,安装nginx,提供配置文件,但其中的worker_processores的值要与主机的cpu核心数相同;此时,就可以把配置文件基于模板方式提供,而这个worker_processores的值,放的就是jinja2所支持的变量,直接使用变量的方式放在那个位置,而本机的template模板会自动套用这里面变量的值,给ansible facts所报告的结果,并把它生成在这个文件中,而后复制到目标主机上去。这就是模板的作用。
能够把里面嵌入的代码执行完以后,把执行后生成的结果放在代码所在处并且生成内容作为文本流输出给目标主机;
编辑epel源复制到远程主机:
]# vim files/epel.repo
[epel]
name=fedora epel
baseurl=http://mirrors.aliyun.com/epel/$releasever/$basearch
enabled=1
gpgcheck=1
]# ansible all -m copy -a "src=files/epel.repo dest=/etc/yum.repos.d" --check 如果有epel源,可省略此步骤;
]# ansible all -m yum -a "name=nginx state=present" --check 测试安装
]# ansible all -m yum -a "name=nginx state=present" 安装nginx
]# cp /etc/nginx/nginx.conf files/nginx.conf.j2
]# vim files/nginx.conf.j2
修改:
worker_processes ` ansible_processor_vcpus `;
注意:template模板不能在命令行中使用,只能编写yaml文件;
]# vim nginx.yaml
- hosts: websrvs
remote_user: root
tasks:
- name: install nginx
yum: name=nginx state=present
- name: install conf file
template: src=files/nginx.conf.j2 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
ansible-playbook --check nginx.yaml 测试执行
]# ansible-playbook nginx.yaml 执行
可观察两台主机上的worker进程个数均为该主机的cpu核心数;即开启了2个worker进程;
还可使用主机变量,让不同主机监听不同端口:
]# vim files/nginx.conf.j2
修改:
listen ` http_port `; 调用主机变量
]# vim /etc/ansible/hosts
[websrvs]
192.168.255.3 http_port=80 定义主机变量
192.168.255.4 http_port=8080
]# ansible-playbook --check nginx.yaml 测试执行
]# ansible-playbook nginx.yaml 执行
可在两台远程主机验证,一个监听在80端口,另一个监听在8080端口;
对变量还可使用算术运算:
例如:
]# vim files/nginx.conf.j2
修改:
worker_processes ` ansible_processor_vcpus-1 `; 变量参与了算术运算
]# ansible-playbook --check nginx.yaml 测试执行
]# ansible-playbook nginx.yaml 执行
可在两台远程主机验证,worker进程个数均减少了1个;
18、playbook
(1)核心元素
Hosts:
Tasks:任务
Variables:变量;可调用ansible的变量或自定义的变量
Templates:包含了模板语法的文本文件;提供配置文件的办法,可在文件中使用变量;该变量时与目标主机相关的值;
Handlers:任务处理器,由特定条件触发的任务;本质还是tasks;
Roles:就是由以上元素组成;把主机列表分出来,用到哪个主机时,就放在哪个主机上执行,这就是roles;
其实还有users,指明在目标主机上,使用哪个用户的身份运行命令;不指明则默认为root,但是通常用sudo的方式进行指定,因此,必要时,要指明远程主机运行此任务的用户身份;
playbook的主要作用:
就是能够把多个相关联的任务,通过读取YAML格式的配置文件一次编完;要把任务、变量、模板、处理器放在一个YAML格式文件中进行指定,然后任务就可一次批量执行;
其他组件
ansible facts可使用stup模块获取;收集远程主机变量;
ansible-playbook -e "var=value"自定义变量
host variable:host iventory主机变量
group variable(主机组上的变量)
[groupname:vars]
var=value
roles
变量调用方法:` variable `
(2)举例:playbook的基础组件hosts和tasks
vim first.yaml
- hosts: all
remote_user: root
tasks:
- name: create a user3
user: name=user3 system=true uid=307
- name: create a user4
user: name=user4 system=true uid=308
在远程三台主机,以root身份执行2个任务,添加两个用户指定用户名、uid且为系统用户。
ansible-playbook --check first.yaml测试执行
[root@centos7 ~]# vim first.yaml
[root@centos7 ~]# ansible-playbook --check first.yaml
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [172.20.53.21]
ok: [172.20.52.185]
TASK [create a user3] **********************************************************
changed: [172.20.53.21]
changed: [172.20.52.185]
TASK [create a user4] **********************************************************
changed: [172.20.53.21]
changed: [172.20.52.185]
PLAY RECAP *********************************************************************
172.20.52.185 : ok=3 changed=2 unreachable=0 failed=0
172.20.53.21 : ok=3 changed=2 unreachable=0 failed=0
PLAY RECAP 返回的报告
172.20.52.185 : ok=3 changed=2 unreachable=0 failed=0 表示3个任务ok,其中2个是修改以后
ok,unreachable表示联系不到执行不了, failed表示执行失败;
172.20.53.21 : ok=3 changed=2 unreachable=0 failed=0
ansible-playbook --list-hosts first.yaml 查看这个playbook运行在哪些主机上;
ansible-playbook first.yaml 真正执行
(3)playbook实际运用举例
mkdir working
cd working
mkdir files
cp /etc/httpd/conf/httpd.conf files/
vim files/httpd.conf
修改其中的Listen 8080
vim web.yaml
- hosts:websrvs
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd state=present
- name: install configure file
copy:src= files/httpd.conf dest= /etc/httpd/conf
- name: start httpd service
service: name=httpd state=started
- name: execute ss command
shell: ss-ntl|grep :8080
ansible all -m yum -a "name=httpd state=absent" 把所有主机的文本服务停掉;
ansible-playbook --check web.yaml 测试
ansible-playbook web.yaml 执行
ansible websrvs -m shell -a "ss -tnl|grep 8080" 查看远程主机是否监听了8080端口;注意:在ansible中执行ss -tnl | grep :8080,这种查询是不显示结果的,所以,一般不在ansible里执行有关查询显示的命令;
(4)演示handlers,触发执行
如果把监听端改为808,再执行,则不会生效,因为,服务已经启动了,除非重启服务,这时,就应该用到handlers处理器;
vim web-2.yaml
- hosts:websrvs
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd state=present
- name: install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
notify: restart httpd ##定义触发,调用处理器的名字
- name: started httpd service
service: name=httpd state=started
handlers: ## 触发后处理器执行的命令
- name: restart httpd ##必须与notify调用名保持一致;
service: name=httpd state=restarted
vim files/httpd.conf(管理机)
Listen 808
ansible-playbook --check web-2.yaml 只有触发时,才执行handlers里面定义的命令;
ansible-playbook web-2.yaml 直接运行
(5)演示tag,调取标签执行指定任务
根据上例,如果仅修改了配置文件,却还要从第一步,执行安装程序包,这样是没必要的,所以,可使用tag,给任务加标签,不指定标签时,执行所有任务,加标签时,只执行标签所在的任务;
vim web-3.yaml
- hosts:websrvs
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd state=present
tags: insthttpd
- name: install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
tags: instconf
notify: restart httpd
- name: started httpd service
service: name=httpd state=started
tags: starthttpd
handlers:
- name: restart httpd
service: name=httpd state=restarted
vim files/httpd.conf
Listen 80
ansible-playbook -t instconf --check web-3.yaml 指定执行标签上的任务.
ansible-playbook -t insthttpd --check web-3.yaml 则发现只运行了一个任务;
还可为让两个任务标签相同。添加后--- ansible-playbook -t insthttpd --check web-3.yaml 发现,会运行两个任务;这就叫标签;
ansible-playbook -t instconf,insthttpd --check web-3.yaml 调用多个标签;
(6)演示在ansible-playbook命令行调用变量
vim forth.yaml
- hosts:websrvs
remote_user:root
tasks:
- name: install ` pkname `必须使用双花括号,调用变量
yum: name=` pkname ` state=present
举例1:ansible-playbook -e pkname=memcached forth.yaml安装memcached,用变量传递。
举例2:
vim /etc/ansible/hosts
[websrvs]
172.20.52.185 hname=www1
172.20.53.21 hname=www2
vim hostname.yaml
- hosts:websrvs
remote_user:root
tasks:
- name: set hostname
hostname: name=` hname `
ansible-playbook --check hostname.yaml 测试执行;
举例3:向主机组中的主机传递相同的变量
[websrvs]
172.20.52.185 hname=baby1
172.20.53.21 hname=baby2
[websrvs:vars]
http_port=8080
[dbsrvs]
172.20.53.21
variables:变量
(1)facts:任何facts变量都由正在通信的目标主机发回的信息,ansible自动获取变量,可直接调用;在setup模块
中查看变量;
(2)ansible-playbook命令的命令行中的自定义变量;
-e VARS, --extra-vars=VARS
(3)通过roles传递变量;
(4)Host Inventory
(a)向不同的主机传递不同的变量;
IP/HOSTNAME varailble=value var2=value2
(b)向组中的主机传递相同的变量;
[groupname:vars]
variable=value
注意:invertory参数:
用于定义ansible远程路径目标主机时使用的参数,而非传递给playbook的变量;
ansible_ssh_host
ansible_ssh_port
ansible_ssh_user
ansible_ssh_pass
ansible_sudo_pass
...
通常ansible中的inventory还有专门参数,不叫变量,因为它不是传递给playbook使用的,而是通过ansible连接每个被管理主机时使用的;
例如:
连接远程主机时,如果不使用密钥方式,需要输入账号、密码;还可编辑hosts文件:
]# vim /etc/ansible/hosts
[dbsrvs]
192.168.255.4
192.168.255.60 ansible_ssh_user=root ansible_ssh_pass=root
可以在模板中调用变量,为不同的主机生成不同的配置,虽然看上去是同一个配置文件,不同主机拿到的配置文件可以不一样;
本文转自 ping9527 51CTO博客,原文链接:http://blog.51cto.com/babyhanggege/1908780,如需转载请自行联系原作者