ansible 的用法
ansible 常用模块
1 command 模块
默认模块,不指定 -m 参数时,使用的就是 command 模块;
但 "<", ">", "|", and "&" 操作都不可以,当然,也不支持管道;
缺点:不支持管道,没法批量执行命令;
示例:
ansible 192.168.2.20 -m command -a 'ifconfig' //联系某一台主机执行ifconfig命令
ansible all -m command -a 'ifconfig' //联系主机清单里所有的主机执行ifconfig命令
ansible all -a 'ifconfig' //command模块是默认的,所以可以省略
ansible websrvs -m command -a 'uptime' # 主机清单中 websrvs 组执行命令 uptime
2 shell 模块
在远程命令通过/bin/sh 来执行;所以,在终端输入的各种命令方式,都可以使用。
示例:
ansible websrvs -m shell -a 'echo $HOSTNAME' # 如果是 command 模块:这里的echo命令是在当前 shell中运行显示出来了,而不是在远程管理主机上
对 shell 模块的使用可以分成两块:
1) 如果待执行的语句少,可以直接写在一句话中:
示例:
ansible websrvs -m shell -a 'source ~/.bash_profile && df -h'
3 script 模块
可以将本地脚本复制到远程主机并运行之。
ansible websrvs -m script -a '/tmp/test.sh' # 本地的脚本在远程主机上运行,本地不需要给执行权限
4 user 模块
远程主机用户管理
-a 'name= uid= state={present|absent} system=' //name:指明创建的用户的名字
示例:
给websrvs中主机添加用户hacluster
# ansible websrvs -m user -a 'name=hacluster state=present'
给websrvs中的主机删除用户hacluster
# ansible websrvs -m user -a 'name=hacluster state=absent'
5 group 模块
-a 'name= gid= state= system='
示例:
ansible websrvs -m group -a 'name=mysql state=present system=yes' # 创建 mysql 系统组
6 cron 模块
-a 'name= minute= hour= day= month= weekday= job= user= state='
示例:
ansible all -m cron -a 'name="sync time from ntpserver" minute="*/10" job="/sbin/ntpdate 192.168.2.50 &> /dev/null"' //所有主机每10分钟同步一下时间
ansible websrvs -a 'crontab -l' // 查看周期性任务
ansible websrvs -m cron -a 'name="sync time" state=absent' // 删除时,只要指明name就可以
7 copy 模块
实现主控端向目标主机拷贝文件,类似 scp 功能
-a 'dest= src= mode= owner= group=' //src:定义本地源文件路径 dest:定义远程目标文件路径 content= : 取代src=,表示直接用此处指定的信息生成为目标文件内容
示例:
ansible websrvs -m copy -a 'src="/etc/fstab" dest="/tmp/" mode=644 owner=mysql group=mysql'
8 file 模块
设定文件属性
-a 'path= mode= owner= group= state={directory|link|present|absent} src=' //path:指定文件路径,可以使用name或dest来替换;src:指明源文件;path:指名符号链接文件路径
示例:
ansible all -m file -a 'path=/tmp/testdir state=directory' //远程主机上创建目录
ansible all -m file -a 'path=/tmp/fstab.symlink state=link src=/tmp/fstab.tmp force=yes'
//远程主机上创建符号链接文件;如果源文件不存在可以使用force=yes或true来强制创建,只是源文件不存在
9 ping 模块
示例:
使用 ping 检查 websrvs 组 或者 ansible 节点的连通性。
ansible websrvs -m ping
10 yum 模块
软件包管理
-a 'name= state={present|absent|latest}' //name:指明要安装的程序包,可以带上版本号
示例:
ansible websrvs -m yum -a 'name=nginx state=latest' //websrvs中的主机安装nginx
ansible websrvs -m yum -a 'name=nginx state=absent' //卸载nginx
11 service 模块
远程主机系统服务管理。
-a 'name= state={started|stopped|restarted} enabled=' //enabled:是否开机自启动,取值为true或false
示例:
ansible websrvs -m service -a 'name=nginx state=started enabled=yes'
12 setup 模块
收集远程主机的facts
每个被管理节点在接收并运行管理命令之前,会将自己主机的相关信息,如操作系统版本、IP 地址等报告给远程的 ansible 主机
示例:
ansible websrvs -m setup //获取远程主机的所支持的所有facts
13 stat 模块
获取远程文件信息
-a 'path='
示例:
ansible websrvs -m stat -a 'path=/etc/hosts'
14 get_url 模块
-a "url= dest= mode= force=yes"
// 如果 force=yes,当下载文件时,如果所下的内容和原目录下的文件内容不一样,则替换原文件,如果一样,就不下载了。
// 如果 force=no,则仅在目标不存在时才下载文件。 一般来说,只有小型本地文件才应该为“是”。 在 0.6 之前,该模块表现为默认为“是”。
示例:
下载 epel-release-latest-7.noarch.rpm 到主机清单中的/tmp/目录下:
ansible websrvs -m get_url -a "url=https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm dest=/tmp/ mode=440 force=yes"
15 sysctl 模块
远程主机 sysctl 配置。
示例:
开启路由转发功能:
ansible websrvs -m sysctl -a 'name=net.ipv4.ip_forward value=1 reload=yes'
playbook 应用
示例一:websrvs主机创建nginx用户和nginx组,dbsrvs主机复制文件
- hosts: websrvs
remote_user: root
tasks:
- name: create nginx group
group: name=nginx system=yes gid=208
- name: reate nginx user
user: name=nginx uid=208 group=208 system=yes
- hosts: dbsrvs
remote_user: root
tasks:
- name: copy file to dbsrvs
copy: src=/etc/inittab dest=/tmp/inittab.ans
# ansible-playbook nginx.yaml
示例二:安装 httpd 服务,并且将本地的配置文件复制到远程主机,然后运行 httpd 服务;当配置文件修改时使用 handlers
- hosts: websrvs
remote_user: root
tasks:
- name: install httpd service
yum: name=httpd state=latest
- name: install configuration file for httpd
copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify:
- restart httpd
- name: start httpd service
service: name=httpd state=started enabled=true
handlers:
- name: restart httpd
service: name=httpd state=restarted
# ansible-playboot httpd.yaml
修改配置文件后再次执行上面命令,会触发 handlers 里面的模块运行。
示例三:变量测试,以上面例子为例
- hosts: websrvs
remote_user: root
vars: // 添加两个变量
- package: httpd
- service: httpd
tasks:
- name: install httpd service
yum: name={{ package }} state=latest # 变量替换使用 {{}}
- name: install configuration file for httpd
copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify:
- restart httpd
- name: start httpd service
service: name={{ service }} state=started enabled=true
handlers:
- name: restart httpd
service: name={{ service }} state=restarted
有些变量我们可以不用定义,直接使用的,比如ansible facts中的变量:
# ansible node1 -m setup //找一个facts,比如ansible_all_ipv4_addresses
- hosts: websrvs
remote_user: root
tasks:
- name: copy file
copy: content={{ ansible_all_ipv4_addresses }} dest=/tmp/vars.ans //直接调用,无需定义
我们还可以使用Inventory中的主机变量:
在hosts文件中添加主机变量:
[websrvs]
192.168.2.20 testvar="2.20" //各添加了 testvar 变量
192.168.2.40 testvar="2.40"
下面我们来调用:
- hosts: websrvs
remote_user: root
tasks:
- name: copy file
copy: content={{ ansible_all_ipv4_addresses }},{{ testvar }} dest=/tmp/vars.ans // 调用testvar变量,虽然变量名都是同一个,但内容在各主机都不一样
示例四:不基于密钥认证的方式联系远程主机
我们如果不使用基于密钥的方式连接各主机,可以在hosts文件中定义账号密码的方式实现:
[websrvs]
192.168.2.20 ansible_ssh_user=root ansible_ssh_pass=ckh //账号和密码
示例五:条件测试 when
- hosts: all
remote_user: root
vars:
- username: user10
tasks:
- name: create {{ username }} user
user: name={{ username }}
when: ansible_fqdn == "node1.ckh.com" //当 facts 是 node1.ckh.com 时,才会添加用户
示例六:迭代
重复同类task时使用
调用:item
定义循环列表:with_items
with_items:
- apache
- php
- mysql-server
注意:with_items中的列表值也可以是字典,但引用时要使用item.KEY:
with_items:
- {name: apache, conf: conffiles/httpd.conf}
- {name: php, conf: conffiles/php.ini}
- {name: mysql-server,conf: conffiles/my.cnf}
示例七:Templates 应用
首先,我们将本地配置文件修改成一个模板:
比如我们修改 httpd.conf 配置文件中的这几项:
Listen {{ http_port }}
maxClients {{ maxClients }}
ServerName {{ ansible_fqdn }}
将上面修改的文件作为模板,就放在/root/templates/httpd.conf.j2
yaml文件中修改:
- hosts: websrvs
remote_user: root
vars:
- package: httpd
- service: httpd
tasks:
- name: install httpd service
yum: name={{ package }} state=latest
- name: install configuration file for httpd
template: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf // 指定模板的位置
notify:
- restart httpd
- name: start httpd service
service: name={{ service }} state=started enabled=true
handlers:
- name: restart httpd
service: name={{ service }} state=restarted
然后在/etc/ansible/hosts中给主机定义变量:
[websrvs]
192.168.2.11 http_port=80
192.168.2.12 http_port=8080
192.168.2.13 http_port=8090
还有一个变量 ServerName 是 facts 中的 ansible_fqdn,所以模板中直接调用就可以。
示例八:Tags 示例
在palybook可以为某个或某些任务定义一个标签,在执行此 playbook 时,通过为 ansible-playbook 命令使用 --tags 选项能实现仅运行指定的 tasks 而非所有的
- hosts: websrvs
remote_user: root
vars:
- package: httpd
- service: httpd
tasks:
- name: install httpd service
yum: name={{ package }} state=latest
- name: install configuration file for httpd
template: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
tags: // 增加 tags
- conf
notify:
- restart httpd
- name: start httpd service
service: name={{ service }} state=started enabled=true
handlers:
- name: restart httpd
service: name={{ service }} state=restarted
# ansible-playbook httpd.yaml --tags="conf" // 执行命令的时候加上 --tags
Tags 还有特殊 tags:always
示例九:roles不同角色执行不同任务
roles注意点:
(1) 目录名同角色名
(2) 目录结构有固定格式:
files:静态文件
templates:Jinjia2 模板文件
tasks:至少有 main.yml 文件,定义各 tasks
handlers:至少有一个 main.yml 文件,定义各 handlers
vars:至少有一个 mail.yml 文件,定义变量
meta:定义依赖关系等信息
(3)
site.yml 中定义 playbook,额外也可以有其他的 yml 文件
创建 roles 所需目录:
# mkdir ansible_playbooks
# mkdir ansible_playbooks/roles/{websrvs,dbsrvs}/{tasks,files,templates,meta,handlers,vars} -pv // 这里 定义两个 role
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: //这边定义了一个通知,调用处理器handlers
- restart httpd
- name: start httpd
service: name=httpd state=started
handlers/main.yml
- name: restart httpd
service: name=httpd state=restarted
vars/main.yml
httpd_port: 80
maxClient: 200
在 roles 目录之外创建一个 site.yml
site.yml
- hosts: 192.168.2.20
remote_user: root
roles:
- websrvs
- hosts: 192.168.2.40
remote_user: root
roles:
- dbsrvs
- hosts: 192.168.2.80
remote_user: root
roles:
- websrvs
- dbsrvs
# ansible-playbook site.yml
示例十:使用 Playbook 批量部署多台 LAMP 环境
1. 在 ansible 服务器上安装 lamp 环境
yum install httpd php php-mysql mariadb-server -y
修改 httpd 配置文件:/etc/httpd/conf/httpd.conf
Listen 8080
添加测试页:index.php
<?php
phpinfo();
?>
修改 mariadb 配置文件:/etc/my.cnf
datedir = /mydata/data
innodb_file_per_table = On
skip_name_resolve = On
执行 mysql 安全脚本:删除匿名用户,给root设置密码等。
启动 mariadb、httpd 并测试。
测试成功后进行 ansible 的配置。
2. ansible 定义 主机清单组
[websrvs]
192.168.2.11
192.168.2.12
3 创建 roles 相关的文件
mkdir /etc/ansible/lamp/roles/{prepare,httpd,mysql,php}/{tasks,files,handlers,templates,vars,meta,default} -pv
4 将上面搭建好的 lamp 环境的 httpd 和 mysql 的配置文件拷贝到对应目录下
cd /etc/ansible
cp /etc/httpd/conf/httpd.conf lamp/roles/httpd/files/
cp /etc/my.cnf lamp/roles/mysql/files/
cp /var/www/html/index.php lamp/roles/httpd/files/
5 写 prepare(前期准备)角色的 playbooks
vim lamp/roles/prepare/tasks/main.yml:
- name: delete yum config
shell: rm -rf /etc/yum.repos.d/*
- name: provide yumrepo file
shell: wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
- name: clean the yum repo
shell: yum clean all
- name: clean the iptables
shell: iptables -F
6 构建 httpd 的任务
/etc/ansible/lamp/roles/httpd/tasks/main.yml
- name: install httpd package
yum: name=httpd state=latest
- name: provide test page
copy: src=index.php dest=/var/www/html/index.php force=yes
- name: delete httpd.conf
shell: rm -rf /etc/httpd/conf/httpd.conf
- name: install configuration file
copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf force=yes
notify:
- restart httpd
/etc/ansible/lamp/roles/httpd/handlers/main.yml
- name: restart httpd
service: name=httpd state=restarted
7 构建 mariadb 服务
/etc/ansible/lamp/roles/mysql/tasks/main.yml
- name: install mysql
yum: name="mariadb-server" state="latest"
- name: create mysql group
group: name=mysql state=present system=yes
- name: create mysql user
user: name=mysql group=mysql state=present system=yes
- name: mkdir the directory
shell: mkdir -p /mydata/data
- name: chage the owner
shell: chown -R mysql.mysql /mydata
- name: delete my.cnf
shell: rm -rf /etc/my.cnf
- name: install my.cnf
copy: src=my.cnf dest=/etc/my.cnf force=yes
notify:
- restart mysql
/etc/ansible/lamp/roles/mysql/handlers/main.yml
- name: restart mysql
service: name=mariadb state=restarted
数据文件这里就不复制了,就复制配置文件好了
8 构建 php 的任务
/etc/ansible/lamp/roles/php/tasks/main.yml
- name: install php
yum: name=php state=latest
- name: install php-mysql
yum: name=php-mysql state=latest
9 定义整个任务
/etc/ansible/lamp/site.yml
- name: LAMP build
remote_user: root
hosts: websrvs
roles:
- prepare
- mysql
- php
- httpd