ansible是什么?
一种自动化运维工具,适用于中小型企业,管理机器数量在一定范围之内,当你使用过一段时间之后就会发现,其实运行起来的速度还是有限。可以实现在多台主机上同时操作,修改用户组,创建新用户,安装程序,差异配置等一系列操作。
Ansible默认通过SSH协议管理机器;安装ansible之后,不需要启动或运行一个后台进程,只需要一台电脑即可通过网络管理一组远程主机,在远程管理的主机上也不需要安装任何软件,因此Ansible的版本升级不会带来太多问题。python开发,基于远程ssh管理,性能可能不比有代理程序的好,但有代理程序的会涉及到每台主机都要安装代理程序较为麻烦。
如何安装?
①yum安装较为简便,但要配置epel源( yum install ansible -y )
②Github下载安装 https://github.com/ansible/ansible
$ git clone git://github.com/ansible/ansible.git --recursive
$ cd ./ansible
$ source ./hacking/env-setup
$ . ./hacking/env-setup.fish
$ source ./hacking/env-setup -q
$ sudo easy_install pip
$ sudo pip install paramiko PyYAML Jinja2 httplib2 six
$ git pull --rebase
$ git submodule update --init --recursive
$ echo "127.0.0.1" > ~/ansible_hosts
$ export ANSIBLE_HOSTS=~/ansible_hosts
$ ansible all -m ping -k
对管理主机的要求?
只要机器上安装了python2.6或2.7以上的版本都可以安装ansible(windows系统不可做控制主机)
到此ansible基本已经安装成功了
在ansible配置文件列表中,有以下几个列表需要特别注意:
1. /etc/ansible/ansible.cfg # 主配置文件,一般没有太多修改
2. /etc/ansible/hosts # 较重要,主机清单,所有被远程的主机都必须在这个文件中
3. /etc/ansible/roles/ # 角色存放的目录
ansible 各类程序:
1. /usr/bin/ansible # 主程序,临时命令执行工具
2. /usr/bin/ansible-doc # 查看配置文档,模块功能查看工具
3. /usr/bin/ansible-galaxy # 下载/上传优秀代码或roles角色模块的官网平台
4. /usr/bin/ansible-palybook # 定制自动化任务,编排剧本任务
5. /usr/bin/ansible-pull # 远程执行命令的工具
6. /usr/bin/ansible-vaule # 文件加密工具
7. /usr/bin/ansible-console # 交互式执行工具
配置文件解释:vim /etc/ansible/ansible.cfg
[defaults]
# some basic default values...
# inventory = /etc/ansible/hosts #主列表配置文件
# library = /usr/share/my_modules/ # 库文件存放目
# remote_tmp = ~/.ansible/tmp # 临时py命令文件存放在远程主机目录
#local_tmp = ~/.ansible/tmp # 本机的临时命令执行目录
#forks = 5 # 默认并发数
#sudo_user = root # 默认sudo用户
#ask_sudo_pass = True # 每次执行ansible命令时是否询问ssh密码
#ask_pass = True
#transport = smart
#remote_port = 22
#module_lang = C
#module_set_locale = False
#log_path = /var/log/ansible # 默认是不记录日志,取消日志,开启记录
#host_key_checking=False # 检查对应服务器的host_key建议取消注释,将其功能开启
了解以上内容之后,现在可以开始第一个ansible程序了
前提是在/etc/ansible/hosts 文件中记录要控制的主机ip地址,才能用ansible远程控制,而不在主机清单中的主机是无法用ansible远程控制的。
[root@localhost ~]# ansible 192.168.1.118 -m ping -k
注:1. IP地址在hosts文件中存在
2. -m ping 指使用ping模块(这里的ping不是icmp ping,而是ping模块,但功能相近,都是用来探测主机是否存活)
3. -k 表示连接时提示输入密码,若本机是root用户,则连接过去的也是以root用户登陆
每次连接主机是都要输入主机密码嫌麻烦?
基于公钥认证验证登陆
实现key认证的方法:
[root@localhost ~]# ssh-keygen # enter三连击
[root@localhost ~]#cd .ssh
[root@localhost ~]#ssh-copy-id 192.168.1.118 #给此IP送去密钥
[root@localhost ~]#ssh-copy-id 192.168.1.119 #其他IP使用相同方式传送key
[root@localhost ~]#ansible 192.168.1.118 -m ping #直接连接无需密码认证
-
ansible-doc 显示模块帮助(两种方式)
-a : 显示所有模块文档
-l ,--list:列出可用模块
-s,--snippet :显示指定模块的playbook片段
- [root@localhost ~]# ansible-doc ping #完整显示整个帮助
- [root@localhost ~]# ansible-doc -s ping #显示部分帮助
- ansible通过ssh实现配置管理,应用部署,任务执行等功能,因此需要先配置ansible端能基于密钥方式联系被管理的各节点
ansible <host-puttern> [ -m module_name ] [ -a args ]
<host-puttern>:主机清单
[ -m module_name ]:指定模块
[ -a args ]:模块对应参数
ansible选项解释
--version // 显示版本
-m module // 指定模板
-v // 详细过程 -vv -vvv 更详细
--list-hosts //显示主机列表
-K , --ask-pass // 提示连接密码默认key认证
-C,--check // 检查,并不执行
-T,--timeout=TIMEOUT // 执行命令的超时时间,默认10s
-u,--user=REMOTE_USER //远程执行的用户,被控主机上的用户
-b,--become //代替旧版sudo切换
ansible的主机清单,匹配主机的各种方式
- all ,表示所有主机 [root@localhost ~]# ansible all -m ping
- * ,星号通配符 [root@localhost ~]# ansible " * " -m ping
- 或关系 [root@localhost ~]# ansible " web:db " -m ping
- 逻辑与 [root@localhost ~]# ansible " web:&db " -m ping
- 逻辑非 [root@localhost ~]# ansible ' web :! db ' -m ping
- 综合逻辑 [root@localhost ~]# ansible " web:db:&app:!tfp " -m ping
- 正则表达式 [root@localhost ~]# ansible " ~ (web|db).*\.baidu\.com " -m ping
ansible命令执行过程
- 加载配置文件,默认/etc/ansible/ansible.cfg
- 加载自己对应的模块文件,如command
- 通过ansible将模块或命令在本地生成对应的临时py文件,并将该文件传输至远程服务器的对应用户家目录下.ansible/tmp目录下
- 给文件+x执行
- 执行并返回结果
- 删除临时的py文件,sleep 0 退出
执行状态
- 绿色:执行成功并且不需要做改变的操作
- 黄色:执行成功并且对目标主机做变更
- 红色:执行失败
ansible常用模块
1.command :在远程主机执行命令默认模块,可忽略直接 -m
实例:
[root@localhost ~]# ansible all -m command -a ' ls -l /etc'
注:此命令不支持变量引用,< > | ; & 等,但可以用shell模块使用
2. shell :和command类似
实例:
[root@localhost ~]# ansible all -m shell -a ' echo $HOSTNAME '
3. script :运行脚本的模块,在本机写好的脚本通过ansible传输到远程主机后执行
实例:
[root@localhost ~]# ansible all -m script -a f1.sh
注:只是在对方主机上运行了脚本,并没有保存在对方主机上
4.copy :从本地主机复制文件到远程主机上
实例:本地(src)到远程主机目录(dest)规定权限(mode)属主(owner)对方主机如存在此文件先备份(backup)
[root@localhost ~]# ansible all -m copy -a ' src=/root/f1.sh dest=/app/fi.sh mode=600 owner=root backup=yes'
5. fetch :从客户端取文件至本地服务器端,与copy方向相反,目录可先tar
实例:
[root@localhost ~]# ansible all -m fetch -a ' src=/tmp/f1.sh dest=/root/f1.sh '
6. file : 设置文件属性
实例:
[root@localhost ~]# ansible all -m file -a ' path=/app/f1.sh state=touch owner=test1 mode=755 ' 创建新文件
[root@localhost ~]# ansible all -m file -a 'src=/root/f1.sh path=/tmp/testfile-link state=link ' 创建软连接
state=absent 删除文件 state=directory 创建空文件夹
7. hostname :管理主机名
实例:
[root@localhost ~]# ansible all -m hostname -a "name=centos" 改主机名
8. yum :管理包
实例:
[root@localhost ~]# ansible all -m yum -a 'name=httpd state=latest '
state=latest 安装最新版包 state=absent 删除包 update_cache=yes清缓存
9. service :管理服务
实例:
[root@localhost ~]# ansible all -m service -a 'name=httpd state=started ' 启动服务
state=stopped 停止服务 state=reloaded 重载 state=restarted 重启
10. user :用户管理模块
实例:
[root@localhost ~]# ansible all -m user -a 'name=user1 comment="test user" uid=2000 home=/app/user1 group=root '
[root@localhost ~]# ansible all -m user -a 'name=user2 system=yes home=/app/sysuser1 '
state=absent 删除用户
11. group :用户组管理
实例:
[root@localhost ~]# ansible all -m group -a " name=testgroup system=yes" 创建系统组
[root@localhost ~]# ansible all -m group -a "name=testgroup state=absent" 删除组
12. cron :计划任务
实例:
创建任务,每五分钟执行一次job,任务名为systime
[root@localhost ~]# ansible all -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.16.0.1 &>/dev/null" name=systime'
[root@localhost ~]# ansible all -m cron -a 'name=systime state=absent' 删除任务
13. setup :搜集主机信息
[root@localhost ~]# ansible all -m setup --a 'filter=*hostname*' 搜集所有主机hostname信息
14. ansible-galaxy 模块
实现从galaxy-ansible role角色仓库中拉去相应功能的模块至本机,直接利用模块实现功能
- 连接 http://galaxy.ansible.com 下载相应的角色,官方网站也可以自行搜索,获得地址后直接下载
- 列出所有已安装的galaxy ansible-galaxy list
- 安装搜索到的galaxy ansible-galaxy install geerlingguy.docker
- 删除 ansible-galaxy remove geerlingguy.docker
15. ansible-pull 模块
Ansible远程执行命令的工具(使用较少,海量机器时使用,对运维的架构能力要求较高)
-
ansible-playbook(重点学习)
- playbook是由一个或多个play 组成的列表
- play相当与一个简单的shell脚本,主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task任务定义好的角色,而task无非就是调用ansible中一个或多个模块,所以说一个play是一个简单的shell脚本一点不过分,只不过在写法上略有不同,它的写法来自于一种叫YAML的标记语言
YAML语言介绍
- YAML是一个可读性高的用来表达资料序列的格式。YAML参考了其他的多中语言,包括:XML,C,python,perl以及电子邮件格式的RFC2822等
- YAML是一种标记语言
- 特性:
YAML的可读性好
YAML的脚本语言交互性好
YAML使用实现语言的数据类型
YAML有一个一致的信息模型
YAML易于实现
YAML可以基于流来处理
YAML表达能力强,扩展性好
YAML语法介绍:
- 在单一的单元中,可连续三个杠(---)开头,连续三点结尾(...)
- 此行开始写playbook的内容,一般建议写明该playbook的功能
- 使用#号注释代码
- 缩进必须是统一的,不能空格和tab混用
- 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的
- YAML文件内容和Linux系统大小判别方式保持一致,是区别大小写的key/value的值均需大小写敏感
- key/value的值可同行写也可换行写,同行用冒号隔开
- value值可是字符串,也可是另一个列表
- 一个完整的代码块功能需要最少的元素包括 name:tasks
- 一个name只能包括一个tasks
- YAML文件扩展名通常为yml或yaml
- Dictionary 字典通常由多个key与value构成
playbook核心组成元素
- hosts 执行的远程主机列表
- tasks 任务集
- varniables 内置变量或自定义变量在playbook中调用
- templates 模板,可替换模板文件中的变量并实现一些简单逻辑文件
- handlers 和notify结合使用,由特定条件触发的操作,满足条件才执行,否则不执行
- tags 标签,指定某条任务执行,用于选择执行playbook中的部分代码。在ansible-playbook命令中选择执行代码中打上tags的代码段来执行。
先来一个简单的剧本体验一下
- 创建一个新用户并且给与755权限,再创建一个属组使新用户属于这个组
[root@centos7 app]# vim user.yml
---
- hosts: all
remote_user: root
tasks:
- name: group_add
group: name=testgroup
- name: user_add
user: name=user1 group=testgroup comment="test user"
[root@centos7 app]# ansible-playbook -C user.yml #测试代码
[root@centos7 app]# ansible-playbook user.yml #运行代码
2.创建一个空文件
[root@centos7 app]# vim mk_dir.yml
---
- hosts: all
remote_user: root
tasks:
- name: mkdir
file: name=/app/testfile state=touch mode=600
[root@centos7 app]# ansible-playbook user.yml #运行代码
进阶一:利用handlers和notify ,使palybook可以重复使用
例如:拷贝一份配置文件到远程主机,当该文件在本地修改后继续利用此代码可再次运行
[root@centos7 app]# vim test.yml
---
- hosts: all
remote_user: root
tasks:
- name: copyfile
copy: src=/app/http.conf dest=/etc/httpd/conf/
notify: copytwo
- name: servicehttp
service: name=httpd state=started
handlers:
- name: copytwo #当配置文件再次修改后,虽然可以拷贝过去,但服务没有重新启动无法生效
service: name=httpd state=restarted
进阶二: playbook中 tags使用,打个标记单独运行,可多个同时运行
[root@centos7 app]# vim http.yml
---
- hosts: all
remote_user: root
tasks:
- name: copyconfig
copy: src= /app/httpd.conf dest= /etc/httpd/conf/
tags: conf
- name: starthttpd
service: name=httpd state=started
tags: conf
[root@centos7 app]# ansible-playbook --tags conf http.yml #单独运行打标记的命令块
进阶三:playbook中变量的使用
- 变量名:仅能由字母,数字,下划线组成,且只能以字母开头
- 变量的来源
- ansible setup facts 远程主机的所有变量都可直接调用
- 在/etc/ansible/hosts中定义;由普通变量(主机组中单独定义,优先级高于公共变量);公共变量(针对主机组中所有主机定义统一变量)
- 通过命令行指定变量,优先级最高
- 在playbook中定义变量;用 vars: 表示 - var1: value1 - var2: value2
- 在role中定义
实例:在playbook中定义变量,在引用
---
- hosts: all
remote_user: root
vars:
- username : user1
- usergroup : group1
tasks:
- name: crente group
group: name={{usergroup}} state=present
- name: crente user
user: name={{username}} group={{usergroup}} home=/app/{{username}}dir
进阶四:playbook中templates模板的使用
- 是个文本文件,嵌套脚本
- templates功能:根据模块文件加上变量动态生成不同的配置文件
- 用到jinja2 语言,可以使用字符串,数字,列表,元组,字典,布尔值,算术运算,数值比较,逻辑运算,流表达式
注:
- templates文件必须存放在templates目录下,且命名为.j2结尾的文件
- yaml或yml文件必须和templates文件同级存放
实例:修改nginx的配置文件,在配置文件中加入cpu核数的变量,当检测到远程主机的cpu核数不同时,生成不同的配置文件到相应的主机上执行配置
找到代表cpu核数的变量
[root@centos7 ~]# ansible all -m setup -a 'filter=*vcpu*'
172.29.239.117 | SUCCESS => {
"ansible_facts": {
"ansible_processor_vcpus": 4, 找到变量ansible_processor_vcpus
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
172.29.239.118 | SUCCESS => {
"ansible_facts": {
"ansible_processor_vcpus": 1,
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}修改nginx.conf配置文件
将配置文件中的
worker_processes auto; 改为
worker_processes {{ansible_processor_vcpus}};
让产生的worker进程数与cpu核心数相同
[root@centos7 templates]# cp /etc/nginx/nginx.conf ./nginx.conf.j2
注意文件以.j2结尾,并且在/app/templates/目录下,接下来就可以写脚本了
[root@centos7 ~]# vim /app/nginxtest.yml---
- hosts: all
remote_user: roottasks:
- name: install_service
yum: name=nginx
- name: template
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf backup=yes
notify: restart_nginx
tags: instconf
- name: start_nginx
service: name=nginx state=started
handlers:
- name: restart_nginx
service: name=nginx state=restarted
[root@centos7 app]# ansible-playbook -C nginxtest.yml 测试成功后, 取消-C运行
进阶五:when条件判断在playbook中的应用
- 条件测试:如果需要根据变量,facts或此前任务的执行结果来做为某个tasks执行与否的前提时要用到条件测试,通过when语句实现,在tasks中来使用,jinja2的语法格式
- 在tasks之后添加when语句
- 示例:可以根据被控主机的版本号不同,来拷贝不同的配置文件
核心代码段
tasks:
- name: templeante6
templates: src=httpd-redhat.conf.j2 dest=/etc/httpd/conf/httpd.conf
when: ansible_os_family=="RedHat"
当检测到远程主机的系统时redhat时,执行templates操作,否则不执行
进阶六:迭代with_items
- 迭代:当有需要重复执行某任务时,可以使用迭代机制
- 对迭代项的引用,固定变量名为“item”
- 要在tasks中使用with_items给定要迭代的元素列表
- 列表格式为 字符串或字典
实例:
- name: adduser
user: name={{item}} state=preset
with_items:
- user1
- user2
- user3 # 依次向上引用,依次创建3个用户
进阶七:roles 角色
- 自ansible 1.2版以来,引入的新功能,用于层次性,结构化的组织playbook。简单来讲roles就是通过分别将变量,文件,任务,模板及处理器放置于单独的目录中,并可以便捷的映入它们的一种机制。角色一般用于基于主机构建服务器的场景,但也可以用于构建守护进程等场景中。
- 复杂场景建议使用roles,代码复用度高
- 每个角色以特定的层级结构进行组织
!! 无实例,自行探索 !!
注:角色功能稍微强大,层级结构严格,但运用起来确实方便,可以一键安装一个服务,在之前提到的galaxy-ansible网站中有很多现成的角色,可以拉去下来自己折腾一下;