一. 架构: 组成
ansible core:
modules:
Core Module
Custom Module
Host Inventory: 主机清单
File
CMDB
Playbooks : 定义对每个主机的操作任务, 定义了host和role的对应关系
hosts:
roles: 任务
Connection plugin: 连接插件
二. 特性
模块化: 调用特定的模块, 完成特定的任务;
基于Python语言研发, 由paramiko,pyYAML和jinja2三个核心库实现;
部署简单: agentless, 无代理;
支持自定义模块, 使用任意编程语言;
强大的playbook机制;
幂等性: 多次执行同一命令, 结果相同;
三. 安装及程序环境
ansible: 主程序
ansible-playbook: 执行脚本文件程序
ansible-doc: 获取帮助文档
配置文件:
/etc/ansible/ansible.cfg
主机清单:
/etc/ansible/hosts
插件目录:
/usr/share/ansible_plugins/: 连接插件
ansible命令:
ansible命令是以ssh通信连接的, 前提要在主机之间建立ssh公钥认证;
ssh-keygen -t rsa -P '' #生成公钥; ssh-copy-id -i .ssh/id_rsa.pub root@NODE #将公钥发送给客户端;
为了手动完成管理功能
前提: 配置/etc/ansible/hosts
[GROUP_NAME] HOST_IP_1 HOST_IP_2 ...
基本语法:
ansible <host-pattern> [options]
host-pattern : 需要管理的主机
options:
-m MOD_NAME : 指明调用的模块;
-a MODULE_ARGS: 指明模块参数;
基本格式:
ansible GRP_NAME -m MOD_NAME -a MOD_ARGS "ARGS"
ansible 模块:
ansible-doc [options] [module…]
-l, –list: 获取模块列表
-s MOD_NAME: 获取模块的简单用法
四. 常用模块
1. ping : 尝试连接主机, 验证一个可用的python并且成功返回"pong";
ansible GRP_NAME -m ping
2. command : 在远程节点上执行命令;
示例:
ansible websrv -m command -a "ifconfig"
注意: command模块不能接受管道等符号, 若需要使用, 需要调用shell模块;
3. shell : 在节点上启动脚本执行命令, 支持shell的高级功能;
注意: command和shell模块的核心参数直接为命令本身, 而其它模块的参数通常为"key=value"格式;
示例:
ansible websrv -m command -a "useradd centos" ansible websrc -m shell -a "echo 'magedu' | passwd --stdin centos"
4. copy : 复制ansible上的文件到远程主机上;
参数:
content: 直接给定内容, 保存在远程主机上;
src= : 要复制到远程服务器的文件的本地路径, 可以是相对路径, 也可以是绝对路径. 所以, 在一般使用中, 会将需要的各种文件, 放置到同一的ansible的目录下进行存放, 方便以后的命令的整体移动使用;
dest= : 指明远程路径, 必须为目录;
mode : 指明目标文件的权限;
group : 指明目标文件的属组;
owner : 指明目标文件的属主;
示例:
ansible all -m copy -a "src=/etc/fstab dest=/tmp/fstab.ansible mode=600" ansible all -m copy -a "content='hello\nworld\n' dest=/tmp/fstab mode=640"
5. file : 设置文件的属性;
参数:
group : 设置文件的属组;
owner : 设置文件的属主;
path= : 指明要修改哪个文件的属性;
state : 定义目标文件属性; 如果是directory, 不存在, 将被创建; 如果是file, 不存在, 不会创建, 请使用copy或template模块; 如果是link, 将创建或更改符号链接; 硬链接使用hard; state默认为present;
示例:
ansible all -m file -a "path=/tmp/fstab.ans owner=centos" #修改文件属主 ansible all -m file -a "path=/tmp/fstab.ans state=absent" #删除文件, absent表示删除; ansible all -m file -a "path=/tmp/dir.ansible state=directory" #创建空目录; ansible all -m file -a "path=/tmp/test.ansible.link src=/tmp/test.ansible state=link" #创建符号链接文件, 其中path指明 #要创建的符号链接文件路径, src指明符号链接的源文件, state指明创建的为符号链接;
6.fetch : 从远程节点获取文件, 通常从远程某一台主机上获取文件, 同时从多台远程主机获取文件, 会发生紊乱;
7. cron : 管理cron.d和crontab任务条目;
参数:
name= : crontab条目的描述, 如果设置了env,则为环境变量的名称. 如果state=absent, 则为必须;
job : 要执行的命令, 或者如果设置了env, 则为环境变量的值; 如果state=present, 则为必须;
state : whether to ensure the job or environment variable is present or absent;
示例:
ansible all -m cron -a "minute='*/5' job='/usr/sbin/ntpdate 10.1.0.1 &> /dev/null name='sync time'" #每5分钟与服务器同步一次时间; 其中, name必须指定, 不能省略; ansible all -m cron -a "name='sync time' state=absent" #删除name指定的计划任务;
crontab -l : 查看本机的计划任务;
8. hostname :设定主机名称;
参数:
name= : 指明要设置的主机名称, 属于必须给的选项;
9. yum : 使用yum管理软件包;
参数:
state={present|installed|latest|absent|removed} :
安装 : present或installed或latest;
删除 : absent或removed;
disable_gpg_check={true|false} : 安装过程中禁止gpg密钥检查;
disablerepo= : 安装过程中临时禁用某个repo;
enablerepo= : 安装过程中, 临时启用某个repositories;
示例:
ansible all -m yum -a "name=httpd" #安装httpd; ansible all -m yum -a "name=httpd state=absent" #删除httpd;
10. service : 管理服务;
参数:
name= : 指明要管理的服务;
state={started|stopped|restarted|reloaded} : 指明服务的动作; 'started'/'stopped'是幂等动作,除非必要,否则不会运行命令; 'restarted'将始终退回服务; 'reloaded'将总是重新加载; *至少一个状态和启用.
enabled={true|false} : 是否开机自动启动;
arguments= : 传递其他参数;
示例:
chkconfig –list httpd
ansible all -m service -a "name=httpd state=started enable=true" # 启动httpd服务, 并且开机启动; systemctl is-enabled *.service #查看服务是否开机启动;
11. group : 添加或删除用户组;
参数:
gid= : 指明组的gid
name= : 指明创建的组名
state={present|absent} : 添加或删除组;
system=[yes] : 如果指明为yes则创建系统组;
12. user : 管理用户账户;
参数:
name= : 指明要创建的用户名;
groups= : 指明要添加到的组;
shell= : 指明默认shell;
uid= : 指明id号;
system= : 创建用户是, 如果为'yes', 则会创建系统用户;
createhome= : 如果指明为no, 则不创建家目录;
comment= : 指明用户的注释信息;
expires= : 指明用户的过期时间;
13. setup : 收集远程主机的系统景况;
当需要用到一些系统的信息的时候, 需要首先收集主机的信息, 将其报告为ansible, 然后才能使用;
示例:
ansible 10.1.52.2 -m setup #此处的IP地址必须是/etc/ansible/hosts中定义了的主机IP地址; 未定义无法获取;
部分获取的主机信息参数:
ansible_distribution : 系统的发行版本;
ansible_distribution_major_version : 系统的主版本号;
ansible_hostname : 主机名;
ansible_processor_core : 每颗CPU的核心数;
ansible_processor_count : 共有几颗CPU;
ansible_processor_vcpus: 虚拟CPU数量;
ansible_processor_threads_per_code : 每个CPU核心的线程数量;
YAML格式的存储文件 : python常用的模板语言;
yum info PyYAML
序列化格式
数据格式:
键值对 key:value
列表 : 有序数组
– item1
– item2
…
字典 : 关联数组
{name:jerry,age:21}
playbook :
语法结构:
tasks : 任务, 由模块定义的操作列表;
variables : 变量
templates : 模板, 即使用模板语法的文本文件;
handlers : 由特定条件触发的task;
roles : 角色;
五. playbook的基础组件
Hosts : 运行指定任务的目标主机;
remote_user : 在远程主机上以哪个用户的身份执行; 建议使用root用户; 非root账户, 要使用sudo_user
tasks : 任务列表;
模块, 模块参数
格式:
(1) action:module arguments
(2) module:arguments
1. tasks 基本语法格式 – 如何定义 tasks
示例一:
- name: deploy web server user: foouser sudo: true hosts: all tasks: - name: install apache apt: pkg=apache2-mpm-prefork state=latest (其中apt指明使用的模块)
示例二:
在hosts中的用户上创建组, 创建用户并指定组
首先创建的playbook脚本要以".yaml"结尾
- hosts: all remote_user: root tasks: - name: install a group group: name=mygrp system=true - name: install a user user: name=user1 group=mygrp system=true - hosts: remote_user: root tasks: - name: install httpd yum: name=httpd - name: start httpd.service service: name=httpd state=started
ansible-playbook命令 – 运行.yml或.yaml脚本
语法:
ansible-playbook [options] PLAYBOOK.yml
options:
-C, –check: 测试模式, 不做任何更改, 而是尝试运行, 进行检查;
–list-hosts: 输出匹配的主机列表, 不执行其他操作;
–list-tags : 列出所有可用的标签
–list-tasks: 列出所有将要执行的任务;
-t TAGS, –tags=TAGS : 只运行tags标识的任务
–skip-tags=SKIP-TAGS : 只运行tags没有标记的任务;
–syntax-check: 对剧本执行语法检查, 但是不执行;
示例三:
要求: 在远程主机上安装httpd服务, 并且能够监听8080端口.
方法:
(1) 安装httpd;
(2) 提供配置文件;
(3) 启动httpd服务;
playbook文件
- hosts: dbsrv remote_user: root tasks: - name: install httpd yum: name=httpd state=latest - name: install conf file copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf - name: start httpd.service service: name=httpd state=started
2. handlers :
playbook文件 :
- hosts: dbsrv remote_user: root tasks: - name: install httpd yum: name=httpd state=latest - name: install conf file copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf notify: restart httpd service - name: start httpd.service service: name=httpd state=started handlers: - name: restart httpd service service: name=httpd state=restarted
handlers: 由特定条件触发的Tasks;
在某个tasks中触发, 当notify存在位置的上一个动作如果发生改变, 就会触发handlers定义的动作; 使用notify来调用, 调用的为handlers中name定义的名字;
此方法在服务类程序中使用较多, 当可以reload生效时, 可以使用command和shell进行定义;
handlers:
– name: reload httpd
shell: systemctl reload httpd.service
3. tags : 给指定的任务定义一个调用标识;
ansible-playbook -t TAGS PLAYBOOK.yaml
ansible-playbook –skip-tags TAGS PLAYBOOK.yaml
在 tasks 或 handlers 中定义, 必须放置在 – name: 段当中, 对存在 tags 的程序段进行操作; 其他全部不进行操作;
4. variables :
类型 :
内建 : 可直接调用
(1) facts : 可以使用 setup模块获取的变量
用户自定义 :
(1) 通过命令行传递
-e VAR1=VALUE1 -e VAR2=VALUE2 …
(2) 在hosts Inventory中为每个主机定义专用变量值;
(a) 向不同的主机传递不同的变量;
IPhone/HOSTNAME variable_name=value
(b) 向组内的所有主机传递相同的变量;
[group_name:VARS]
variable_name=value
调用 :
{{ var_name }}
示例:
- hosts: dbsrv remote_user: root vars: - pkgname: httpd tasks: - name: install a packet yum: name={{ pkgname }} state=present
使用vars记性变量的定义, 格式如下
vars:
– VAR_NAME1: VALUE1
– VAR_NAME2: VALUE2
…
若没指定, 可以使用 -e 选项, 并且命令行中给定的 -e VAR_VALUE 的优先级更高;
ansible-playbook -e VAR_VALUE PLAYBOOK.yaml
组变量 :
可以在/etc/ansible/hosts中单独向主机传递变量
方式一:
[websrv] 10.1.52.2 pkgname=naginx 10.1.52.3 pkgname=httpd
方式二:
[websrv] 10.1.52.2 10.1.52.3 [websrv:vars] pkgname=memcached
Inventory还可以使用参数
用于定义ansible远程连接目标主机时使用的属性, 而非传递给playbook;
[websrv]
10.1.52.2 ansible_ssh_user=USER ansible_shh_pass=PASSWORD ansible_sudo_pass=SUDO_PASSWD
ansible_ssh_host
ansible_ssh_port
ansible_ssh_user
ansible_ssh_pass
ansible_sudo_pass
5. templates : 模板
文本文件, 内部嵌套有模板语言脚本(使用模板编程语言)
语法 :
字面量:
字符串 : 使用单引号或双引号;
数字 : 整数, 浮点数
列表 : [item1, item2,…]
元组 : (item1,item2,…)
字典 : {key1:value1,key2:valuse2,…}
布尔值 : true/false
算数运算 :
+, -, * , /, //, %, **
比较操作 :
逻辑运算 : and, or, not
执行模板文件中的脚本, 并生成结果数据流, 需要使用template模块;
template :
-a ""
src=
dest=
mode=
owner=
group=
注意 : 此模块不能在命令行中使用, 只能在playbook中使用, 别模板语言一般为了表示使用 .j2 结尾;
示例:
- hosts: all remote_user: root tasks: - name: install nginx.conf template: src=/root/nginx.conf.j2 dest=/tmp/nginx.conf
并且要在需要使用template解析的文件中, 添加引用的参数, 例如: nginx.conf中添加
worker_processes {{ ansible_processor_vcpus }}
可以调用setup模块中的变量名, 使用template将其解析为 value的值
完整安装nginx并提供配置文件, 示例:
- hosts: ngxsrvs remote_user: root tasks: - name: install nginx yum: name=nginx state=latest - name: install nginx.conf template: src=/root/nginx.conf.j2 dext=/tmp/nginx.conf tags: ngxconf notify: reload nginx service - name: start nginx service service: name=nginx state=started enabled=true handlers: - name: reload nginx service shell: "/usr/sbin/nginx -s reload"
6. 条件测试
when语句 : 在tasks中使用, jinja2的语法格式;
可以调用 setup 模块的变量, 判断后面的值是否符合条件;
示例 :
- hosts: all remote_user: root tasks: - name: install nginx yum: name=nginx state=latest - name: service nginx.service restart service: name=nginx state=started when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "6" - name: systemctl start nginx shell: systemctl start nginx.service when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7" - name: install nginx.conf template: src=/root/nginx.conf.j2 dest=/tmp/nginx.conf tags: ngxconf notify: reload nginx handlers: - name: relaod nginx shell: "/usr/sbin/nginx -s reload"
7. 循环 : 迭代, 需要重复执行的任务;
对迭代项的引用, 固定变量名 "item", 使用with_items属性给定要迭代的元素, 通过遍历元素, 完成所有执行;
元素 : 列表, 字典
示例一: 基于字符串列表给出元素
- hosts: websrv remote_user: root tasks: - name: install packages yum: name={{ item }} state=latest with_items: - httpd - php - mariadb-server - php-mysql - sariadb-devel - php-devel - php-gd - php-mbstring
示例二: 基于字典列表给出元素
- hosts: websrv remote_user: root tasks: - name: create groups group: name={{ item }} state=present with_items: - group1 - group2 - group3 - name: create users user: name={{ item.name }} group={{ item.group }} state=present with_items: - { name: user1, group: group1 } - { name: user2, group: group2 } - { name: user3, group: group3 }
示例三: 在CentOS6 和CentOS 7上分别安装lamp;
- hosts: websrv remote_user: root tasks: - name: install lamp on CentOS 7 when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7" yum: name={{ item }} state=latest with_items: - httpd - mariadb-server - php - php-mysql - php-gd - php-mbstring - name: install lamp on CentOS 6 when: ansible_distribution == "CnetOS" and ansible_distribution_major_version == "6" yum: name={{ item }} state=latest with_items: - httpd - mysql-server - php - php-mysql - php-gd - php-mbstring
8. 角色 : roles
以特定的层级目录结构进行组织的tasks, variables, handlers, templates, files等;
role_NAME/
files/ : 存放于copy或script等模块调用的文件;
tasks/ : 此目录中至少应该有一个名为main.yml的文件, 用于定义各tasks; 其他的文件需要由main.uml进行"包含(include)"调用;
handlers/ : 此目录中至少应该有一个名为main.yml的文件, 用于定义各handlers; 其他的文件需要由main.uml进行"包含(include)"调用;
vars/ : 此目录中至少应该有一个名为main.yml的文件, 用于定义各variables; 其他的文件需要由main.uml进行"包含(include)"调用;
templates/ : 存储由templates模块调用的模板文件;
meta/ : 此目录中至少应该有一个名为main.yml的文件, 定义当前角色特殊设定及其依赖关系; 其他的文件需要由main.uml进行"包含(include)"调用;
default/ : 此目录中至少应该有一个名为main.yml的文件, 用于定义默认变量;
路径按照结构, 进行自包含, 不需要指定路径, 程序会自动根据相对路径进行查找文件;
示例:
(1) 在/etc/ansible/roles目录下创建httpd, nginx, mariadb目录, 在目录下创建 files, tasks, handlers, vars, templates, meta, default目录
mkdir -pv /etc/ansible/roles/{httpd,nginx,mariadb}/{files,tasks,handlers,vars,templates,meta,default}
(2) 在tasks目录下创建任务文件
- name: copy nginx package copy: src=nginx.rpm dest=/tmp/nginx.rpm tags: cppkg - name: install nginx yum: name=nginx.rpm state=latest - name: install conf file templates: src={{ item.ngxconfj2 }} dest={{ item.ngxconf }} with_items: - { ngxconfj2: nginx.conf.j2, ngxconf: /etc/nginx/nginx.conf } - { ngxconfj2: default.conf.j2, ngxconf: /etc/nginx/conf.d/default.conf } tags: ngxconf notify: reload nginx service - name: start nginx service shell: /usr/bin/systemctl start nginx
(3) 在files文件下存放nginx.rpm文件
(4) 在templates目录下放置nginx.conf.j2和default.conf.j2文件
(5) 在vars目录下新建main.yml文件, 存放templates目录下放置配置文件中的变量和值
(6) 在/etc/ansible目录下新建nginx.yml的playbook文件
- hosts: websrv remote_user: root roles: - nginx
(7) 检查语法和试运行
ansible-playbook –syntax-check nginx.yml
ansible-playbook –check nginx.yml
ansible-playbook nginx.yml
原创文章,作者:black_fish,如若转载,请注明出处:http://www.178linux.com/57470