ansible概述:
Ansible是一款为类Unix系统开发的自由开源的配置和自动化工具。它用Python写成,类似于saltstack和Puppet,但是有一个不同和优点是我们不需要在节点中安装任何客户端。它使用SSH来和节点进行通信。Ansible基于 Python paramiko 开发,分布式,无需客户端,轻量级,配置语法使用 YMAL 及 Jinja2模板语言,更强的远程命令执行操作。
ansible具有的特点:
1、部署简单,只需在主控端部署Ansible环境,被控端无需做任何操作;
2、默认使用SSH协议对设备进行管理;
3、主从集中化管理;
4、配置简单、功能强大、扩展性强;
5、支持API及自定义模块,可通过Python轻松扩展;
6、通过Playbooks来定制强大的配置、状态管理
7、对云计算平台、大数据都有很好的支持;
1.2 ansible工作原理:
Ansible 在管理节点将 Ansible 模块通过 SSH 协议推送到被管理端执行,执行完之后自动删除,可以使用 SVN 等来管理自定义模块及编排。
由上面的图可以看到 Ansible 的组成由 5 个部分组成:
Ansible : ansible核心
Modules : 包括 Ansible 自带的核心模块及自定义模块
Plugins : 完成模块功能的补充,包括连接插件、邮件插件等
Playbooks : 剧本;定义 Ansible 多任务配置文件,由Ansible 自动执行
Inventory : 定义 Ansible 管理主机的清单 [ˈɪnvəntri] 清单
ansible过程
官方文档:https://docs.ansible.com/ansible/latest/modules/list_of_database_modules.html
安装ansible服务
在ansible【172.16.1.61】安装服务:
安装epel仓库(ansible在epel扩展仓库中)
[root@m01 ~]# yum install epel-release -y
安装ansible:
[root@m01 ~]# yum install ansible -y
[root@m01 ~]# ansible --version #阿里云镜像可以下载最新版本的服务
ansible 2.8.5
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
ansible参数
anisble命令语法: ansible [-i 主机文件] [-f 批次] [组名] [-m 模块名称] [-a 模块参数]
ansible详细参数:
-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查询命令:
ansible-doc -l #列出所有的模块列表
ansible-doc -s 模块名 #查看指定模块的参数 -s, --snippet # [ˈsnɪpɪt] 片断
定义主机清单
基于端口,用户,密码定义主机清单
格式:
ansible_ssh_port :指定ssh端口
ansible_ssh_user :指定 ssh 用户
ansible_ssh_pass :指定 ssh 用户登录是认证密码(明文密码不安全)
ansible_sudo_pass :指明 sudo 时候的密码
ansible_host --- 可以设置IP地址信息, 建立地址和名称解析关系
ansible_become --- 是否开启普通用户提权操作 yes true(开启)/no false
ansible_become_method --- 指定普通用户提权方法 su - root / sudo
ansible_become_user --- 指定提权后用户身份
ansible_become_password --- 指定提权后用户密码
采取用户进行批量管理提权操作:
采用su方式进行提权:
172.16.1.41 ansible_user=wei ansible_password=123456 ansible_become=yes ansible_become_method=su ansible_become_user=root ansible_become_password=123123
采用sudo方式进行提权:
172.16.1.41 ansible_user=wei ansible_password=123456 ansible_become=yes ansible_become_method=sudo ansible_sudo_user= oldboy ansible_become_password=123456
配置文件: (定义的主机清单)
[root@m01 ansible]# ls
ansible.cfg hosts (主机清单) roles(角色)
方式一:
[db_server] #主机组名
192.168.1.64 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=123456 #定义:端口,登录用户,密码
方式二:主机组变量设置方法 (剧本)
主机组变量设置方法 (剧本)
[rsync_server]
172.16.1.41
172.16.1.42
172.16.1.43
172.16.1.44
[rsync_server:vars]
ansible_user=root
ansible_password=123123
oldboy=123
方式三: 主机组子组配置方法
[db:children] #孩子
master_db
slave_db
[master_db]
172.16.1.7
[slave_db]
172.16.1.31
172.16.1.41
方式四:序列匹配配置方法
[rsync_server]
172.16.1.[41:100]
前提:批量管理用户服务要创建公钥文件
第一种方式:
[root@m01 ansible]# ssh-keygen #一路回车 #脚本批量分发公钥文件 #!/bin/bash #先下载 yum install sshpass #创建秘钥 # ssh-keygen . /etc/init.d/functions for ip in {7,31,41} do sshpass -pnihao123! ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.$ip -o StrictHostKeyChecking=no &>/dev/ null if [ $? -eq 0 ] then action "主机 172.16.1.$ip" /bin/true echo "" else action "主机 172.16.1.$ip" /bin/false echo "" fi done
第二种方式:
[root@m01 .ssh]# ansible db_server -m copy -a "src=/root/.ssh/id_rsa.pub dest=/root/.ssh" #创建完公钥通过ansible发送过去
简单测试主机是否可以ping通:
[root@m01 ansible]# ansible -i /etc/ansible/hosts db_server -m ping
-i # 指定 host 文件的路径,默认是在 /etc/ansible/hosts
-m # 指定使用的ping模块
在ansible服务端运行命令
例1:ping模块检查网络连通性
command模块执行shell命令,command:作为ansible的默认模块,可以运行远程权限范围内的所有shell命令
例1:使用ping检查‘db_server’或者ansible节点的连通性。
[root@ansible ~]# ansible -i /etc/ansible/hosts 'db_server' -m ping
或:
[root@ansible ~]# ansible 'db_server' -m ping #不指定,默认使用/etc/ansible/hosts文件
192.168.1.63 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.1.64 | SUCCESS => {
"changed": false,
"ping": "pong"
}
例2:检查Ansible节点的运行时间(uptime)
[root@ansible ~]# ansible -m command -a "uptime" 'db_server' #也可以把主机清单组名写到最后,这样方便阅读命令
172.16.1.7 | SUCCESS | rc=0 >>
12:45:23 up 32 min, 5 users, load average: 0.17, 0.11, 0.27
172.16.1.41 | SUCCESS | rc=0 >>
12:45:23 up 26 min, 2 users, load average: 0.03, 0.03, 0.10
例3:检查节点的内核版本
[root@ansible ~]# ansible -m command -a "uname -r" 'db_server'
例4:给节点增加用户
[root@ansible ~]# ansible -m command -a "useradd wei" 'db_server'
172.16.1.7 | SUCCESS | rc=0 >>
172.16.1.41| SUCCESS | rc=0 >>
[root@ansible ~]# ansible -m command -a "grep wei /etc/passwd" 'db_server'
例5:将df命令在所有节点执行后,重定向输出到本机的/tmp/command-output.txt文件中
[root@ansible ~]# ansible -m command -a "df -Th" 'db_server' > /tmp/command.txt
[root@ansible ~]# cat /tmp/command-output.txt
ansible常见模块高级使用方法
command模块
作用:为ansible默认模块,不指定-m参数时,使用的就是command模块; comand模块比较简单,常见的命令都可以使用,但其命令的执行不是通过shell执行的,所以,像这些 "<", ">", "|", and "&"操作都不可以,当然,也就不支持管道; 缺点:不支持管道,没法批量执行命令;
参数 | 选项/默认值 | 释义 |
chdir | 在执行命令前,进入到指定目录中 | |
creates | 判断指定文件是否存在,如果存在,不执行后面的操作 | |
removes | 判断指定文件是否存在,如果存在,执行后面的操作 | |
free_form | 必须要输入一个合理的命令 |
shell模块:
作用:在远程命令通过/bin/sh来执行
例1:运行free -m 命令
[root@ansible ~]# ansible -i /etc/ansible/hosts db_server -m shell -a "free -m"
注:但是我们自己定义在~/.bashrc或~/.bash_profile中的环境变量shell模块由于没有加载,所以无法识别;如果需要使用自定义的环境变量,就需要在最开始,执行加载自定义脚本的语句;
对shell模块的使用可以分成两块:
1) 如果待执行的语句少,可以直接写在一句话中:
[root@ansible ~]# ansible -i /etc/ansible/hosts db_server -m shell -a "source ~/.bash_profile && df -h | grep sda1"
2) 如果在远程待执行的语句比较多,可写成一个脚本,通过copy模块传到远端,然后再执行;但这样就又涉及到两次ansible调用;对于这种需求,ansible已经为我们考虑到了,script模块就是干这事的;
scripts模块
作用:在远程服务器上使用本地脚本
[root@m01 scripts]# vim ansible.sh
#!/bin/bash
ifconfig
[root@ansible ~]# ansible -i /etc/ansible/hosts db_server -m script -a "/server/scripts/ansible.sh" #执行在/server下的脚本
copy模块:
作用:实现主控端向目标主机拷贝文件,类似scp功能
例1:把ansible主机上的/etc/hosts文件复制到主机组中机器的/tmp目录下
[root@ansible ~]# ansible -i /etc/ansible/hosts db_server -m copy -a "src=/etc/hosts dest=/tmp/ owner=root group=root mode=0755"
相关选项如下:
backup:在覆盖之前,将源文件备份,备份文件包含时间信息。有两个选项:yes|no
content:用于替代“src”,可以直接设定指定文件的值
dest:必选项。要将源文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录
directory_mode:递归设定目录的权限,默认为系统默认权限
force:如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes
others:所有的file模块里的选项都可以在这里使用
src:被复制到远程主机的本地文件,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用“/”来结尾,则只复制目录里的内容,如果没有使用“/”来结尾,则包含目录在内的整个内容全部复制,类似于rsync。
file模块
作用:设置文件属性。
例如:
[root@ansible ~]# ansible -i /etc/ansible/hosts web-servers -m file -a "path=/tmp/hosts mode=0777"
– force:需要在两种情况下强制创建软链接,一种是源文件不存在但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no
– group:定义文件/目录的属组
– mode:定义文件/目录的权限
– owner:定义文件/目录的属主
– path:必选项,定义文件/目录的路径
– recurse:递归的设置文件的属性,只对目录有效
– src:要被链接的源文件的路径,只应用于state=link的情况
– dest:被链接到的路径,只应用于state=link的情况
– state:
。directory:如果目录不存在,创建目录
。file:即使文件不存在,也不会被创建
。link:创建软链接
。hard:创建硬链接
。touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
。absent:删除目录、文件或者取消链接文件
剧本:
# 更改文件所有权,组和模式。 当使用八进制数指定模式时,第一个数字应始终为0。 - file: path: /etc/foo.conf owner: foo group: foo mode: 0644 # touch创建文件,使用符号模式设置权限(相当于0644) - file: path: /etc/foo.conf state: touch mode: "u=rw,g=r,o=r" # touch创建文件,添加/删除一些权限 - file: path: /etc/foo.conf state: touch mode: "u+rw,g-wx,o-rwx" # 创建一个目录,如果它不存在 - file: path: /etc/some_directory state: directory mode: 0755
stat模块
作用:获取远程文件信息
[root@ansible ~]# ansible -i /etc/ansible/hosts db-servers -m stat -a "path=/tmp/hosts"
path:文件路径信息
get_url模块
作用:实现远程主机下载指定url到本地,支持sha256sum文件校验
例如:下载nginx-1.6.3.tar.gz到主机清单中的/tmp/目录下
[root@ansible ~]# ansible db-servers -m get_url -a "url=http://nginx.org/download/nginx-1.6.3.tar.gz dest=/tmp/ mode=0440 force=yes"
剧本:
- name: Download foo.conf get_url: url: http://example.com/path/file.conf dest: /etc/foo.conf mode: 0440 - name: Download file with custom HTTP headers get_url: url: http://example.com/path/file.conf dest: /etc/foo.conf headers: 'key:value,key:value' - name: Download file with check (sha256) get_url: url: http://example.com/path/file.conf dest: /etc/foo.conf checksum: sha256:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c
dest:指定节点目录
mode:权限
force:如果force=yes,当下载文件时,如果所下的内容和原目录下的文件内容不一样,则替换原文件,如果一样,就不下载了。
如果为“否”,则仅在目标不存在时才下载文件。 一般来说,只有小型本地文件才应该为“是”。 在0.6之前,该模块表现为默认为“是”。
yum模块
linux平台软件包管理:
state状态(安装)
。lstest
。present
。installed
(卸载)
。removed
。absent
例:安装httpd
[root@ansible ~]# ansible -i /etc/ansible/hosts db-servers -m yum -a "name=httpd state=latest"
剧本:
[root@ansible ~]# vim apache.yml - hosts: db_server remote_user: root gather_facts: False tasks: - name: install apache on CentOS 7 yum: name=httpd state=present - name: copy httpd conf copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf - name: start apache service service: name=httpd state=started
cron模块
作用:远程主机crontab配置
例: 每三十分钟执行 df -h 查看磁盘情况
[root@ansible ~]# ansible -i /etc/ansible/hosts db-servers -m cron -a "name='list fdisk' minute='*/30' job='df -h'"
常用参数:
。minute参数: 分钟
。hour参数:小时
。day参数: 天数
。month参数:月
。weekday参数:周
其他参数:
user参数:此参数用于设置当前计划任务属于哪个用户,当不使用此参数时,默认为管理员用户。
job参数:此参数用于指定计划的任务中需要实际执行的命令或者脚本,比如上例中的 “echo test” 命令。
name参数:此参数用于设置计划任务的名称,计划任务的名称会在注释中显示,当不指定计划任务的名称时,ansible 会默认为计划任务加入注释,注释的内容为 #Ansible: None,假设指定计划任务的名称为 test,那么注释的内容为#Ansible: test,在一台机器中,计划任务的名称应该具有唯一性,方便我们以后根据名称修改或删除计划任务。
disabled参数:当计划任务有名称时,我们可以根据名称使对应的任务”失效”(注释掉对应的任务)。注意,使用此参数时,除了需要指定任务的名称,还需要同时指定任务的job 以及任务的时间设定,而且任务的时间设定必须和对应任务完全相同,否则在注释任务的同时,任务的时间设定会被修改,除非你确定这样做。
backup参数:如果此参数的值设置为 yes,那么当修改或者删除对应的计划任务时,会先对计划任务进行备份,然后再对计划任务进行修改或者删除,cron 模块会在远程主机的 /tmp 目录下创建备份文件,以 crontab 开头并且随机加入一些字符,具体的备份文件名称会在返回信息的 backup_file 字段中看到,推荐将此此参数设置为 yes。
service模块
作用:远程主机系统服务管理
service模块常用参数:
。name:此参数用于指定需要操作的服务名称,比如 nginx,httpd。
。 state参数:此参数用于指定服务的状态
I:started(启动)
II:stopped(停止)
III:restarted(重启)
vi:reloaded(平滑重启)
。enabled参数:此参数用于指定是否将服务设置为开机
I:yes(开机自启)
II:no(不开机自启)
例:远程启动Apache服务
[root@ansible ~]# ansible -i /etc/ansible/hosts web-servers -m service -a "name=httpd state=restarted"
user模块
作用:远程主机用户管理
[root@ansible ~]# ansible -i /etc/ansible/hosts web-servers -m user -a "name=xuegod6 state=present"
常用参数:
name参数:必须参数,用于指定要操作的用户名称,可以使用别名 user。
group参数:此参数用于指定用户所在的基本组。
gourps参数:此参数用于指定用户所在的附加组。(附加组之间用逗号隔开)注意,如果说用户已经存在并且已经拥有多个附加组,那么如果想要继续添加新的附加组,需要结合 append 参数使用,否则在默认情况下,当再次使用 groups 参数设置附加组时,用户原来的附加组会被覆盖。
append参数:如果用户原本就存在多个附加组,那么当使用 groups 参数设置附加组时,当前设置会覆盖原来的附加组设置,如果不想覆盖原来的附加组设置,需要结合 append 参数,将 append 设置为 yes,表示追加附加组到现有的附加组设置,append 默认值为 no。
shell参数:此参数用于指定用户的默认 shell。
uid参数:此参数用于指定用户的 uid 号。
expires参数:此参数用于指定用户的过期时间,相当于设置 /etc/shadow 文件中的的第8列,比如,你想要设置用户的过期日期为2018年12月31日,那么你首先要获取到2018年12月31日的 unix 时间戳,使用命令 “date -d 2018-12-31 +%s” 获取到的时间戳为1546185600,所以,当设置 expires=1546185600 时,表示用户的过期时间为2018年12月31日0点0分,设置成功后,查看远程主机的 /etc/shadow 文件,对应用户的第8八列的值将变成17895(表示1970年1月1日到2018年12月31日的天数,unix 时间戳的值会自动转换为天数,我们不用手动的进行换算),目前此参数只支持在 Linux 和 FreeBSD 系统中使用。
comment参数:此参数用于指定用户的注释信息。
state参数:此参数用于指定用户是否存在于远程主机中,可选值有 present、absent,默认值为 present,表示用户需要存在,当设置为 absent 时表示删除用户。
remove参数:(是否删除家目录)当 state 的值设置为 absent 时,表示要删除远程主机中的用户。但是在删除用户时,不会删除用户的家目录等信息,这是因为 remove 参数的默认值为 no,如果设置为yes,在删除用户的同时,会删除用户的家目录。当 state=absent 并且 remove=yes 时,相当于执行 “userdel --remove” 命令。
password参数:(密文加密)此参数用于指定用户的密码。但是这个密码不能是明文的密码,而是一个对明文密码”加密后”的字符串,相当于 /etc/shadow 文件中的密码字段,是一个对明文密码进行哈希后的字符串,你可以在 python 的命令提示符下输入如下命令,生成明文密码对应的加密字符串。
例:
[root@ansible-manager ~]# python Python 2.7.5 (default, Aug 4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import crypt;crypt.crypt('666666') '$6$ziT/sb5KRtUaxoq7$ulfHVLqVgXfmfFUYY7FppzqBQMUYd.2GLDyQwmKv4dYAd0zpgtt5JDheoO/OvvTvY53x9UShX.PtHykJEvsmG0' ansible ansible-demo3 -m user -a ' name=ding password="$6$ziT/sb5KRtUaxoq7$ulfHVLqVgXfmfFUYY7FppzqBQMUYd.2GLDyQwmKv4dYAd0zpgtt5JDheoO/OvvTvY53x9UShX.PtHykJEvsmG0" '
group模块
作用:批量创建用户组
常用参数:
gid:创建的组ID信息
name:创建组名称信息
state:参数
。absent:删除指定的用户组
。present:创建指定的用户组
创建一个指定的用户组 god gid=666
[root@ansible ~]# ansible db_server -m group -a "name=god gid=666"
删除一个指定的组用户god gid=666
[root@ansible ~]# ansible db_server -m group -a "name=god gid=666 state=absent"
备注:无法支持"<",">","|",";","&"等符号
作用:批量进行挂在操作
常用选项:
src:需要挂载的存储设备或文件信息
path:指定目标挂在的目录
fstype:指定挂载是的文件系统类型
state:状态
进行挂载:present / mounted
present:不会实现立即挂载,修改fstab文件,实现开机自动挂载
mounted:会立即实现挂载,并且会修改fstab文件,实现开机自动挂载
进行卸载:absent / umounted
absent:会实现立即卸载,并且会删除fstab信息,禁止开机自动挂载
umounted:会实现立即卸载,但是不会删除fstab文件信息
[root@ansible ~]# ansible db_server -m mount -a " src=172.16.1.31:/data path=/data fstype=nfs state=present"
# 将web服务器挂载到nfs存储服务器/data上面