版本:CentOS Linux release 7.9.2009 (Core) ansible 2.9.27 python 2.7.5
Ansible的返回结果非常友好,一般会用三种颜色来表示执行结果:
颜色 | 是否成功 | 说明 |
---|---|---|
绿色 | 成功 | 没有对目标机器做修改 |
橘黄色 | 成功 | 执行后目标机器有状态变化 |
红色 | 失败 | 执行过程出现异常 |
ansible [-h] [--version] [-v] [-b] [--become-method BECOME_METHOD]
[--become-user BECOME_USER] [-K] [-i INVENTORY] [--list-hosts]
[-l SUBSET] [-P POLL_INTERVAL] [-B SECONDS] [-o] [-t TREE] [-k]
[--private-key PRIVATE_KEY_FILE] [-u REMOTE_USER]
[-c CONNECTION] [-T TIMEOUT]
[--ssh-common-args SSH_COMMON_ARGS]
[--sftp-extra-args SFTP_EXTRA_ARGS]
[--scp-extra-args SCP_EXTRA_ARGS]
[--ssh-extra-args SSH_EXTRA_ARGS] [-C] [--syntax-check] [-D]
[-e EXTRA_VARS] [--vault-id VAULT_IDS]
[--ask-vault-pass | --vault-password-file VAULT_PASSWORD_FILES]
[-f FORKS] [-M MODULE_PATH] [--playbook-dir BASEDIR]
[-a MODULE_ARGS] [-m MODULE_NAME]
pattern
-i :指定主机清单,不指定默认是/etc/ansible/hosts;
--list-hosts: 列出指定组里有哪些主机;
-o :简化输出,显示为一行;
-u,--user=REMOTE_USER : 远程执行时受控主机的用户;
-k, --ask-pass :提示输入ssh密码,默认key验证;
-K, --ask-become-pass : 提示输入sudo时的密码口令;
-b,--become:特权方式运行命令;
-T,--timeout=TIMEOUT : 执行命令时的超时时间,默认10s;
-f 10 :指定ansible并行线程数,在高并发场景下可以指定ansible的线程数,可以让ansible执行时启动多个线程发送命令到受控主机从而提高效率。默认是5个线程;
-m: 指定模块,m是module的缩写,不指定模块缺省值默认是command,可以在ansible.cfg配置文件中配置默认模块。
-a:指定模块所要执行的命令,参数等。
-l,--limit: 指只针对某个组的某些主机执行。
演示示例:
ansible -i /etc/ansible/hosts node --list-hosts #查看/etc/ansible/hosts主机清单的node组有哪些主机
ansible all --list-hosts #查看默认主机文件/etc/ansible/hosts主机清单的全部受控主机
ansible -i /etc/ansible/hosts node -u guo -b -k -K -T 20 -m shell -a 'ls -l /root' #-u指定远程执行的用户为guo,-b指定以root特权方式运行命令,-k表示输入ssh登陆密码,-K表示特权方式时输入sudo密码,-T指定命令超时时间,-m指定要使用模块是shell模块,-a指定要运行的命令.
ansible all -m ping --limit 192.168.118.133 #针对全部主机里的192.168.118.133执行
ansible node -m ping -l 192.168.118.133 #针对node组里的192.168.118.133执行
all:表示主机清单所有的主机,如下所示:
ansible -i /etc/ansible/hosts all -m ping #all表示主机清单所有的主机
指定主机清单的某个组,如指定node组,如下所示:
ansible -i /etc/ansible/hosts node -m ping #指定node组
指定主机清单的某个主机IP,如下所示:
ansible -i /etc/ansible/hosts 192.168.118.132 -m ping #指定主机清单里面的192.168.118.132这台受控主机
*使用通配符模糊匹配组,如下所示:
ansible -i /etc/ansible/hosts *web -m ping #模糊匹配带有web后缀的组
或关系,表示在A组或B组中的主机,如下所示:
ansible -i /etc/ansible/hosts 'node:web' -m ping #表示在node组或web组中的主机
ansible '192.168.118.132:192.168.118.133' -m ping #也表示或关系
逻辑与:表示同时在A组和B组中的主机,如下所示:
ansible -i /etc/ansible/hosts 'node:&web' -m ping #同时在node组和web组中的主机
逻辑非:表示在A组,但不在B组中的主机,如下所示:
ansible -i /etc/ansible/hosts 'node:!web' -m ping #同时在node组但不在web组中的主机
ansible -i /etc/ansible/hosts '!web:node' -m ping #同上,表示在node组但不在web组中的主机
综合逻辑:可以把上面的逻辑组合起来形成综合逻辑,如下所示:
ansible -i /etc/ansible/hosts 'web:node:&redis!db:' -m ping #表示在web组或node组同时又在redis组但不在db组中的主机
正则表达式:
ansible -i /etc/ansible/hosts '~(web|node)servers' -m ping #表示匹配以web或node开头servers结尾的组中的主机
作用:主要用于在目标受控主机上创建文件,目录,删除文件等操作。
参数:
path:指定路径,path的别名是dest, name
state:表示状态,absent 删除文件或目录, directory 创建目录, file, hard 创建硬链接, link 创建软链接, touch 创建普通文件,默认是:file
owner:属主
group:属组
mode:设置权限
src:表示创建的是软硬链接时链接到的源文件
#查看file模块帮助文档
ansible-doc file
#创建一个普通文件
ansible -i /etc/ansible/hosts all -m file -a 'path=/root/test.txt state=touch'
#创建一个目录
ansible -i /etc/ansible/hosts all -m file -a 'path=/root/k8s state=directory'
#创建一个可执行文件属组是root,属组也是root,权限是755
ansible -i /etc/ansible/hosts all -m file -a 'path=/root/run.sh state=touch mode=755 owner=root group=root'
#删除文件或目录(会级联删除)
ansible -i /etc/ansible/hosts all -m file -a 'name=/root/k8s state=absent'
作用:主要用于复制ansible主控端的文件到受控端上
#查看copy模块帮助文档
ansible-doc cppy
# src指定源文件,dest指定目标路径
ansible -i /etc/ansible/hosts node -m copy -a 'src=/root/test_file1 dest=/root/'
# src指定源文件,dest指定目标路径,owner group mode等参数可以指定文件属性
ansible -i /etc/ansible/hosts node -m copy -a 'src=/root/test_file2 dest=/root/ owner=root group=fuji mode=755'
# backu=yes 表示当src源文件改变了,目标机器上具有同名文件时,备份同名的目标文件,默认backup=no不备份直接覆盖目标主机上同名文件,备份的文件名会加上年月日时分秒
ansible -i /etc/ansible/hosts node -m copy -a 'src=/root/test_file2 dest=/root/ owner=root group=fuji mode=755 backup=yes'
作用:从远程主机上抓取文件到主控端上。fetch模块功能与copy模块功能整好相反。
#从远程主机上抓取/var/log/messages文件到/root/logs/目录下
# src参数表示远程文件,必须是一个文件,不能是目录;dest是本地目录
ansible all -m fetch -a 'src=/var/log/messages dest=/root/logs/'
#抓取后的文件,其实是用主机地址为目录做了区分,同时被抓取的文件连同绝对路径也一起抓取过来了,如下所示:
[root@master ~]# tree logs/ #查看抓取后的文件
logs/
├── 192.168.118.132 #以远程主机IP为目录做了区分
│ └── var #被抓取的文件连同绝对路径也一起抓取过来
│ └── log #被抓取的文件连同绝对路径也一起抓取过来
│ └── messages #被抓取的文件名
└── 192.168.118.133 #以远程主机IP为目录做了区分
└── var #被抓取的文件连同绝对路径也一起抓取过来
└── log #被抓取的文件连同绝对路径也一起抓取过来
└── messages #被抓取的文件名
6 directories, 2 files
[root@master ~]#
作用:添加、删除Linux的定时计划任务。
参数:
name :指定计划任务的名称;
minute、hour、day、month、weekday:分时日月周,默认是*
job:表示计划任务要执行的命令
state:状态,状态有两种,present表示添加计划任务含义,absent表示删除计划任务;
user:表示计划任务的所属的用户,默认是root;
disabled:disabled=true表示禁用计划任务,disabled=false表示启用计划任务,默认是false表示启用计划任务;
#每十分钟执行
ansible node -m cron -a 'name="sync-date" minute=*/10 user=root job="/usr/sbin/ntpdate ntp1.aliyun.com" state=present'
#每小时执行
ansible node -m cron -a 'name="sync-date" hour=*/1 user=root job="/usr/sbin/ntpdate ntp1.aliyun.com" state=present'
#每天一点执行
ansible node -m cron -a 'name="sync-date" minute=00 hour=1 user=root job="/usr/sbin/ntpdate ntp1.aliyun.com" state=present '
#每周一凌晨两点整执行
ansible node -m cron -a 'name="sync-date" minute=00 hour=2 weekday=1 user=root job="/usr/sbin/ntpdate ntp1.aliyun.com" state=present'
#在远程主机上查看第一条的计划任务
[root@node1 ~]# crontab -l
#Ansible: sync-date
*/10 * * * * /usr/sbin/ntpdate ntp1.aliyun.com
[root@node1 ~]#
# 使用disabled=yes禁用计划任务,必须指明name和job才能唯一标识一个计划任务,user不指定默认就是root
ansible node -m cron -a 'name="sync-date" user=root job="/usr/sbin/ntpdate ntp1.aliyun.com" disabled=yes'
[root@node1 ~]# crontab -l #查看远程主机,计划任务已经被注释掉了
#Ansible: sync-date
#* * * * * /usr/sbin/ntpdate ntp1.aliyun.com
[root@node1 ~]#
# 使用disabled=no重新启用计划任务,必须指明name和job才能唯一标识一个计划任务,user不指定默认就是root
ansible node -m cron -a 'name="sync-date" user=root job="/usr/sbin/ntpdate ntp1.aliyun.com" disabled=no'
[root@node1 ~]# crontab -l #查看远程主机,计划任务已经重启启用了
#Ansible: sync-date
* * * * * /usr/sbin/ntpdate ntp1.aliyun.com
[root@node1 ~]#
#删除计划任务
ansible node -m cron -a 'name="sync-date" user=root job="/usr/sbin/ntpdate ntp1.aliyun.com" state=absent'
作用:主要用于用户信息管理,包括用户创建,密码修改,组等基本操作。
#查看user模块的帮助文档
ansible-doc user
#在所有主机组上创建一个xiaoming用户
ansible -i /etc/ansible/hosts all -m user -a 'name=xiaoming'
#在所有主机组上创建一个xiaoming用户
#如果创建的用户需要密码,则密码需要使用 openssl命令和passwd命令从标准输入中先加密,然后再ansible使用password指定,如下所示:
echo "123456" | openssl passwd -1 -stdin #-1是密码加密的复杂度
$1$v9/AfSPE$Ojk8HUwrbeEQ5jdtw9aYy0
ansible -i /etc/ansible/hosts all -m user -a 'name=xiaoming group=root uid=1009 shell=/usr/bin/bash comment="I am xiaoming,I am new." password="$1$v9/AfSPE$Ojk8HUwrbeEQ5jdtw9aYy0"'
#删除xiaoming用户,家目录也一起删除
ansible -i /etc/ansible/hosts all -m user -a 'name=xiaoming state=absent remove=yes'
作用:yum模块主要用于包管理,如安装、升级、卸载包等操作。
#更新nginx,state参数:present、installed 都可以表示安装,latest 表示更新、removed、absent 表示卸载
ansible -i /etc/ansible/hosts node -m yum -a 'name=nginx state=latest'
#同时安装多个,使用道号隔开
ansible -i /etc/ansible/hosts node -m yum -a 'name=nginx,vsftpd state=present'
#安装本地的包,首先需要把包上传到远程目标主机上才能安装
ansible -i /etc/ansible/hosts node -m copy -a 'src=/root/grafana-8.3.3-1.x86_64.rpm dest=/root/'
ansible -i /etc/ansible/hosts node -m yum -a 'name=/root/grafana-8.3.3-1.x86_64.rpm state=present'
#卸载nginx,同时卸载多个的话也要使用道号隔开
ansible -i /etc/ansible/hosts node -m yum -a 'name=nginx state=absent'
# 仅下载nginx,不安装
ansible -i /etc/ansible/hosts node -m yum -a 'name=nginx download_only=true'
作用:用于管理服务,包括启动服务,停止服务,设置服务开机自启等操作。
#查看service模块的帮助文档
ansible-doc service
#启动nginx服务
#state参数可选值:reloaded 重新加载, restarted 重启, started 启动, stopped 停止
ansible -i /etc/ansible/hosts all -m service -a 'name=nginx state=started'
#停止服务,state=stopped 表示停止
ansible -i /etc/ansible/hosts all -m service -a 'name=nginx state=stopped'
#设置服务开机自启
ansible -i /etc/ansible/hosts all -m service -a 'name=nginx enabled=yes'
#启动ntpd服务,并设置服务开机自启
ansible -i /etc/ansible/hosts all -m service -a 'name=ntpd state=started enabled=yes'
作用:收集指定目标受控主机的基本信息
#查看setup模块帮助文档
ansible-doc setup
#查看基本信息,会输出所有信息
ansible -i /etc/ansible/hosts all -m setup
#查看主机的总内存信息,通过使用 filter 参数过滤
ansible -i /etc/ansible/hosts all -m setup -a 'filter=ansible_memtotal_mb'
作用:command模块用于执行一些简单的命令,command不能识别特殊字符,使用shell模块能识别特殊字符。
#查看command模快帮助文档
ansible-doc command
#查看主机名
ansible -i /etc/ansible/hosts node -m command -a 'hostname'
#查看用户信息,但是由于有管道符,所以会报错,command模块不能识别不了特殊字符
ansible all -m shell -a 'cat /etc/passwd | grep ssh' #报错
作用:shell模块能实现平时Linux全部操作,即shell模块能实现上面所讲的各个模块全部功能。
#查看shell帮助文档
ansible-doc shell
#查看ntpd服务状态
ansible -i /etc/ansible/hosts node -m shell -a 'systemctl status ntpd'
#重启ntpd服务状态
ansible -i /etc/ansible/hosts node -m shell -a 'systemctl restart ntpd'
#查看Linux版本和内核版本
ansible -i /etc/ansible/hosts node -m shell -a 'cat /etc/redhat-release ;uname -a'
#查看系统启动时间和系统负载,以及登陆用户数
ansible -i /etc/ansible/hosts node -m shell -a 'uptime'
ansible-playbook命令常用参数:
--list-hosts :列出剧本的主机
--list-tags :列出剧本的tags
--syntax-check :语法检查,检查剧本的语法有无错误
-l SUBSET, --limit SUBSET :指定主机组里哪些主机执行剧本
-t TAGS, --tags TAGS:只执行指定tags的步骤
palybook特性:
#号表注释
--- 表示文件的开始
区别大小写
一个name只能写一个task,不能一个nginx下写多个task,不然只会应用最后的一个task;
文件名后缀通常是.yaml或.yml
hosts:执行的远程主机列表
tasks:任务集
template:模板
handlers: 与notify结合使用,有特定条件触发执行操作,满足条件执行,不满足不执行。
编写一个playbook剧本,剧本是以yaml格式语法进行编写的,并在ansible服务器上创建一个/root/httpd.conf配置文件,端口是8000,然编写剧本,如下:
[root@master ~]# vim install_httpd.yaml
- hosts: node #指定主机
tasks: #任务
- name: install httpd #名字,可自定义
yum: name=httpd state=present #yum模块,安装httpd服务
- name: copy apache conf file #名字,可自定义
copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf #copy模块,复制httpd.conf去替换远程主机的httpd.conf
- name: start apache running #名字,可自定义
service: name=httpd state=started enabled=yes #service模块,启动httpd服务
#剧本语法检查,没有报错输出说明剧本语法ok
[root@master ~]# ansible-playbook install_httpd.yaml --syntax-check
playbook: install_httpd.yaml
#列出剧本要运行的主机
[root@master ~]# ansible-playbook install_httpd.yaml --list-hosts
playbook: install_httpd.yaml
play #1 (node): node TAGS: []
pattern: [u'node']
hosts (2):
192.168.118.132
192.168.118.133
[root@master ~]#
#执行剧本,没有报错,远程主机上已经运行起来了httpd服务
[root@master ~]# ansible-playbook install_httpd.yaml
[root@master ~]#
[root@node1 local]# lsof -i:8000 #在node1节点上查看,8000端口起来了,说明我们的剧本copy模块复制式成功的
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 53560 root 4u IPv6 1602043 0t0 TCP *:irdmi (LISTEN)
httpd 53561 apache 4u IPv6 1602043 0t0 TCP *:irdmi (LISTEN)
httpd 53562 apache 4u IPv6 1602043 0t0 TCP *:irdmi (LISTEN)
httpd 53563 apache 4u IPv6 1602043 0t0 TCP *:irdmi (LISTEN)
httpd 53564 apache 4u IPv6 1602043 0t0 TCP *:irdmi (LISTEN)
httpd 53565 apache 4u IPv6 1602043 0t0 TCP *:irdmi (LISTEN)
[root@node1 local]#
我们修改本地的/root/httpd.conf文件端口为8111。然后重新执行ansible-playbook install_httpd.yaml,如下:
#修改/root/httpd.conf文件端口为8111,然后重新执行剧本
[root@master ~]# ansible-playbook install_httpd.yaml
[root@node1 local]# lsof -i:8000 #查看远程受控主机上查看,还是之前的8000端口
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 53560 root 4u IPv6 1602043 0t0 TCP *:irdmi (LISTEN)
httpd 53561 apache 4u IPv6 1602043 0t0 TCP *:irdmi (LISTEN)
httpd 53562 apache 4u IPv6 1602043 0t0 TCP *:irdmi (LISTEN)
httpd 53563 apache 4u IPv6 1602043 0t0 TCP *:irdmi (LISTEN)
httpd 53564 apache 4u IPv6 1602043 0t0 TCP *:irdmi (LISTEN)
httpd 53565 apache 4u IPv6 1602043 0t0 TCP *:irdmi (LISTEN)
[root@node1 local]# lsof -i:8111 #没有8111端口
[root@node1 local]# grep 8111 /etc/httpd/
conf/ conf.d/ conf.modules.d/ logs/ modules/ run/
[root@node1 local]# grep 8111 /etc/httpd/conf/httpd.conf #查看配置文件,配置问价已经是8111端口了
Listen 8111
[root@node1 local]#
细心的网友会发现问题所在,我们的剧本中,当文件发生改变了,copy会重新复制httpd.conf文件到远程主机,但是httpd服务并没有重启,如果在剧本后面写上重启httpd视乎是可行的,但是每执行一次剧本都重启一次httpd服务,视乎有点不合理。此时,我们引入一个handlers来监听某个事件然后触发某种操作,如下所示:
[root@master ~]# vim install_httpd.yaml
- hosts: node
tasks:
- name: install httpd
yum: name=httpd state=present
- name: copy apache conf file
copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: restart httpd service #notify定义当copy模块的文件发生了改变时去执行对应名字的handlers,注意,这里的“restart httpd service“要与handlers的name的内容一样,不然对应不上
- name: start apache running
service: name=httpd state=started enabled=yes
handlers: #引入一个handlers
- name: restart httpd service #定义一个name
service: name=httpd state=restarted #操作是,使用service模块,重启httpd服务
[root@master ~]# vim httpd.conf #修改端口为8222
[root@master ~]# ansible-playbook install_httpd.yaml #执行剧本
[root@node1 local]# lsof -i:8222 #查看受控主机,端口8222已经启动了
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 60105 root 4u IPv6 1621895 0t0 TCP *:8222 (LISTEN)
httpd 60106 apache 4u IPv6 1621895 0t0 TCP *:8222 (LISTEN)
httpd 60107 apache 4u IPv6 1621895 0t0 TCP *:8222 (LISTEN)
httpd 60108 apache 4u IPv6 1621895 0t0 TCP *:8222 (LISTEN)
httpd 60109 apache 4u IPv6 1621895 0t0 TCP *:8222 (LISTEN)
httpd 60110 apache 4u IPv6 1621895 0t0 TCP *:8222 (LISTEN)
[root@node1 local]#
tags其实相当于一个标签,在为某个tasks打上一个tags,然后执行剧本时可以指定tags名字,这样就能单独执行tags那行的任务,如下所示:
[root@master ~]# vim install_httpd.yaml
- hosts: node
tasks:
- name: install httpd
yum: name=httpd state=present
- name: copy apache conf file
copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: restart httpd service
- name: start apache running
service: name=httpd state=started enabled=yes
tags: start apache #定义一个名叫start apache的tags
handlers:
- name: restart httpd service
service: name=httpd state=restarted
#列出剧本有哪些tags
ansible-playbook install_httpd.yaml --list-tags
#指定tags执行剧本(假设剧本已经执行过,现在要启动nginx,那么可以指定tags来执行剧本)
ansible-playbook -t "start apache" install_httpd.yaml
注意:可以将一个tags放在不同的task下,这样执行剧本的时候就会执行多个task;同时,执行剧本时指定tag也可以指定多个tags,使用道号间隔即可。
ansible-vault 命令主要用于加密yaml文件,当我们的yaml文件有敏感信息时,可以使用使用ansible-vault命令加密yaml文件,加密过的yaml文件,直接cat vim 看到的会是一串乱码,所以还是要使用ansible-vault 命令进行编辑,查看,解密等操作。
注意:加密后的yaml文件,需要解密后才能正常执行。
常用参数:
encrypt :加密文件
{create,decrypt,edit,view,encrypt,encrypt_string,rekey}
create 创建一个加密的yaml文件
decrypt 解密一个加密文件
edit 编辑加密文件
view 查看加密文件
encrypt 加密一个yaml文件
encrypt_string 加密一个字符串
rekey Re-key a vault encrypted file
#创建一个秘文,创建的时候需要输入密码,然后ansible就直接打开文件可以写剧本了
ansible-vault create vault.yml
#解密一个加密过的文件,需要输入正确密码才能解密
ansible-vault decrypt vault.yml
#加密install_httpd.yaml文件,加密后的文件就变成了密文,vim打开看到的是一串乱码
ansible-vault encrypt install_httpd.yaml
#rekey更换口令密码
ansible-vault rekey install_httpd.yaml
#解密加密install_httpd.yaml ,加密后的文件就变成了密文,vim打开看到的是一串乱码
ansible-vault encrypt install_httpd.yaml
#查看加密后的文件,只能这样看,cat install_httpd.yaml 看还是乱码
ansible-vault view install_httpd.yaml
#编辑加密文件,只能这样编辑,vim install_httpd.yaml 看的话会显示一串乱码
ansible-vault edit install_httpd.yaml
剧本中可以定义变量,变量的定义使用 vars定义,变量的引用使用{{ variable }},中间有空格,如下所示:
[root@master ansbile]# cat install_soft.yaml
- hosts: node
vars: #定义变量,及其赋值
- pkname1: httpd #定义了一个pkname1变量,并赋值httpd
- pkname2: vsftpd #定义了一个pkname2变量,并赋值vsftpd
tasks:
- name: install httpd
yum: name={{ pkname1 }} state=present #定义一个pkname1变量
- name: install vsftpd
yum: name={{ pkname2 }} state=present #定义一个pkname2变量
- name: start httpd
service: name=httpd state=started enabled=yes
- name: start vsftpd
service: name=vsftpd state=started enabled=yes
[root@master ansbile]#
#如果基本里面没有定义变量,也没有给变量赋值,那么可以在命令行使用-e参数给变量赋值,如下:
ansible-playbook -e 'pkname1=httpd,pkname2=vsftpd' install_soft.yaml