Ansible是一款为类Unix系统开发的自由开源的配置和自动化工具。它用Python写成,类似于saltstack和Puppet,但是有一个不同和优点是我们不需要在节点中安装任何客户端。它使用SSH来和节点进行通信。Ansible基于 Python paramiko 开发,分布式,无需客户端,轻量级,配置语法使用 YMAL 及 Jinja2模板语言,更强的远程命令执行操作
配置本地源
[root@centos1 ~]# vim /etc/yum.repos.d/centos7.repo
[centos7]
name=centos7
baseurl=file:///mnt/cdrom
enabled=1
gpgcheck=0
配置absible本地源
[root@centos1 ~]# vim /etc/yum.repos.d/ansible.repo
[ansible]
name=ansible
baseurl=file:///root/ansible
enabled=1
gpgcheck=0
配置阿里网络源
[root@centos1 ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
配置epel源
Ansible软件默认不在yum仓库中,因此我们需要配置 epel仓库
[root@centos1 ~]# yum install -y epel-release
[root@centos1 ~]# ls
anaconda-ks.cfg ansible
安装ansible
[root@centos1 ~]# yum install -y ansible
ansible [-i 主机文件] [-f 批次] [组名] [-m 模块名称] [-a 模块参数]
-v,–verbose #详细模式,如果命令执行成功,输出详细的结果 (-vv –vvv -vvvv)
-i PATH, -inventory=PATH #指定host 文件的路径,默认是在 /etc/ansible/hosts,参数后指定的远程主机时,也可以写端口,用户,密码。
inventory [ˈɪnvəntri] 库存
-f NUM,-forks=NUM # NUM是指定一个整数,默认是 5 ,指定 fork 开启同步进程的个数。
-m NAME,-module-name=NAME #指定使用的 module 名称,默认使用 command模块
-a,MODULE_ARGS #指定 module 模块的参数,就是要执行的命令
-k,-ask-pass #提示输入 ssh 的密码,而不是使用基于 ssh 的密钥认证
-sudo # 指定使用 sudo 获得 root 权限
-K,-ask-sudo-pass #提示输入 sudo 密码,与 -sudo 一起使用
-u USERNAME,-user=USERNAME #指定移动端的执行用户
-C,–check #测试此命令执行会改变什么内容,不会真正的去执行
ansible-doc -l #列出所有的模块列表
ansible-doc -s 模块名 #查看指定模块的参数 -s, --snippet # [ˈsnɪpɪt] 片断
[root@centos1 ~]# vim /etc/ansible/hosts
#文件 /etc/ansible/hosts 维护着Ansible中服务器的清单。在文件最后追加以下内容
(这是一个组,可以针对不同组进行运维)
[web-servers]
192.168.100.102 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=abc123,
192.168.100.103 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=abc123,
ansible_ssh_port:指定ssh端口
ansible_ssh_user:指定 ssh 用户
ansible_ssh_pass:指定 ssh 用户登录是认证密码(明文密码不安全)
ansible_sudo_pass:指明 sudo 时候的密码
[root@centos1 ~]# ansible -i /etc/ansible/hosts web-servers -m ping
-i # 指定 host 文件的路径,默认是在 /etc/ansible/hosts
-m # 指定使用的ping模块
报错:
192.168.100.102 | FAILED! => {
"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host."z
}
解决:
[root@centos1 ~]# ssh [email protected]
#手动连接一下/etc/ansible/hosts主机清单中的主机,这样就可以在ansible服务器上保存目标主机的fingerprint指纹。后期可以正常连接了
[root@centos1 ~]# ansible -i /etc/ansible/hosts web-servers -m ping #测试成功
配置ssh无密码访问
一般来说,使用明文密码不安全,所以增加主机无密码访问。在Ansible服务端生成密钥,并且复制公钥到节点中。
[root@centos1 ~]# ssh-keygen
[root@centos1 ~]# ssh-copy-id [email protected]
[root@centos1 ~]# ssh-copy-id [email protected]
不指定-m参数时,使用的就是command模块;但是这些 “<”, “>”, “|”, and "&"操作都不可以, 缺点:不支持管道,没法批量执行命令;
command不支持各种命令方式,而shell支持
[root@centos1 ~]# ansible -i /etc/ansible/hosts web-servers -m shell -a “free -m”
注:但是我们自己定义在~/.bashrc或~/.bash_profile中的环境变量shell模块由于没有加载,所以无法识别;如果需要使用自定义的环境变量,就需要在最开始,执行加载自定义脚本的语句
使用scripts模块可以在本地写一个脚本,在远程服务器上执行:
[root@centos1 ~]# vim /etc/ansible/net.sh
#!/bin/bash
date
hostname
[root@centos1 ~]# ansible -i /etc/ansible/hosts web-servers -m script -a “/etc/ansible/net.sh”
实现主控端向目标主机拷贝文件,类似scp功能
把ansible主机上的/etc/hosts文件复制到主机组中机器的/tmp目录下
[root@centos1 ~]# ansible -i /etc/ansible/hosts web-servers -m copy -a “src=/etc/hosts dest=/tmp/ owner=root group=root mode=0755”
[root@centos1 ~]# ansible -i /etc/ansible/hosts web-servers -m shell -a “ls /tmp/hosts”
修改12,13上/tmp/hosts文件权限为777
[root@centos1 ~]# ansible -i /etc/ansible/hosts web-servers -m file -a “path=/tmp/hosts mode=0777”
查看文件权限
[root@centos2 ~]# ll /tmp/hosts
stat模块获取远程文件信息
[root@centos1 ~]# ansible -i /etc/ansible/hosts web-servers -m stat -a “path=/tmp/hosts”
192.168.100.102 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"stat": {
"atime": 1563264384.410397,
"attr_flags": "",
"attributes": [],
"block_size": 4096,
"blocks": 8,
"charset": "us-ascii",
"checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa",
"ctime": 1563264642.2300954,
"dev": 64768,
"device_type": 0,
"executable": true,
"exists": true,
"gid": 0,
"gr_name": "root",
"inode": 16777756,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"mimetype": "text/plain",
"mode": "0777",
"mtime": 1563264383.5873852,
"nlink": 1,
"path": "/tmp/hosts",
"pw_name": "root",
"readable": true,
"rgrp": true,
"roth": true,
"rusr": true,
"size": 158,
"uid": 0,
"version": "18446744072653809054",
"wgrp": true,
"woth": true,
"writeable": true,
"wusr": true,
"xgrp": true,
"xoth": true,
"xusr": true
}
}
get_url模块实现远程主机下载指定url到本地,支持sha256sum文件校验
下载epel-release-latest-7.noarch.rpm到主机清单中的/tmp/目录下
[root@centos1 ~]# ansible -i /etc/ansible/hosts web-servers -m get_url -a “url=https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm dest=/tmp/ mode=0440 force=yes”
如果force=yes,当下载文件时,如果所下的内容和原目录下的文件内容不一样,则替换原文件,如果一样,就不下载了。
在centos2查看下载的文件
[root@centos2 ~]# ll /tmp/epel-release-latest-7.noarch.rpm
测试force=yes
Centos2修改epel-release-latest-7.noarch.rpm文件,centos3不修改,然后再此执行下载命令
[root@centos2 ~]# cp /etc/passwd /tmp/epel-release-latest-7.noarch.rpm
cp:是否覆盖"/tmp/epel-release-latest-7.noarch.rpm"? y
[root@centos1 ~]# ansible -i /etc/ansible/hosts web-servers -m get_url -a “url=https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm dest=/tmp/ mode=0440 force=yes”
#当文件不一样时,会替换原来的文件,修改成功的显示黄色,没有修改显示绿色
yum模块可以提供的status状态:
latest ,present,installed #这3个代表安装;
removed, absent #后面2个是卸载
安装httpd软件:
[root@centos1 ~]# ansible -i /etc/ansible/hosts web-servers -m yum -a “name=httpd state=latest”
[root@centos1 ~]# ansible -i /etc/ansible/hosts web-servers -m cron -a “name=‘list dir’ minute=’*/30’ job=‘ls /tmp’” #增加每30分钟执行ls /tmp
在centos2上查看
[root@centos2 ~]# crontab -l
#Ansible: list dir
*/30 * * * * ls /tmp
service模块常用参数:
(1)name参数:指定需要操作的服务名称,比如 nginx,httpd。
(2)state参数:指定服务的状态,比如,启动远程主机中的httpd,就将 state 的值设置为 started;如果停止远程主机中的服务,就将 state 的值设置为 stopped。此参数的可用值有 started、stopped、restarted(重启)、reloaded。
enabled参数:是否将服务设置为开机启动项,设置为 yes 表示将对应服务设置为开机启动,设置为 no 表示不会开机启动。
注:想使用service模块启动服务,被启动的服务,必须支持service 命令启动或关闭
远程启动apache服务
[root@centos1 ~]# ansible -i /etc/ansible/hosts web-servers -m service -a “name=httpd state=restarted”
Centos2查看httpd状态
[root@centos2 ~]# systemctl status httpd
[root@centos1 ~]# ansible -i /etc/ansible/hosts web-servers -m sysctl -a “name=net.ipv4.ip_forward value=1 reload=yes”
Centos2查看状态
[root@centos2 ~]# cat /proc/sys/net/ipv4/ip_forward
1
在被管理端添加账号centos2
[root@centos1 ~]# ansible -i /etc/ansible/hosts web-servers -m user -a “name=centos2 state=present”
去centos2查看账号
[root@centos2 ~]# id centos2
uid=1002(centos2) gid=1002(centos2) 组=1002(centos2)
Playbook是一个不同于使用ansible命令行执行方式的模式,功能更强大更灵活。
- name: task description #任务描述信息
module_name: module_args #需要使用的模块名字: 模块参数
[root@centos1 ~]# ansible-playbook site.yml
playbook是由一个或多个"play"组成的列表。play的主要功能在于将事先归为一组的主机装扮成事先通过ansible中的task定义好的角色。
github上提供了大量的实例供大家参考:
https://github.com/ansible/ansible-examples
这些文件都需要自己创建
files:存放需要同步到异地服务器的源码文件及配置文件;
handlers:当服务的配置文件发生变化时需要进行的操作,比如:重启服务,重新加载配置文件; ['hændləz] 处理程序
meta:角色定义,可留空; ['metə] 元
tasks:需要进行的执行的任务; #任务
templates:用于执行lamp安装的模板文件,一般为脚本; ['templɪts] 模板
vars:本次安装定义的变量
首先,我们可以在ansible服务器上安装LAMP环境,然后,再将配置文件通过ansible拷贝到远程主机上
[root@centos1 ~]# yum install -y httpd
[root@centos1 ~]# systemctl start httpd
[root@centos1 ~]# yum install -y mariadb-server mariadb
[root@centos1 ~]# mkdir -p /data/mysql/data #创建数据库保存目录
[root@centos1 ~]# chown -R mysql:mysql /data/mysql/ #修改权限
[root@centos1 ~]# vim /etc/my.cnf #修改数据保存目录
[mysqld]
datadir=/data/mysql/data
[root@centos1 ~]# systemctl start mariadb
[root@centos1 ~]# yum install -y php php-mysql
提供php的测试页
[root@centos1 ~]# vim /var/www/html/index.php
重启httpd服务
[root@centos1 ~]# systemctl restart httpd
http://192.168.100.101/
确保已经出现上面的测试页,而且,要看到MySQL已经被整合进来了,才能进行下一步操作
[root@centos1 ~]# vim /etc/ansible/hosts
[web-servers]
192.168.100.102
192.168.100.103
设置过请跳过
[root@centos1 ~]# ssh-keygen
[root@centos1 ~]# ssh-copy-id [email protected]
[root@centos1 ~]# ssh-copy-id [email protected]
[root@centos1~]# mkdir -pv /etc/ansible/lamp/roles/{prepare,httpd,mysql,php}/{tasks,files,templates,vars,meta,default,handlers}
将搭建成功的LAMP环境的httpd和MySQL的配置文件拷贝到对应目录下
[root@centos1 ~]# cd /etc/ansible/
[root@centos1 ansible]# cp /etc/httpd/conf/httpd.conf lamp/roles/httpd/files/
[root@centos1 ansible]# cp /etc/my.cnf lamp/roles/mysql/files/
#咱们没有网络可以不设置这个脚本,是初始化系统环境的脚本(略过)
[root@centos1 ansible]# vim lamp/roles/prepare/tasks/main.yml
- name: delete yum config
shell: rm -rf /etc/yum.repos.d/* #删除原有的yum配置文件
- name: provide yumrepo file
shell: wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo #下载新的yum配置>文件
- name: clean the yum repo
shell: yum clean all #清除原有的yum缓存信息
- name: clean the iptables
shell: iptables -F #清除原有防火墙规则,不然后可能上不了网
[root@centos1 ansible]# cd /etc/ansible/lamp/roles
[root@centos1 roles]# cp /var/www/html/index.php httpd/files/
[root@centos1 roles]# vim httpd/tasks/main.yml
- name: web server install
yum: name=httpd state=present #安装httpd服务
- name: provide test page
copy: src=index.php dest=/var/www/html #提供测试页
- name: delete apache config
shell: rm -rf /etc/httpd/conf/httpd.conf #删除原有的apache配置文件,如果不删除,下面的copy任务是不会执行的,因为当源文件httpd.conf和目标文件一样时,copy命令是不执行的。如果copy命令不执行,那么notify将不调用handler。
- name: provide configuration file
copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf #提供httpd的配置文件
notify: restart httpd #当前面的copy复制成功后,通过notify通知名字为restart httpd的handlers运行。
notify [ˈnəʊtɪfaɪ] 通知
notify: 这个action(行动)可用于在每个play的最后被触发,这样可以避免多次有改变发生时,每次都执行指定的操作,取而代之,仅在所有的变化发生完成后一次性地执行指定操作。
在notify中列出的操作称为handler,也即notify中调用handler中定义的操作。例子:看加粗
---- name: test.yml just for test
hosts: testserver
vars:
region: ap-southeast-1
tasks:
- name: template configuration
file template: src=template.j2 dest=/etc/foo.conf
notify:
- restart memcached
- restart apache
handlers:
- name: restart memcached
service: name=memcached state=restarted
- name: restart apache
service: name=apache state=restarted
handlers概述:
Handlers 也是一些 task(任务)的列表,通过名字来引用,它们和一般的并没有什么区别。
Handlers 是由通知者进行notify, 如果没有被 notify,handlers 不会执行。
不管有多少个通知者进行了notify,等到 play 中的所有 task 执行完成之后,handlers 也只会被执行一次。
Handlers 最佳的应用场景是用来重启服务,或者触发系统重启操作.除此以外很少用到了。
[root@centos1 roles]# vim httpd/handlers/main.yml
- name: restart httpd
service: name=httpd enabled=yes state=restarted
创建MySQL服务的任务,需要安装MySQL服务,改变属主信息,启动MySQL
[root@centos1 roles]# cd /etc/ansible/lamp/roles
[root@centos1 roles]# vim mysql/tasks/main.yml
- name: install the mysql
yum: name=mariadb-server state=present #安装mysql服务
- name: mkdir date directory
shell: mkdir -p /data/mysql/data #创建数据挂载点目录
- name: provide configration file
copy: src=my.cnf dest=/etc/my.cnf #提供mysql的配置文件
- name: chage the owner
shell: chown -R mysql:mysql /data/mysql #更改属主和属组
- name: start mariadb
service: name=mariadb enabled=yes state=started #启动mysql服务
[root@centos1 roles]# vim php/tasks/main.yml
- name: install php
yum: name=php state=present #安装php
- name: install php-mysql
yum: name=php-mysql state=present #安装php与mysql交互的插件
[root@centos1 roles]# cd /etc/ansible/lamp/roles
[root@centos1 roles]# vim site.yml
- name: LAMP build
remote_user: root
hosts: web-servers
roles:
- prepare #如果前面没有写这个,把它删掉或者注释
- mysql
- php
- httpd
[root@centos1 ~]# ansible-playbook -i /etc/ansible/hosts /etc/ansible/lamp/roles/site.yml
http://192.168.100.102/
http://192.168.100.103/
默认情况下,首次登陆一台服务器,系统会提示是否要记住对端的指纹,用ansible也会这样,这样会导致需要手工输入yes或no,ansible 才可以往下执行。如需避免这种情况,需要在 /etc/ansible/ansible.cfg 文件中设置 host_key_checking = False
[root@centos1 ~]# rm -rf /root/.ssh/known_hosts
[root@centos1 ~]# ansible-playbook -i /etc/ansible/hosts /etc/ansible/lamp/roles/site.yml
[root@centos1 ~]# vim /etc/ansible/ansible.cfg
71 host_key_checking = False #去掉这一行的注释
[root@centos1 ~]# ansible-playbook -i /etc/ansible/hosts /etc/ansible/lamp/roles/site.yml
#不需要输入yes,直接执行