Ansible 学习笔记

简介

  • 基于Python开发的自动化运维工具
  • 集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点
  • 基于模块工作,本身没有批量部署能力,批量部署由运行的模块实现
  • 提供自动化运维框架

作用

  • 批量系统配置
  • 批量程序部署
  • 批量运行命令

框架组成

  • Connection Plugins:负责和被监控端实现通信
  • Host Inventory:定义监控主机的配置文件
  • 模块
    • 核心模块
    • command模块
    • 自定义模块
  • 插件:完成记录日志邮件等功能
  • Playbook:剧本,非必需,可让节点一次性运行多个任务

架构图

Ansible架构图

架构字段解释

  • Ansible:核心程序
  • Host Inventory:主机清单(可定义主机组和主机)
  • 模块:实际执行任务的组件
  • Playbook:Yaml定义的剧本文件(类似shell脚本)
  • Connect Plugin:连接插件

工作原理

  1. 控制端通过inventory定义主机组
  2. 通过编写playbook或AD-HOC命令
  3. 使用SSH将模块推送到被控端
  4. 被控端执行任务(要求被控端有Python2环境)
  5. 任务完成后返回结果

命令执行过程

  1. 加载配置文件(/etc/ansible/ansible.cfg)
  2. 查找主机配置文件
  3. 加载对应模块文件
  4. 生成临时Python脚本并传输到远程主机
  5. 存储在远程主机的~/.ansible/tmp/目录
  6. 添加执行权限
  7. 执行并返回结果
  8. 删除临时文件

执行流程理解图

执行流程

特性

  • No Agents:无需在被控端安装客户端
  • No Server:无服务端架构
  • Modules in Any Languages:支持任意语言开发模块
  • YAML:使用YAML语言编写playbook
  • SSH by Default:默认基于SSH工作
  • Multi-tier Solution:支持多级指挥

配置文件

配置文件优先级(从高到低):

  1. 项目目录下的ansible.cfg
  2. 用户家目录下的.ansible.cfg
  3. 默认的/etc/ansible/ansible.cfg

主要配置项

1
2
3
4
5
6
7
8
9
10
11
#inventory = /etc/ansible/hosts      # 主机列表
#library = /usr/share/my_modules/ # 模块库目录
#remote_tmp = ~/.ansible/tmp # 远程临时目录
#local_tmp = ~/.ansible/tmp # 本地临时目录
#forks = 5 # 并发数
#sudo_user = root # 默认sudo用户
#ask_sudo_pass = True # 是否询问sudo密码
#ask_pass = True # 是否询问SSH密码
#remote_port = 22 # 远程端口
host_key_checking = False # 跳过主机指纹检查
log_path = /var/log/ansible.log # 日志路径

优点

  • 轻量级,客户端无需安装agent
  • 批量任务可写成脚本且无需分发
  • 基于Python,维护简单
  • 支持sudo

环境搭建

主机规划

主机 IP 角色
h1 192.168.50.60 master
h2 192.168.50.61 host1
h3 192.168.50.62 host2
h4 192.168.50.63 host3

SSH免密登录配置

1
2
ssh-keygen -t dsa -f ~/.ssh/id_dsa -P ""
ssh-copy-id -i ~/.ssh/id_dsa.pub root@192.168.50.61

安装

1
yum install -y ansible

主机清单配置

1
2
3
4
5
6
7
[hosts]
192.168.50.61
192.168.50.62
192.168.50.63

[local]
127.0.0.1

测试

1
2
ansible webservers -m command -a 'uptime'
ansible all -m ping

常用模块

setup模块

查看远程主机基本信息

1
ansible webservers -m setup

fetch模块

从主机获取文件

1
ansible 192.168.50.61 -m fetch -a 'src=/root/t2 dest=/root'

file模块

设置文件属性

选项:

  • force: 强制创建软链接(yes|no)
  • group: 文件属组
  • mode: 文件权限
  • owner: 文件属主
  • path: 文件路径(必选)
  • recurse: 递归设置属性(仅目录)
  • src: 源文件路径(仅state=link时)
  • dest: 链接目标路径(仅state=link时)
  • state:
    • directory: 创建目录
    • file: 不创建文件
    • link: 创建软链接
    • hard: 创建硬链接
    • touch: 创建空文件或更新修改时间
    • absent: 删除文件/目录

