1、简介
ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。(百度百科)
自动化即是一种思想,也是一种悟,其方法论是相通的【规范--标准--自动化--智能化】在介绍到ansible不得不说这是一个新贵,不管是什么运维管理工具,其主要目的与要实现的功能是一至的,如果考虑到更多细节问题的话,主要还要看现有环境是否需要一款运维自动化管理工具,需要一款什么样的自动化工具才算得上运维人员的利器。其实大部分自动化工具软件都可以满足一般的企业做为生产环境使用。
ansible的特性:
- 基于Python语言实现,由Paramiko, PyYAML和Jinja2三个关键模块;
- 部署简单,agentless
- 默认使用SSH协议:
(1) 基于密钥认证;
(2) 在inventory文件中指定帐号和密码 - 主从模式:
master: ansible, ssh client
slave: ssh server - 支持自定义模块:支持各种编程语言
- 支持Playbook
- 基于“模块”完成各种“任务”
-
安装:依赖于epel源
配置文件:/etc/ansible/ansible.cfg
Inventory: /etc/ansible/hosts - ansible架构
如何查看模块帮助:
- ansible-doc -l
- ansible-doc -s MODULE_NAME
ansible执行状态不同颜色的含义:
- 绿 色代表执行成功,系统没有发生改变
- 黄 色代表系统状态发生改变
- 红 色代表执行失败,显示错误输出
- 粉 色代表警告信息
YAML
- 缩进: YAML使用一个固定的缩进风格表示层级结构,每个缩进由两个空格组成, 不能使用tabs
- 冒号: 以冒号结尾的除外,其他所有冒号后面所有必须有空格
- 短横线: 表示列表项,使用一个短横杠加一个空格。多个项使用同样的缩进级别作为同一列表
playbook基础组件
- Hosts:运行执行任务(task)的目标主机
- remote_user:在远程主机上执行任务的用户
- tasks:任务列表
- handlers:任务,与tasks不同的是只有在接受到通知时才会被触发
- templates:使用模板语言的文本文件,使用jinja2语法
- variables:变量,变量替换{{ variable_name }}
2、安装
ansible依赖于Python 2.6或更高的版本、paramiko、PyYAML及Jinja2。
2.1 编译安装
解决依赖关系
#yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto
#tar xf ansible-2.7.9.tar.gz
#cd ansible-2.7.9
#python setup.py build
#python setup.py install
#mkdir /etc/ansible
#cp -r examples/* /etc/ansible
2.2 rpm包安装
#yum install ansible
注意:不同版本的ansible的功能差异可能较大
2.3 配置文件
/etc/ansible/ansible.cfg
/etc/ansible/hosts
3、常用模块
command: 命令模块,默认模块,用于在远程主机执行命令
ansible]# ansible web01 -m command -a 'date'
ansible]# ansible all -a 'date' 【可以省略-m command】
-
cron:
ansible]# ansible web01 -m cron -a 'minute="*/10" job="/bin/echo hello" name="test cron job"' ansible]# ansible web01 -m cron -a 'minute="*/10" job="/bin/echo hello" name="test cron job" state=absent' ansible]# ansible web01 -a 'crontab -l'
-
user:
ansible]# ansible all -m user -a 'name="user11"' ansible]# ansible all -m user -a 'name="user11" state=absent'
-
group:
ansible]# ansible web01 -m group -a 'name=mysql gid=306 system=yes' ansible]# ansible web01 -m user -a 'name=mysql uid=306 system=yes group=mysql'
-
copy:
ansible]# ansible all -m copy -a 'src=/etc/fstab dest=/tmp/fstab.ansible owner=root mode=640' ansible]# ansible all -m copy -a 'content="Hello Ansible" dest=/tmp/test.ansible'
-
file: 设定文件属性
path=: 指定文件路径,可以使用name或dest来替代;
创建文件的符号链接:
src=: 指明源文件
path=: 指明符号链接文件路径ansible]# ansible all -m file -a 'owner=mysql group=mysql mode=600 path=/tmp/fstab.ansible' ansible]# ansible all -m file -a 'path=/tmp/fstab1.link src=/tmp/fstab.ansible state=link' ansible]# ansible all -m file -a 'owner=mysql group=mysql mode=600 path=/tmp/fstab.link src=/tmp/fstab.ansible state=link'
-
ping: 测试指定主机是否能连接
ansible]# ansible all -m ping -
service: 指定运行状态
enabled=: 是否开机自动启动,取值为true或者false;
name=: 指明服务名称
state=: 状态,取值有started, stopped, restarted;ansible]# ansible web -a 'service httpd start' 【启动httpd服务】 ansible]# ansible web -a 'service httpd status' 【查看服务状态】 ansible]# ansible web -a 'chkconfig --list httpd' 【查看服务是否能开机启动】 ansible]# ansible web -m service -a 'enabled=true name=httpd state=started'
-
shell: 在远程主机上运行命令
ansible]# ansible all -m user -a 'name=user1' ansible]# ansible all -m command -a 'echo 123456 | passwd --stdin user1' 【执行不成功】 ansible]# ansible all -m shell -a 'echo 123456 | passwd --stdin user1' 【有变量或管道时不要使用command模块了,建议使用shell模块】
-
script: 将本地脚本复制到远程主机并运行之;
ansible]# ansible all -m yum -a "name=zsh" ansible]# ansible all -m yum -a "name=zsh state=absent"
- setup: 收集远程主机的facts
每个被管理节点在接收并运行管理命令之前,会将自己主机相关信息,如操作系统版本、IP地址等报告给远程的ansible主机;
ansible]# ansible all -m setup
4、playbook
playbook的组成结构:
Inventory 【应用哪些主机】
Modules 【调用哪些模块】
Ad hoc Commands 【在这个主机上运行哪些命令】
Playbooks
Tasks: 任务,即调用模块完成的某操作
Variables: 变量
Templates: 模板
Handlers: 处理器,由某事件触发执行的操作
Roles: 角色
简单示例1:
- hosts: websrvs
remote_user: root
tasks:
- name: create nginx group
group: name=nginx system=yes gid=208
- name: create nginx user
user: name=nginx uid=208 group=nginx system=yes
- hosts: dbsrvs
remote_user: root
tasks:
- name: copy file to dbsrvs
copy: src=/etc/inittab dest=/tmp/inittab.ans
简单示例2:
- hosts: websrvs
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd state=latest
- name: install configuration file for httpd
copy: src=/root/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
- name: start httpd service
service: enabled=true name=httpd state=started
简单示例3:
- hosts: all
remote_user: root
vars:
- username: user10
tasks:
- name: create {{ username }} user
user: name={{ username }}
when: ansible_fqdn == "node2.com"
5、roles
(1) 目录名同角色名
(2) 目录结构有固定格式
files: 静态文件
templates: Jinjia2模板文件
tasks: 至少有main.yml文件,定义各tasks
handlers: 至少有一个main.yml文件,定义各handlers
vars: 至少有一个main.yml文件,定义变量
mate: 定义依赖关系等信息
(3)【调用时在roles目录之外,通常使用site.yml定义playbook】
site.yml中定义playbook,额外也可以有其它的yml文件
[root@node1 ~]# mkdir -pv ansible_playbooks/roles/{websrvs,dbsrvs}/{tasks,files,templates,meta,handlers,vars} 【创建roles目录】
[root@node1 ~]# tree ansible_playbooks/
ansible_playbooks/
└── roles
├── dbsrvs
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ ├── templates
│ └── vars
└── websrvs
├── files
├── handlers
├── meta
├── tasks
├── templates
└── vars
[root@node1 websrvs]# cp /root/conf/httpd.conf files/
[root@node1 websrvs]# vim tasks/main.yml
- name: install httpd package
yum: name=httpd
- name: install configuration file
copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf
tags:
- conf
notify:
- restart httpd
- name: start httpd
service: name=httpd state=started
[root@node1 websrvs]# vim handlers/main.yml
- name: restart httpd
service: name=httpd state=restarted
root@node1 websrvs]# vim vars/main.yml
{http_port: 80, maxClients: 100} 【必须是字典格式】
- http_port: 80
- maxClients: 200
[root@node1 ansible_playbooks]# vim site.yml
- hosts: web
remote_user: root
roles:
- websrvs
[root@node1 ansible_playbooks]# ansible-playbook site.yml
[root@node1 ansible_playbooks]# vim site.yml 【代码多次调用】
- hosts: 192.168.200.202
remote_user: root
roles:
- websrvs
- hosts: 192.168.200.203
remote_user: root
roles:
- dbsrvs
- hosts: 192.168.200.200
remote_user: root
roles:
- websrvs
- dbsrvs
[root@node1 dbsrvs]# cp /etc/my.cnf files/
[root@node1 dbsrvs]# vim tasks/main.yml
- name: install mysql-server package
yum: name=mysql-server state=latest
- name: install configuration file
copy: src=my.cnf dest=/etc/my.cnf
tags:
- myconf
notify:
- restart mysqld
- name: start mysqld service
service: name=mysqld enabled=true state=started
[root@node1 dbsrvs]# vim handlers/main.yml
- name: restart mysqld
service: name=mysqld state=restarted
[root@node1 ansible_playbooks]# ansible-playbook site.yml
6、总结
运维自动化的工作包括:运维工作:系统安装(物理机、虚拟机)--> 程序包安装、配置、服务启动 --> 批量操作 --> 程序发布 --> 监控
运维自动化也是一个迭代的过程,ansible使用技巧需要与各公司的流程相结合才能更完美的落地,对于前人们的推荐的说法是:几十台的设备用ansible管理,几百台的设备用saltstack,上千台则是puppet,其它相关话题就不在此展开了。最后说明一下像有的环境不能提供agent部署,这时就可利用ansible agentless这一点来实现自动化。ansible是一个轻量级的自动化工具,目前支持程序安装配置、批量操作、程序发布、监控都有与ansible结合的案例。
常用命令总结:
创建目录
# ansible -i /u01/ops/ansible/hosts web01 -m file -a "path=/tmp/test state=directory"
创建文件
# ansible -i /u01/ops/ansible/hosts web -m file -a "path=/tmp/test.txt state=touch"
删除文件
# ansible -i /u01/ops/ansible/hosts web -m file -a "path=/tmp/test.txt state=absent"
创建链接
# ansible -i /u01/ops/ansible/hosts web01 -m file -a "src=/etc/fstab dest=/tmp/fstab state=link"
复制文件
# ansible -i /u01/ops/ansible/hosts web02 -u root -m copy -a "src=/u01/syswin.com.sh dest=/tmp mode=755 owner=root group=root backup=yes"
# ansible dbservers -m copy -a 'src=/etc/ansible/memcached-1.4.15.tar.gz dest=/tmp'
# ansible dbservers -a "ls /tmp"
查看远程文件
# ansible -i /u01/ops/ansible/hosts web01 -u root -m command -a 'ls /tmp' -k
# ansible -i /u01/ops/ansible/hosts web01 -a 'cat /tmp/tmp.txt'
web01 | success | rc=0 >>
abcd 1234
文件不存在--命令执行
# ansible -i /u01/ops/ansible/hosts web01 -a 'creates=/tmp/ccxx.txt ls /home'
远程服务器服务
# ansible -i /u01/ops/ansible/hosts web01 -m shell -a 'ps -ef |grep rpc'
raw
# ansible -i /u01/ops/ansible/hosts web01 -m service -a 'name=httpd state=stopped'
# ansible -i /u01/ops/ansible/hosts web01 -m service -a 'name=httpd state=stopped sleep=3 '
# ansible -i /u01/ops/ansible/hosts web01 -m service -a 'name=httpd state=started sleep=3 enabled=yes'
计划任务
每3分钟ls 一下/u01
# ansible -i /u01/ops/ansible/hosts web01 -m cron -a 'name="check home directory" minute=*/3 job="ls -lh /u01"'
软件安装
# ansible -i /u01/ops/ansible/hosts web01 -m yum -a 'name=httpd state=installed'
添加用户
# ansible -i /u01/ops/ansible/hosts web01 -m command -a 'useradd -s /sbin/nologin -M user1'
# ansible -i /u01/ops/ansible/hosts web01 -m command -a 'id user1'
# ansible -i /u01/ops/ansible/hosts web01 -m user -a 'createhome=yes home=/home/user2 password=123456 name=user2 state=present shell=/bin/bash'
删除用户
# ansible -i /u01/ops/ansible/hosts web01 -m user -a 'remove=yes state=absent name=user2'
rsync同步
# ansible -i /u01/ops/ansible/hosts web01 -m synchronize -a 'src=./ansible.cfg dest=/tmp/ mode=push delete=yes rsync_path=/usr/bin/rsync rsync_opts="-avz,--exclude=.git"'
常见问题解决方法:
1、ansible-playbook 命令执行过程出现 skipping: no hosts matched 说明没有此主机,需要检查hosts文件。
2、执行ansible命令时ERROR,注意引号位置别加错了
3、在2.11版本以后不再支持指定' name: "{{ item }}" '
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions is
deprecated. Instead of using a loop to supply multiple items and specifying `name: "{{ item
}}"`, please use `name: ['php-mysql', 'php', 'php-fpm']` and remove the loop. This feature will
be removed in version 2.11. Deprecation warnings can be disabled by setting
deprecation_warnings=False in ansible.cfg.