Ansible
1、 特性:
模块化:调用特定的模块,完成特定任务;
基于Python语言实现部署简单:agentless;
支持自定义模块;
支持playbook;编排任务;
ansible自身并不实现任何管理任务,它的所有管理任务,统统都使用模块完成;
2、 安装
]# yum -y install ansible
安装ansible
]# rpm -ql ansible | less
安装了大量的模块,其中:
/etc/ansible/ansible.cfg 主配置文件,配置ansible程序的工作特性
/etc/ansible/hosts 主机清单
/etc/ansible/roles 存放角色的目录
/usr/bin/ansible 主程序
/usr/bin/ansible-doc 查看配置文档
/usr/bin/ansible-galaxy
/usr/bin/ansible-playbook 辅助工具:剧本
模块:
获取模块列表:ansible-doc -l
获取指定模块的使用帮助:ansible-doc -s MOD_NAME
查看模块选项用法
先在管理主机上配置ssh-keygen生成秘钥对
[root@centos6clean ansible]# ssh-keygen -t rsa -P ''
[root@centos6clean ~]# ssh-copy-id -i .ssh/id_rsa.pub root@10.1.72.10
[root@centos6clean ~]# ssh-copy-id -i .ssh/id_rsa.pub root@10.1.72.20
简单应用:
a)、Vim /etc/ansible/hosts
定义一个keepalived组,里面包含2台主机
20 [keepalived]
21 10.1.72.10
22 10.1.72.20
[root@centos6clean ~]# ansible keepalived -m ping
b)、使用command模块
[root@centos6clean ~]# ansible keepalived -m command -a "ls /tmp"
C)、使用shell模块
[root@centos6clean ~]# ansible all -m shell -a "cat /etc/fstab | grep 'ext4'"
注意:command和shell模块的核心参数直接为命令本身;而其它模块的参数通常为“key=value”格式
d)、使用copy模块
[root@centos6clean ~]# ansible all -m copy -a "src=/etc/issue dest=/tmp/issue.bak mode=777"
[root@centos6clean ~]# ansible all -m copy -a "content=hello\nworld dest=/tmp/hello"
可以直接将文件内容写进文件
[root@centos6clean ~]# ansible all -m copy -a "content=hello\nworld owner=root dest=/tmp/hello"也可以直接指定属主
e)、使用cron模块
[root@centos6clean ~]# ansible all -m cron -a "minute=*/10 job='/sbin/ntpdate 10.1.0.1 &> /dev/null' name=ntp state=present"
Name:表示计划任务条目,必须指定
State:表示状态present(创建)是默认值|absent(删除)
f)、使用fetch模块:表示从远程主机取文件
[root@centos6clean ~]# ansible all -m fetch -a "src=/etc/issue dest=/tmp/issue.bak"
g)、file:设定文件特性;(修改属主、组等属性)
(1)创建链接文件
[root@centos6clean ~]# ansible 10.1.72.10 -m file -a "path=/tmp/issue src=/etc/issue state=link"
Path:表示要创建的链接文件
Src:链接哪个文件
(2)修改属性
[root@centos6clean ~]# ansible 10.1.72.10 -m file -a "path=/tmp/hello owner=user1 mode=222"
(3)创建文件夹
[root@centos6clean ~]# ansible 10.1.72.10 -m file -a "path=/tmp/tmp state=directory"
h)、使用hostname模块
要使用变量方式,写个循环实现批量更改远程主机主机名
i)、使用yum模块
[root@centos6clean ~]# ansible all -m yum -a "name=tree state=present"
name= 指定程序包名称,可以带版本号,默认最新版本;
state=
present,latest(最新版) 安装程序;
absent 卸载程序;
j)、使用service模块,:管理远程主机的服务
[root@centos6clean ~]# ansible all -m service -a "name=httpd state=started"
[root@centos6clean ~]# ansible all -m service -a "name=httpd state=stopped"
name= 指明管理的服务
state=
started 启动服务;
stopped 停止服务;
restarted 重启服务;
enabled= 开机自动启动;1或0;
k)、使用user模块
name= 指定要管理的用户;
state= 为present | absent;
system= 是否创建系统账号;
uid= 指定UID;
shell= 默认shell类型;
group= 基本组;
groups= 额外(附加)组;
comment= 注释信息;
home= 用户的家目录;
remove 当state=absent时,删除用户时同时删除家目录;
[root@centos6clean ~]# ansible all -m user -a "name=newuser shell=/sbin/nologin uid=555"
[root@centos6clean ~]# ansible all -m user -a "name=newuser state=absent"//删除用户
l)、使用group模块
name=管理的组
state=新建|删除
system=系统组
gid=
[root@centos6clean ~]# ansible all -m group -a "name=newgroup system=true"
3、YAML:是数据序列化格式设计的可读性与脚本语言与互动
数据结构:
key:value
– item1
– item2
– item3
{name:jerry, age:21}
4、PlayBook:
核心元素:
Tasks:任务,由模块定义的操作的列表;
Variables:变量,可调用ansible的变量或自定义的变量
Templates:模板,即使用了模板语法的文本文件;
Handlers:由特定条件触发的Tasks;
Roles:角色,就是由以上元素组成;把主机列表分出来,用到哪个主机时,就放在哪个主机上执行;
主要作用:就是能够把多个相关联的任务,通过读取YAML格式的配置文件一次编完;要把任务、变量、模板、处理器放在一个YAML格式文件中进行指定,然后任务就可一次批量执行;
Vim /etc/ansibles/first.yaml
– hosts: all
remote_user: root
tasks:
– name: create user
user: name=user111 system=true //SYSTEM=true 表示系统用户
– name: create group
group: name=group111 system=true state=present
注意:此处严格要求语法
[root@centos6clean ansible]# ansible-playbook –check first.yaml//预设置
[root@centos6clean ansible]# ansible-playbook –check –list-hosts –list-tasks first.yaml
–list-hosts:显示要执行的主机
–list-tasks:显示要执行的任务
[root@centos6clean ansible]# ansible-playbook –check –syntax-check first.yaml
–syntax-check:测试语法
[root@centos6clean ansible]# ansible-playbook first.yaml //执行
GATHERING FACTS 第一个任务,是默认的,在每一个目标主机上运行之前,需要知道目标主机的状态,例如主机名、ip地址等,这些都是内建变量,叫主机的facts变量,是ansible可调用的变量之一;这个过程就是收集变量的过程,也可手动收集;
TASK [create user] 在playbook中定义的第一个任务
TASK [create group] 在playbook中定义的第二个任务
PLAY RECAP 返回的报告
[root@centos6clean ansible]# ansible all -m setup //手动收集信息
5、handlers:由特定条件触发的Tasks
使用场景:当远程主机已经启动nginx服务,并监听在80端口,这时,我想改变监听的端口
[root@centos6clean ansible]# vim nginx.yaml
– hosts: all
remote_user: root
tasks:
– name: install nginx
yum: name=nginx
– name: start nginx
service: name=nginx state=started
– name: set conf
copy: src=/etc/nginx/nginx.conf dest=/etc/nginx/nginx.conf
notify: reload nginx
handlers:
– name: reload nginx
shell: nginx -s reload
如果仅修改了配置文件,却还要从第一步,执行安装程序包,这样是没必要的,所以,可使用tag,给任务加标签,不指定标签时,执行所有任务,加标签时,只执行标签所在的任务;修改如下:tags
vim nginx.yaml
– hosts: all
remote_user: root
tasks:
– name: install nginx
yum: name=nginx
– name: start nginx
service: name=nginx state=started
– name: set conf
copy: src=/etc/nginx/nginx.conf dest=/etc/nginx/nginx.conf
tags: instconf
notify: reload nginx
handlers:
– name: reload nginx
shell: nginx -s reload
[root@centos6clean ansible]# ansible-playbook -t instconf –list-tasks nginx.yaml
显示标签
[root@centos6clean ansible]# ansible-playbook –check -t instconf nginx.yaml
跳过执行
可以定义一个标签,多次使用
vim nginx.yaml
– hosts: all
remote_user: root
tasks:
– name: install nginx
yum: name=nginx
tags: instconf
– name: start nginx
service: name=nginx state=started
– name: set conf
copy: src=/etc/nginx/nginx.conf dest=/etc/nginx/nginx.conf
tags: instconf
notify: reload nginx
handlers:
– name: reload nginx
shell: nginx -s reload
[root@centos6clean ansible]# ansible-playbook -t instconf nginx.yaml
也可以定义多个标签一同调用
vim nginx.yaml
– hosts: all
remote_user: root
tasks:
– name: install nginx
yum: name=nginx
tags: instnginx
– name: start nginx
service: name=nginx state=started
– name: set conf
copy: src=/etc/nginx/nginx.conf dest=/etc/nginx/nginx.conf
tags: instconf
notify: reload nginx
handlers:
– name: reload nginx
shell: nginx -s reload
[root@centos6clean ansible]# ansible-playbook -t instconf,instnginx nginx.yaml
Playbook小结:
Hosts: 指明任务的目标主机
Remote_user: 在远程主机上执行任务的用户
tasks: 任务列表
如果指明了三个任务,在三台主机上运行,执行次序是,把第一个任务在第三台主机运行,没问题则在三台主机上再运行第二个任务,如果在运行其中某一主机出现故障,后面的任务会终止;所以,任务列表,是自上而下,每个任务依次进行的;
6、variables:变量
类型:
内建:
(1) facts:任何facts变量都由正在通信的目标主机发回的信息,ansible自动获取变量,可直接调用;在setup模块中查看变量;
自定义:
(1) 命令行传递;
-e VAR=VALUE
vim install.yaml
– hosts: all
remote_user: root
tasks:
– name: install
yum: name={{ pkgname }} state=present
[root@centos6clean ansible]# ansible-playbook -e pkgname=tree install.yaml
(2) 在hosts Inventory中为每个主机定义专用变量值;
(a) 向不同的主机传递不同的变量 ;
IP/HOSTNAME variable_name=value
在/etc/ansible/hosts文件中写入参数
[keepalived]
10.1.72.10 hostn=cent10
10.1.72.20 hostn=cent20
[root@centos6clean ansible]# vim host.yaml
– hosts: keepalived
remote_user: root
tasks:
– name: hostname
hostname: name={{ hostn }}
[root@centos6clean ansible]# ansible-playbook host.yaml
(b) 向组内的所有主机传递相同的变量 ;
[groupname:vars]
variable_name=value
[keepalived]
10.1.72.10
10.1.72.20
[keepalived:vars]
pkgname=tree
[root@centos6clean ansible]# vim host.yaml
– hosts: keepalived
remote_user: root
tasks:
– name: hostname
hostname: name={{ hostn }}
[root@centos6clean ansible]# ansible-playbook host.yaml
(3) 在playbook中定义
vars:
– var_name: value
– var_name: value
– hosts: all
remote_user: root
vars:
– pkgname: tree
tasks:
– name: install
yum: name={{ pkgname }} state=present
[root@centos6clean ansible]# ansible-playbook install.yaml
(4) Inventory还可以使用参数:
用于定义ansible远程连接目标主机时使用的属性,而非传递给playbook的变量;
ansible_ssh_host
ansible_ssh_port
ansible_ssh_user
ansible_ssh_pass
ansible_sudo_pass
…
此方法很少使用
(5) 在角色调用时传递
roles:
– { role: ROLE_NAME, var: value, …}
Templates:模板
文本文件,内部嵌套有模板语言脚本(使用模板语言编写)
补充一点:setup模块式用来收集主机的一些信息的
执行模板文件中的脚本,并生成结果数据流,需要使用template模块;
template:
-a ”“
src=
dest=
mode=
onwer=
group=
注意:此模板不能在命令行使用,而只能用于playbook;
vim nginx.yaml
– hosts: keepalived
remote_user: root
tasks:
– name: install nginx
yum: name=nginx state=present
– name: start service
service: name=nginx state=started
– name: set conf
template: src=/root/nginx.conf.j2 dest=/etc/nginx/nginx.conf
tags: setconf
notify: reload server
handlers:
– name: reload server
shell: nginx -s reload
[root@centos6clean ansible]# vim /root/nginx.conf.j2
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes {{ ansible_processor_vcpus }};
条件测试:when语句:在tasks中使用,Jinja2的语法格式
vim nginx.yaml
– hosts: all
remote_user: root
tasks:
– name: install nginx
yum: name=nginx state=present
– name: start service6
shell: service nginx start
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "6"
– name: start service
shell: systemctl start nginx
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
1、基于列表的方式
vim install.yaml
– hosts: all
remote_user: root
tasks:
– name: install
yum: name={{ item }} state=present
with_items:
– tree
– php
– vsftpd
2、基于字典的方式
vim createuser.yaml
– hosts: 10.1.72.10
remote_user: root
tasks:
– name: create group
group: name={{ item }} state=present
with_items:
– group1
– group2
– group3
– name: create user
user: name={{ item.user }} group={{ item.group }} state=present
with_items:
– {user: "user1",group: "group1"}
– {user: "user2",group: "group2"}
– {user: "user3",group: "group3"}
===================给centos6|7安装amp并启动服务============================
vim amp.yaml
– hosts: all
remote_user: root
tasks:
– name: install amp
yum: name={{ item }} state=present
with_items:
– php
– php-mysql
– mysql
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "6"
– name: start server
shell: service mysqld start
shell: service httpd start
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "6"
– name: install amp
yum: name={{ item }} state=present
with_items:
– php
– php-mysql
– mariadb
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
– name: start server
shell: systemctl start mariadb
shell: systemctl start httpd
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
角色:roles
以特定的层级目录结构进行组织的tasks、variables、handlers、templates、files等;
role_name/
files/:存储由copy或script等模块调用的文件;
tasks/:此目录中至少应该有一个名为main.yml的文件,用于定义各task;其它的文件需要由main.yml进行“包含”调用;
handlers/:此目录中至少应该有一个名为main.yml的文件,用于定义各handler;其它的文件需要由main.yml进行“包含”调用;
vars/:此目录中至少应该有一个名为main.yml的文件,用于定义各variable;其它的文件需要由main.yml进行“包含”调用;
templates/:存储由template模块调用的模板文本;
meta/:此目录中至少应该有一个名为main.yml的文件,定义当前角色的特殊设定及其依赖关系;其它的文件需要由main.yml进行“包含”调用;
default/:此目录中至少应该有一个名为main.yml的文件,用于设定默认变量;
在playbook中调用角色的方法:
– hosts: HOSTS
remote_user: USERNAME
roles:
– ROLE1
– ROLE2
– { role: ROLE3, VARIABLE: VALUE, …}
– { role: ROLE4, when: CONDITION }
第一步:创建固定目录结构
]# mkdir /etc/ansible/roles/nginx/{files,tasks,templates,handlers,vars,default,meta} -pv
]# tree /etc/ansible/roles/nginx/
第二步:提供各目录下的配置文件
[root@centos6clean nginx]# vim tasks/main.yml
– name: install nginx
yum: name=nginx state=present
– name: copy conf
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: reload nginx
tags: setconf
– name: start nginx
service: name=nginx state=started
[root@centos6clean nginx]# vim handles/main.yml
– name: reload nginx
shell: nginx -s reload
[root@centos6clean nginx]# cp /root/nginx.conf.j2 templates/
第三步:编写yml文件
[root@centos6clean nginx]#vim nginx.yml
hosts: keepalived
remote_user: root
roles:
– nginx
实战作业:
(1) 主/备模型的keepalived+nginx;
(2) httpd+php+php-mysql;
(3) mysql-server或mariadb-server;
拥有testdb库,并允许testuser对其拥有所有权限;
准备环境:
[root@centos6cleanroles]#mkdir{keepalived,mariadb,php,phpmysql,httpd}/{files,tasks,vars,templates,meta,default,handlers} -pv
[root@centos6clean ansible]# vim hosts
[keepalived]
10.1.72.10 STATE=MASTER LEVEL=100 ip_addr=10.1.72.10
10.1.72.20 STATE=BACKUP LEVEL=90 ip_addr=10.1.72.20
#STATE是keepalived的状态
#LEVEL是优先级
#ip_addr是nginx反代
[nginx]
10.1.72.40
10.1.72.30
[mariadb]
10.1.72.60
[root@centos6clean ansible]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@10.1.72.30 …//拷贝ssh
Keepalived角色
[root@centos6clean ansible]# vim roles/keepalived/tasks/main.yml
– name: install keeplived
yum: name=keepalived state=present
– name: set conf
template: src=keepalived.conf.j2 dest=/etc/keepalived/keepalived.conf
– name: start keepalived
service: name=keepalived state=started
[root@centos6cleanansible]#cp/etc/keepalived/keepalived.conf ./roles/keepalived/templates/keepalived.conf.j2
[root@centos6clean ansible]# vim roles/keepalived/templates/keepalived.conf.j2
global_defs {
notification_email {
root@localhost
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_script nginx {
script "killall -0 nginx && exit 0 || exit 1"
interval 3
weight -50
}
vrrp_instance VI_1 {
state {{ STATE }}
interface eth0
virtual_router_id 51
priority {{ LEVEL }}
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
{{ ip_addr }}
}
track_script {
nginx
}
[root@centos6clean ansible]# vim roles/keepalived/vars/main.yml
ip_addr: "10.1.72.211/16"
Nginx角色
[root@centos6clean ansible]# vim roles/nginx/tasks/main.yml
– name: install nginx
yum: name=nginx state=present
– name: copy conf
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: reload nginx
tags: setconf
– name: start nginx
service: name=nginx state=started
[root@centos6clean ansible]# vim roles/nginx/handles/main.yml
– name: reload nginx
shell: nginx -s reload
[root@centos6clean ansible]# vim roles/nginx/templates/nginx.conf.j2
user nginx;
worker_processes {{ ansible_processor_vcpus }};
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr – $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
upstream webser {
server 10.1.72.30 weight=2;
server 10.1.72.40 weight=1
}
server {
listen 80;
root /var/www/html;
server_name www.72.com;
location / {
proxy_pass http://webser;
}
}
}
http角色
[root@centos6clean ansible]# vim roles/httpd/tasks/main.yml
– name: install amp
yum: name={{ item }} state=present
with_items:
– httpd
– php
– php-mysql
– name: start amp
service: name=httpd state=started
– name: copy
copy: src=index.php dest=/var/www/html/index.php
vim roles/httpd/files/index.php
<?php
$conn=mysql_connect("10.1.72.60",'testuser','123');
if ($conn){
echo "sussful";
}else{
echo "fales";
}
?>
mariadb角色
[root@centos6clean ansible]# vim roles/mariadb/tasks/main.yml
– name: install mariadb
yum: name=mariadb-server state=present
– name: start mariadb
service: name=mariadb state=started
– name: create db
script: sql.sh
[root@centos6clean ansible]# vim ./roles/mariadb/files/sql.sh
#!/bin/bash
#
mysql_host="127.0.0.1"
mysql_user="testuser"
mysql_pass="123"
mysql_db="testdb"
mysql -e "create database $mysql_db;"
mysql -e "grant all on $mysql_db.* to '$mysql_user'@'%' identified by '$mysql_pass';"
剧本文件:
[root@centos6clean ansible]# vim ans.yml
– hosts: all
remote_user: root
roles:
– { role: nginx, when: "ansible_default_ipv4.address == '10.1.72.10'"}
– { role: nginx, when: "ansible_default_ipv4.address == '10.1.72.20'"}
– { role: keepalived, when: "ansible_default_ipv4.address == '10.1.72.10'"}
– { role: keepalived, when: "ansible_default_ipv4.address == '10.1.72.20'"}
– { role: httpd, when: "ansible_default_ipv4.address == '10.1.72.30'"}
– { role: httpd, when: "ansible_default_ipv4.address == '10.1.72.40'"}
– { role: mariadb, when: "ansible_default_ipv4.address == '10.1.72.60'"}
[root@centos6clean roles]# tree
.├── httpd
│ ├── default
│ ├── files
│ │ └── index.php
│ ├── handlers
│ ├── meta
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ └── vars
├── keepalived
│ ├── default
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ │ └── keepalived.conf.j2
│ └── vars
│ └── main.yml
├── mariadb
│ ├── default
│ ├── files
│ │ └── sql.sh
│ ├── handlers
│ ├── meta
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ └── vars
└── nginx
├── default
├── files
├── handlers
│ └── main.yml
├── meta
├── tasks
│ └── main.yml
└── templates
└── nginx.conf.j2
原创文章,作者:landanhero,如若转载,请注明出处:http://www.178linux.com/57923