示例:

1
2
# 创建符号链接
ansible hosts -m file -a "src=/etc/resolv.conf dest=/root/resolv.conf state=link"

copy模块

复制文件到远程主机

选项:

  • backup: 覆盖前备份(yes|no)
  • content: 直接设置文件内容(替代src)
  • dest: 目标绝对路径(必选)
  • directory_mode: 递归设置目录权限
  • force: 强制覆盖(yes|no)
  • src: 本地源文件路径

示例:

1
ansible hosts -m copy -a "src=/etc/ansible/ansible.cfg dest=/tmp/ansible.cfg owner=root group=root mode=0755"

command模块

在远程主机执行命令

选项:

  • creates: 文件存在时不执行
  • free_form: Linux命令
  • chdir: 执行前切换目录
  • removes: 文件不存在时不执行
  • executable: 指定shell路径

示例:

1
2
ansible webservers -m command -a "ls -al /tmp"
ansible webservers -m command -a 'useradd abc'

shell模块

支持管道操作的命令执行

示例:

1
2
3
4
5
# 执行远程脚本
ansible hosts -m shell -a "/root/test.sh"

# 批量添加用户密码
ansible hosts -m shell -a 'useradd abc && echo 123 |passwd --stdin abc'

cron模块

管理计划任务

选项:

  • minute/hour/day/month/weekday: 时间设置
  • job: 任务命令
  • name: 任务名称
  • user: 执行用户
  • state: present(添加)|absent(删除)

示例:

1
2
3
4
5
# 创建任务
ansible all -m cron -a "minute='*/5' job='/usr/sbin/ntpdate 192.168.50.60 &>/dev/null' name='sync time'"

# 删除任务
ansible all -m cron -a "name='sync time' state=absent"

hostname模块

管理主机名

示例:

1
2
# 修改主机名
ansible 192.168.50.63 -m hostname -a "name=t4"

yum模块

软件包管理

示例:

1
2
3
4
5
# 安装tree
ansible all -m yum -a "name=tree"

# 卸载
ansible all -m yum -a 'name=tree state=absent'

service模块

服务管理

示例:

1
2
# 启动ntpdate服务
ansible all -m service -a "name=ntpdate state=started enabled=true"

group模块

用户组管理

示例:

1
2
# 添加系统组
ansible all -m group -a "name=gansible system=true"

user模块

用户管理

选项:

  • name: 用户名
  • state: present(新增)|absent(删除)
  • force: 删除时是否删除家目录
  • system: 是否系统用户
  • uid: 指定UID
  • shell: 指定shell
  • home: 指定家目录

示例:

1
2
# 添加系统用户
ansible all -m user -a "name=ccc system=true"

YAML语法

  • 数据序列化格式
  • 基本结构:
    1
    2
    3
    4
    key: value
    - item1
    - item2
    - item3
    例如: {name: jerry, age: 21}

Playbook

核心元素

  • Tasks: 任务列表
  • Variables: 变量
  • Templates: 模板文件
  • Handlers: 条件触发任务
  • Roles: 角色

基础组件

  • Hosts: 目标主机
  • remote_user: 执行用户
  • sudo_user: sudo用户
  • tasks: 任务列表

运行Playbook

1
2
3
4
5
6
7
8
# 语法检查
ansible-playbook --syntax-check playbook.yaml

# 测试运行
ansible-playbook -C playbook.yaml

# 实际运行
ansible-playbook playbook.yaml

示例

1. 添加用户和组

1
2
3
4
5
6
7
- hosts: all
remote_user: root
tasks:
- name: add a group
group: name=test system=test
- name: add a user
user: name=test group=test system=true

2. 配置HTTP服务

1
2
3
4
5
6
7
8
9
- hosts: hosts
remote_user: root
tasks:
- name: install http
yum: name=httpd state=latest
- name: install conf
copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf.bak
- name: start
service: name=httpd state=reloaded enabled=true

更多模块

  • synchronize: 使用rsync同步文件
  • raw: 直接执行命令(类似shell)

模块帮助

# 列出所有模块
ansible-doc -l

# 查看模块帮助
ansible-doc -s MOD_NAME