首页 > 其他分享 >ANSIBLE

ANSIBLE

时间:2024-06-30 20:53:18浏览次数:1  
标签:web name ansible nginx state ANSIBLE root

ANSIBLE

云计算核心职能

  1. 搭建平台架构
  2. 日常运营保障
  3. 性能效率优化

相关工具

  • 代码管理(SCM):GitHub、GitLab、BitBucket、SubVersion
  • 构建工具:maven、Ant、Gradle
  • 自动部署:Capistrano、CodeDeploy
  • 持续集成(CI):Jenkins、Travis
  • 配置管理:Ansible、SaltStack、Chef、Puppet
  • 容器:Docker、Podman、LXC、第三方厂商如AWS
  • 编排:Kubernetes、Core、Apache Mesos
  • 服务注册与发现:Zookeeper、etcd、Consul
  • 脚本语言:python、ruby、shell、go
  • 日志管理:ELK、Logentries
  • 系统监控:Prometheus、Zabbix、Datadog、Graphite、Ganglia、Nagios
  • 性能监控:AppDynamics、New Relic、Splunk
  • 压力测试:JMeter、Blaze Meter、loader.io ab
  • 应用服务器:Tomcat、JBoss、IIS
  • Web服务器:Apache、Nginx
  • 数据库:MySQL、Oracle、PostgreSQL等关系型数据库;mongoDB、redis等NoSQL数据库
  • 项目管理(PM):Jira、Asana、Taiga、Trello、Basecamp、Pivotal Tracker

自动化脚本 , 去写脚本,

批量处理工具,ansible 替代脚本 同一时间下发 给500 台机器 新建 /data

幂等性

1 Ansible 发展史及功能

作者:Michael DeHaan( Cobbler pxe kikstar 与 Func 作者)ansible 的名称来自科幻小说《安德的游戏》中跨越时空的即时通信工具,使用它可以在相距数光年的距离,远程实时控制前线的舰队战斗2012-03-09,发布0.0.1版,2015-10-17,Red Hat宣布1.5亿美元收购。

官网:https://www.ansible.com/
官方文档:https://docs.ansible.com/

1.1Ansible 功能

  • 批量执行远程命令,可以对远程的多台主机同时进行命令的执行
  • 批量安装和配置软件服务,可以对远程的多台主机进行自动化的方式配置和管理各种服务
  • 编排高级的企业级复杂的IT架构任务, Ansible的Playbook和role可以轻松实现大型的IT复杂架构
  • 提供自动化运维工具的开发API, 有很多运维工具,如jumpserver(堡垒机)就是基于 ansible 实现自动化管理功能

1.2 Ansible 特性

  • 模块化:调用特定的模块完成特定任务,支持自定义模块,可使用任何编程语言写模块(账号,软件等)

  • Paramiko(python对ssh的实现),PyYAML,Jinja2(模板语言)三个关键模块

  • 基于Python语言实现

  • 部署简单,基于python和SSH(默认已安装),agentless,无需代理不依赖PKI(无需ssl)

  • 安全,基于OpenSSH

  • 幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况,此特性非绝对

    cp  -r   /etc/      /mnt/etc.bak     
    cp  -r   /etc/      /mnt/etc.bak
    cp  -r   /etc/      /mnt/etc.bak
    
  • 支持playbook编排任务,YAML格式,编排任务,支持丰富的数据结构 剧本演员要按照 系统按照你规定的方式去执行命令

  • 较强大的多层解决方案 role

1.3 Ansible架构

1.3.1 Ansible组成

  • INVENTORY:Ansible管理主机的清单 /etc/anaible/hosts 需要管理的服务清单
  • MODULES:Ansible执行命令的功能模块,多数为内置核心模块,也可自定义
  • PLUGINS:模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用
  • API:供第三方程序调用的应用程序编程接口 应用接口

1.3.2 Ansible 命令执行来源

  • USER 普通用户,即SYSTEM ADMINISTRATOR

  • PLAYBOOKS:任务剧本(任务集),编排定义Ansible任务集的配置文件,由Ansible顺序依次执行,通常是JSON格式的YML文件

  • CMDB(配置管理数据库) API 调用

  • PUBLIC/PRIVATE CLOUD API调用

2.Ansible安装和入门

2.1 安装

########yum源安装###############


yum install epel-release.noarch  -y
yum install ansible -y


[root@node1 yum.repos.d]#vim CentOS-Base.repo 
#加入 epel源
[epel]
name=gn
baseurl=https://mirrors.aliyun.com/epel/$releasever/x86_64
        https://mirrors.cloud.tencent.com/epel/$releasever/x86_64
        https://mirrors.huaweicloud.com/epel/$releasever/x86_64
        https://mirrors.tuna.tsinghua.edu.cn/epel/$releasever/x86_64
gpgcheck=0


[root@node1 yum.repos.d]#yum info  ansible
已加载插件:fastestmirror, langpacks
base                                                                                | 3.6 kB  00:00:00     
epeel                                                                               | 4.7 kB  00:00:00     
extras                                                                              | 2.9 kB  00:00:00     
updates                                                                             | 2.9 kB  00:00:00     
(1/3): epeel/7/group_gz                                                             |  96 kB  00:00:00     
(2/3): epeel/7/updateinfo                                                           | 1.0 MB  00:00:00     
(3/3): epeel/7/primary_db                                                           | 7.0 MB  00:00:04     
Loading mirror speeds from cached hostfile
 * base: mirrors.163.com
 * epeel: mirrors.aliyun.com
 * extras: mirrors.163.com
 * updates: mirrors.163.com
可安装的软件包
名称    :ansible
架构    :noarch
版本    :2.9.25
发布    :1.el7
大小    :17 M
源    :epeel/7
简介    : SSH-based configuration management, deployment, and task execution system
网址    :http://ansible.com
协议    : GPLv3+
描述    : Ansible is a radically simple model-driven configuration management,
         : multi-node deployment, and remote task execution system. Ansible works
         : over SSH and does not require any software or daemons to be installed
         : on remote nodes. Extension modules can be written in any language and
         : are transferred to managed machines automatically.



[root@node1 yum.repos.d]#yum install ansible -y
......................省略..................................
已安装:
  ansible.noarch 0:2.9.25-1.el7                                                                            

作为依赖被安装:
  PyYAML.x86_64 0:3.10-11.el7                          libyaml.x86_64 0:0.1.4-11.el7_0                    
  python-babel.noarch 0:0.9.6-8.el7                    python-jinja2.noarch 0:2.7.2-4.el7                 
  python-markupsafe.x86_64 0:0.11-10.el7               python-paramiko.noarch 0:2.1.1-9.el7               
  python2-httplib2.noarch 0:0.18.1-3.el7               python2-jmespath.noarch 0:0.9.4-2.el7              

完毕!



#############编译安装#########################

yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto
wget https://releases.ansible.com/ansible/ansible-1.5.4.tar.gz
tar xf ansible-1.5.4.tar.gz
cd ansible-1.5.4
python setup.py build
python setup.py install
mkdir /etc/ansible
cp -r examples/* /etc/ansible


###############Git方式#######################
yum install git
git clone git://github.com/ansible/ansible.git --recursive
cd ./ansible
source ./hacking/env-setup

2.2相关文件

  • /etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性,也可以在项目的目录中创建此文件,当前目录下如果也有ansible.cfg,则此文件优先生效,建议每个项目目录下,创建独有的ansible.cfg文件 不用修改

  • /etc/ansible/hosts 主机清单, 放 了被管理主机列表

  • /etc/ansible/roles/ 存放角色的目录

2.3 ansible 主配置文件

Ansible 的配置文件可以放在多个不同地方,优先级从高到低顺序如下

ANSIBLE_CONFIG #环境变量,注意此项用 ansible --version 看不到,但可以生效
./ansible.cfg   #当前目录下的ansible.cfg
~/.ansible.cfg #当前用户家目录下的.ansible.cfg
/etc/ansible/ansible.cfg  #系统默认配置文件



可以使用 来查看
[root@node1 yum.repos.d]#ansible --version

Ansible 的默认配置文件 /etc/ansible/ansible.cfg ,其中大部分的配置内容无需进行修改

[defaults]
#inventory     = /etc/ansible/hosts 	#主机列表配置文件
#library = /usr/share/my_modules/ 		#库文件存放目录
#remote_tmp = $HOME/.ansible/tmp 		#临时py命令文件存放在远程主机目录
#local_tmp     = $HOME/.ansible/tmp 	#本机的临时命令执行目录
#forks         = 5   					#默认并发数
#sudo_user     = root 					#默认sudo 用户
#ask_sudo_pass = True 					#每次执行ansible命令是否询问ssh密码
#ask_pass     = True   
#remote_port   = 22
#host_key_checking = False     			#检查对应服务器的host_key,建议取消此行注释,实现第一次连接自动信任目标主机
#log_path=/var/log/ansible.log 			#日志文件,建议启用
#module_name = command   		、mod		#默认模块,可以修改为shell模块
[privilege_escalation] 					#普通用户提权配置
#become=True
#become_method=sudo
#become_user=root
#become_ask_pass=False

2.4 inventory 主机清单文件

ansible的主要功能用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory 主机清单文件中填写

官方文档:

https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html  

默认的inventory file 位置在:

/etc/ansible/hosts

参数详细说明

ansible_ssh_host 
#将要连接的远程主机名.与你想要设定的主机的别名不同的话,可通过此变量设置.
ansible_ssh_port 
#ssh端口号.如果不是默认的端口号,通过此变量设置.这种可以使用 ip:端口
192.168.1.100:2222

ansible_ssh_user 
#默认的 ssh 用户名

ansible_ssh_pass 
#ssh 密码(这种方式并不安全,我们强烈建议使用 --ask-pass 或 SSH 密钥)

ansible_sudo_pass 
#sudo 密码(这种方式并不安全,我们强烈建议使用 --ask-sudo-pass)

ansible_sudo_exe (new in version 1.8)
#sudo 命令路径(适用于1.8及以上版本)

ansible_connection 
#与主机的连接类型.比如:local, ssh 或者 paramiko. Ansible 1.2 以前默认使用 paramiko.1.2 以后默认使用 'smart','smart' 方式会根据是否支持 ControlPersist, 来判断'ssh' 方式是否可行.

ansible_ssh_private_key_file
#ssh 使用的私钥文件.适用于有多个密钥,而你不想使用 SSH 代理的情况.

ansible_shell_type 
#目标系统的shell类型.默认情况下,命令的执行使用 'sh' 语法,可设置为'csh' 或 'fish'.

ansible_python_interpreter 
#目标主机的 python 路径.适用于的情况: 系统中有多个 Python, 或者命令路径不是"/usr/bin/python",比如 \*BSD, 或者 /usr/bin/python 不是 2.X 版本的Python.之所以不使用 "/usr/bin/env" 机制,因为这要求远程用户的路径设置正确,且要求 "python" 可执行程序名不可为 python以外的名字(实际有可能名为python26).与ansible_python_interpreter 的工作方式相同,可设定如 ruby 或 perl 的路径....

例子:

[web]                        
192.168.91.101:666
#可以指定ssh端口非默认的端口
192.168.91.102


[server]
192.168.91.[100:105]
#指定连续的主机

[ky15]
node[1:5]  
#指定连续的主机



[server:ky15]
server
ky15
#可以嵌套组



[local]
192.168.91.100 ansible_connection=local
#指定本地连接,无需ssh配置


#ansible_connection=ssh 需要StrictHostKeyChecking no
192.168.91.103  ansible_connection=ssh  ansible_ssh_port=2222  ansible_ssh_user=root ansible_ssh_password=123123
10.0.0.6  ansible_connection=ssh  ansible_ssh_user=root ansible_ssh_password=123123
还可以指定用户身份  端口号 和密码



#执行ansible命令时显示别名,如web01
[websrvs]
node2 
node3

[websrvs]
ansible_ssh_password=123123




例子:

[root@node1 ansible]#vim hosts 
[local]
192.168.91.100 ansible_connection=local

[web]
192.168.91.101
192.168.91.102

[accp]
192.168.91.103
192.168.91.105


[webserver]
192.168.91.[101:103]
192.168.91.105

[web:children]
web
accp

[root@node1 ~]#ansible 192.168.91.105 -m ping
#可以指定   m代表使用模块  ping代表ping模块 命令探测下,需要输入 yes 或no
The authenticity of host '192.168.91.105 (192.168.91.105)' can't be established.
ECDSA key fingerprint is SHA256:ffeaxHUOVaBahhnpmEmFFpdl9iRFkdjKcuko6ISBiic.
ECDSA key fingerprint is MD5:28:cc:f0:39:36:33:b4:68:93:e2:30:d2:d5:78:38:ab.
Are you sure you want to continue connecting (yes/no)?

[root@node1 ~]#ansible accp -m ping
#指定 之前清单中的主机组   需要输入 yes 或no,但是只有一次机会,只能
The authenticity of host '192.168.91.105 (192.168.91.105)' can't be established.
ECDSA key fingerprint is SHA256:ffeaxHUOVaBahhnpmEmFFpdl9iRFkdjKcuko6ISBiic.
ECDSA key fingerprint is MD5:28:cc:f0:39:36:33:b4:68:93:e2:30:d2:d5:78:38:ab.
Are you sure you want to continue connecting (yes/no)? The authenticity of host '192.168.91.103 (192.168.91.103)' can't be established.
ECDSA key fingerprint is SHA256:+SWP6YETV3W/XC8Q6dJ0D6y9kCEWR5y1xRnl/gpIIwY.
ECDSA key fingerprint is MD5:c5:b1:f0:07:cc:df:6e:0e:b5:65:52:6f:d6:6d:76:c5.
Are you sure you want to continue connecting (yes/no)? 

[root@localhost .ssh]#ansible acpp -m ping
#输入yes后
The authenticity of host '192.168.91.101 (192.168.91.101)' can't be established.
ECDSA key fingerprint is SHA256:jAdnvemeML+z00Zmk/SL5PWDVEvJqwPFID3iae+Xf4g.
ECDSA key fingerprint is MD5:f7:0e:02:3a:06:8c:71:0b:a2:b8:94:15:0f:0e:55:29.
Are you sure you want to continue connecting (yes/no)? The authenticity of host '192.168.91.102 (192.168.91.102)' can't be established.
ECDSA key fingerprint is SHA256:Sp14x5f9tQ76+x6Tsg0LSfRBqCbu6iAroJFMoWIfDwc.
ECDSA key fingerprint is MD5:91:19:be:cc:6d:ae:3c:e5:f5:9b:04:08:63:12:34:69.
Are you sure you want to continue connecting (yes/no)? yes
192.168.91.101 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: Warning: Permanently added '192.168.91.101' (ECDSA) to the list of known hosts.\r\nAuthentication failed.", 
    "unreachable": true
}









[root@node1 ~]#ansible accp -m ping -k
#-k 输入密码 只有一次机会,如果密码不同无法一起管理,建议ssh免密 ,
SSH password: 
192.168.91.105 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.91.103 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}









ansible 默认使用 ssh 连接
所以管理前要免密登录
[root@node1 ~]#vim /etc/ssh/ssh_config 
#   StrictHostKeyChecking ask
#   修改35行 StrictHostKeyChecking  no


[root@node1 ~]#vim /etc/ansible/ansible.cfg 
71 #host_key_checking = False
开启71行的ansible的不验证即可


运维

2.5 Ansible 相关工具

  • /usr/bin/ansible 主程序,临时命令执行工具
  • /usr/bin/ansible-doc 查看配置文档,模块功能查看工具,相当于man ansible-doc -l |grep 关键字 具体模块名字
  • /usr/bin/ansible-playbook 定制自动化任务,编排剧本工具,相当于脚本
  • /usr/bin/ansible-pull 远程执行命令的工具
  • /usr/bin/ansible-vault 文件加密工具
  • /usr/bin/ansible-console 基于Console界面与用户交互的执行工具
  • /usr/bin/ansible-galaxy 下载/上传优秀代码或Roles模块的官网平台

2.5.1 ansible

执行临时任务一次性任务

用法

ansible <host-pattern> [-m module_name] [-a args]
命令     主机或者清单中的组 -m 指定模块      -a  执行的任务


ansible    主机     -m 模块   "ansbil模块的语法"


ansible    web    -m  yum  -a  "name=httpd   state=lastest"

选项

--version 					#显示版本
-m module   				#指定模块,默认为command
-v 							#详细过程 -vv -vvv更详细
--list-hosts 				#显示主机列表,可简写 --list
-C, --check   				#检查,并不执行
-T, --timeout=TIMEOUT 		#执行命令的超时时间,默认10s
-k, --ask-pass     			#提示输入ssh连接密码,默认Key验证 
-u, --user=REMOTE_USER 		#执行远程执行的用户,默认root
-b, --become    			#代替旧版的sudo 切换
--become-user=USERNAME  	#指定sudo的runas用户,默认为root  vim /etc/sudoers 用户权限
-K, --ask-become-pass  		#提示输入sudo时的口令
-f FORKS, --forks FORKS 	#指定并发同时执行ansible任务的主机数

例子:

命令

shell > 特殊 符号

[root@node1 ~]#ansible localhost -m ping
localhost | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}



########  提权操作   ######
[root@centos7 ~]#grep lisi /etc/sudoers
#先在被控制端(目标主机)sudo授权
zhangsan    ALL=(ALL) NOPASSWD: ALL

#以zhangsan的用户连接用户,并利用sudo代表wang执行whoami命令
[root@ansible ~]#ansible 192.168.91.101 -m shell -a 'whoami' -u zhangsan -k -b --become-user=lisi
SSH password: #输入远程主机lisi用户ssh连接密码
10.0.0.8 | CHANGED | rc=0 >>




[root@node1 ~]#ansible 192.168.91.105 -m shell -a 'hostname >/opt/host.txt' -u zhangsan -k -b
SSH password: 
192.168.91.105 | CHANGED | rc=0 >>


ansible    主机    -m  模块    -a  "模块指令"   选项

########################   主机列表   ###########################
##支持通配符
ansible all -m ping
ansible "*" -m ping 
ansible 192.168.91.* -m ping
ansible "srvs" -m ping
ansible "192.168.91.101 192.168.91.102" -m ping



#或关系
[root@node1 ~]#ansible 'web:accp' --list-hosts
  hosts (4):
    192.168.91.101
    192.168.91.102
    192.168.91.103
    192.168.91.105


#并且关系
[root@node1 ~]#ansible "web:&accp" --list-hosts
[WARNING]: No hosts matched, nothing to do
  hosts (0):

#逻辑非
[root@node1 ~]#ansible 'web:!accp' --list-hosts
  hosts (2):
    192.168.91.101
    192.168.91.102


#正则表达式
ansible "websrvs:dbsrvs" -m ping
ansible "~(k|a).*" -m ping
[root@node1 ~]#ansible "~(k|a).*" -m ping

################例子###
ansible 'kube*:etcd:!10.0.0.101' -a reboot && reboot



##并行执行
-f
[root@node1 ~]#ansible all -a "sleep 3" -f1
[root@node1 ~]#ansible all -a "sleep 3" -f4


##ansible命令执行过程
1. 加载自己的配置文件,默认/etc/ansible/ansible.cfg
#[root@node1 ~]#ansible all -a "sleep 100" -f4
#cd /root/.ansible/tmp
2. 加载自己对应的模块文件,如:command
3. 通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件
4. 给文件+x执行
5. 执行并返回结果
6. 删除临时py文件,退出

$HOME 为当前用户的家目录

执行返回结果

  • 绿色:执行成功并且不需要做改变的操作
  • 黄色:执行成功并且对目标主机做变更
  • 红色:执行失败

配置文件中定义了

vim /etc/ansible/ansible.cfg 
[colors]
#highlight = white
#verbose = blue
#warn = bright purple
#error = red
#debug = dark gray
#deprecate = purple
#skip = cyan
#unreachable = red
#ok = green
#changed = yellow
#diff_add = green

2.5.2 ansible-doc

[root@node1 ~]#ansible-doc -l
#查看所有支持的模块
[root@node1 ~]#ansible-doc -l |wc -l
3387
[root@node1 ~]#ansible-doc -l |grep ^ping
ping                                                          Try to connect to host, verify a usable ...
pingdom                                                       Pause/unpause Pingdom alerts   

q

[root@node1 ~]#ansible-doc ping
#该模块的详细信息
[root@node1 ~]#ansible-doc -s ping
#简单模块
[root@node1 ~]#ansible-doc file
#幂等性,安全性,自己写脚本

2.5.3 ansible-console

#此工具可交互执行命令,支持tab,ansible 2.0+新增
提示符格式
执行用户@当前操作的主机组 (当前组的主机数量)[f:并发数]$

常用子命令:
设置并发数: forks n 例如: forks 10
切换组: cd 主机组 例如: cd web
列出当前组主机列表: list
列出所有的内置命令: ?或help


root@all (4)[f:5]$ cd web
root@web (2)[f:5]$ 
root@web (2)[f:5]$ forks 1
root@web (2)[f:1]$ 


[root@node1 ~]#ansible-console
Welcome to the ansible console.
Type help or ? to list commands.

root@all (4)[f:5]$ ping   
#直接使用模块

2.5.4 playbook

此工具用于执行编写好的 playbook 任务
范例
ansible-playbook   -C  hello.yml  
cat hello.yml
---
#hello world yml file
- hosts: websrvs
 remote_user: root
 gather_facts: no
  
 tasks:
    - name: hello world
      command: /usr/bin/wall hello world

2.6 模块

2015年底270多个模块,2016年达到540个,2018年01月12日有1378个模块,2018年07月15日1852个模块,2019年05月25日(ansible 2.7.10)时2080个模块,2020年03月02日有3387个模块虽然模块众多,但最常用的模块也就2,30个而已,针对特定业务只用10几个模块

常用模块帮助文档参考:

https://docs.ansible.com/ansible/2.9/modules/modules_by_category.html
https://docs.ansible.com/ansible/2.9/modules/list_of_all_modules.html


https://docs.ansible.com/ansible/latest/modules/list_of_all_modules.html
https://docs.ansible.com/ansible/latest/modules/modules_by_category.html

默认模块 可以不写

2.6.1 Command 模块

功能:在远程主机执行命令,此为默认模块,可忽略 -m 选项

注意:此命令不支持 $VARNAME < > | ; & 等,可以用shell模块实现 shell 模块是加强版的 命令模块

注意:此模块不具有幂等性

例子:

[root@node1 ~]#ansible web -a 'hostname'
192.168.91.102 | CHANGED | rc=0 >>
localhost.localdomain
192.168.91.101 | CHANGED | rc=0 >>
node2

root@node1 ~]#ansible web -a "touch /opt/ky15.txt"
#此处的  警告是  让你用  file  模块 专业的模块
[WARNING]: Consider using the file module with state=touch rather than running 'touch'.  If you need to
use command because file is insufficient you can add 'warn: false' to this command task or set
'command_warnings=False' in ansible.cfg to get rid of this message.
192.168.91.102 | CHANGED | rc=0 >>

192.168.91.101 | CHANGED | rc=0 >>

[root@node1 ~]#ansible web -a "ls /opt/ky15.txt"
192.168.91.102 | CHANGED | rc=0 >>
/opt/ky15.txt
192.168.91.101 | CHANGED | rc=0 >>
/opt/ky15.txt

[root@node1 ~]#ansible web -a "echo hello > /opt/hello.log"
#不支持一些  重定向等功能
192.168.91.101 | CHANGED | rc=0 >>
hello > /opt/hello.log
192.168.91.102 | CHANGED | rc=0 >>
hello > /opt/hello.log



114 #module_name = command

2.6.1 shell模块

功能:和command相似,用shell执行命令,支持各种符号,比如:*,$, >

注意:此模块不具有幂等性

[root@node1 ~]# ansible web -m shell -a "echo hello > /opt/hello.txt"
#如果没有明确指明文件生成的目录,会默认在家目录下生成
[root@node1 ~]# ansible web -m shell -a "cat /opt/hello.txt"


#修改默认模块
113 # default module name for /usr/bin/ansible
114 module_name = shell

[root@node1 ~]#ansible web -a "echo $PATH"
192.168.91.102 | CHANGED | rc=0 >>
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
192.168.91.101 | CHANGED | rc=0 >>
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

2.6.3 Script模块

功能:在远程主机上运行ansible服务器上的脚本(无需执行权限)

注意:此模块不具有幂等性

范例:

[root@node1 ~]#vim test.sh
#!/bin/bash
hostname
[root@node1 ~]#ansible web -m script -a '/root/test.sh'

2.6.4 copy 模块

功能:从ansible服务器主控端复制文件到远程主机

注意: src=file 如果是没指明路径,则为当前目录或当前目录下的files目录下的file文件

关键字:

src   	代表源文件路径    
dest  	代表文件落地路径   
owner 	属主
group 	属组
mode  	代表权限
backup  如果复制时有同名文件会先备份再复制(源文件要有变动才会有备份)
content

例子:

ansible web -m copy -a "src=/etc/passwd dest=/mnt/ owner=zhangsan mode=700"



ansible web -m copy -a "src=test.sh dest=/mnt/t.sh owner=zhangsan mode=700"


ansible web -m copy -a "src=/root/test.sh dest=/mnt/test2.sh owner=zhangsan mode=600 backup=yes"
#如目标存在,默认覆盖,此处指定先备份 源文件要有变动才会复制操作

ansible web -m copy -a "content='test line1\ntest line2\n' dest=/tmp/test.txt"
#指定内容,直接生成目标文件  
#  test  line1
#  test  line2



ansible web -m copy -a "src=/etc dest=/backup"
ansible web -m copy -a "src=/etc/ dest=/backup"


加/    复制加改名
不加/   连etc一起复制  

etc  	不加  	/   	连etc  一起复制, etc会变成子目录
etc   	加  		/	   	只复制etc下的文件 把etc文件夹改名成 backup

2.6.5 Get_url 模块

功能: 用于将文件从http、https或ftp下载到被管理机节点上

常用参数如下:

  • dest:指明下载文件的存放目录
  • url :指明下载路径
ansible web -m get_url -a "url=https://nginx.org/download/nginx-1.18.0.tar.gz dest=/opt/"

wget https://nginx.org/download/nginx-1.18.0.tar.gz
md5sum nginx-1.18.0.tar.gz
ansible web -m get_url -a 'url=https://nginx.org/download/nginx-1.18.0.tar.gz dest=/opt checksum="md5:3ca4a37931e9fa301964b8ce889da8cb"'



url: 下载文件的URL,支持HTTP,HTTPS或FTP协议
dest:下载到目标路径(绝对路径),如果目标是一个目录,就用服务器上面文件的名称,如果目标设置了名称就用目标设置的名称
owner:指定属主
group:指定属组
mode:指定权限
force:如果yes,dest不是目录,将每次下载文件,如果内容改变,替换文件。如果否,则只有在目标不存在时才会下载该文件

checksum:对目标文件在下载后计算摘要,以确保其完整性
url_username:用于HTTP基本认证的用户名。对于允许空密码的站点,此参数可以不使用`url_password'
url_password:用于HTTP基本认证的密码。如果未指定`url_username'参数,则不会使用`url_password'参数
validate_certs:如果“no”,SSL证书将不会被验证。适用于自签名证书在私有网站上使用
timeout: URL请求的超时时间,秒为单位


wget https://nginx.org/download/nginx-1.18.0.tar.gz

ansible web -m get_url -a 'url=https://nginx.org/download/nginx-1.18.0.tar.gz dest=/opt'



##可以检测文件是否有问题
[root@node1 ~]#md5sum nginx-1.18.0.tar.gz 
3ca4a37931e9fa301964b8ce889da8cb  nginx-1.8.0.tar.gz


ansible web -m get_url -a 'url=https://nginx.org/download/nginx-1.18.0.tar.gz dest=/opt checksum="md5:3ca4a37931e9fa301964b8ce889da8cb"'

#####   checksum 后面不要忘记 加 md5: ###

2.6.6 Fetch 模块

功能:从远程主机提取文件至ansible的主控端,copy相反,目前不支持目录

范例:

[root@localhost data]#ansible web -m fetch -a 'src=/etc/passwd dest=/mnt'
[root@node1 ~]#ansible web -m fetch -a 'src=/var/log/messages dest=/mnt'
[root@node1 mnt]#tree
.
├── 192.168.91.101
│   └── var
│       └── log
│           └── messages
└── 192.168.91.102
    └── var
        └── log
            └── messages

6 directories, 2 files

2.6.7 File模块

功能:设置文件属性,创建软链接等

path   	指定文件路径
state  	文件状态 有:新建(touch) 删除(absent) 文件夹(directory)  连接文件(link)等
src    	源文件   建立连接文件时 使用    
mode   	权限
owner  	属主
group  	属组
recurse	递归 修改属性时有效

范例:

ansible web -m file -a 'path=/mnt/web.txt state=touch owner=zhangsan group=zhangsan mode=755'
#创建空文件
ansible web -m file -a 'path=/mnt/web state=directory'
#新建目录
ansible web -m file -a 'src=/mnt/web path=/opt/web-link state=link'
#新建软连接 path|dest|name   这三个选项都可以使用
ansible web -m file -a 'path=/opt/web-link state=absent'
#删除文件


ansible all -m file -a "path=/data/mysql state=directory owner=mysql group=mysql"
ansible all -m file -a "path=/data/mysql state=directory owner=mysql group=mysql recurse=yes"
#递归修改目录及子目录的属性

2.6.8 stat模块

功能:检查文件或文件系统的状态

注意:对于Windows目标,请改用win_stat模块

选项

path:文件/对象的完整路径(必须)

常用的返回值判断:

exists: 判断是否存在
isuid: 调用用户的ID与所有者ID是否匹配
ansible web -m stat -a 'path=/mnt/test.txt'
#查看是否存在
192.168.91.102 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "gid": 0, 
    "group": "root", 
    "mode": "0755", 
    "owner": "root", 
    "path": "/opt/mysql", 
    "secontext": "unconfined_u:object_r:usr_t:s0", 
    "size": 18, 
    "state": "directory", 
    "uid": 0
}

2.6.9 unarchive 模块

功能:解包解压缩

实现有两种用法:

1、将ansible主机上的压缩包传到远程主机后解压缩至特定目录,设置copy=yes,此为默认值,可省略

2、将远程主机上的某个压缩包解压缩到指定路径下,设置copy=no

常见参数:

copy:默认为yes,当copy=yes,拷贝的文件是从ansible主机复制到远程主机上,如果设置为copy=no,会在远程主机上寻找src源文件
remote_src:和copy功能一样且互斥,yes表示在远程主机,不在ansible主机,no表示文件在ansible主机上
src:源路径,可以是ansible主机上的路径,也可以是远程主机(被管理端或者第三方主机)上的路径,如果是远程主机上的路径,则需要设置copy=no
dest:远程主机上的目标路径
mode:设置解压缩后的文件权限



ansible web -m get_url -a 'url=https://nginx.org/download/nginx-1.18.0.tar.gz dest=/data  copy=yes' 
ansible web -m unarchive  -a 'src=/data/nginx-1.18.0.tar.gz  dest=/mnt'

web
192.168.91.101
192.168.91.102  









ansible web -m unarchive -a 'src=/data/ky.tar.bz2 dest=/mnt  copy=yes'
#把本机的 压缩  加压到远程主机



ansible websrvs -m unarchive -a 'src=https://nginx.org/download/nginx-1.18.0.tar.gz dest=/usr/local/src/ copy=no'
# copy=no  代表压缩文件不是去本机上查找   去远端服务器查找

2.6.10 Archive模块

功能:打包压缩保存在被管理节点

对远端机器 进行 压缩

范例:

ansible web -m archive -a "path=/var/log/ dest=/data/log.tar.bz2 format=bz2 owner=zhangsan mode=0600"


2.6.11 Hostname模块

功能:管理主机名

ansible 192.168.91.102 -m hostname -a 'name=node3 '
#一般不使用此模块,主机名会一致

2.6.12 Cron 模块

功能:计划任务

支持时间:minute,hour,day,month,weekday

关键字:

name  会生成一行注释,显示标题如下显示
job   执行的命令

范例:

ansible 192.168.91.101 -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql" job=/root/mysql_backup.sh'
#创建任务

ansible web -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql" job=/root/mysql_backup.sh'

ansible 192.168.91.101 -m cron -a 'hour=*/2 minute=30 weekday=1-5 name="backup mysql" job=/root/mysql_backup.sh   disabled=yes'
ansible 192.168.91.101 -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql" job=/root/mysql_backup.sh   disabled=no'




#删除任务
ansible websrvs -m cron -a "name='backup mysql' state=absent"
ansible websrvs -m cron -a 'state=absent name=Synctime'

2.6.13 Yum和 Apt 模块

功能:yum 管理软件包,只支持RHEL,CentOS,fedora,不支持Ubuntu其它版本apt 模块管理 Debian 相关版本的软件包

关键字:

name参数:必须参数,用于指定需要管理的软件包  安装latest present   卸载  absent
state参数:用于指定软件包的状态 ,默认值为。present,表示确保软件包已经安装,除了。present,其他可用值有 installed、							  latest、absent、removed,其中 installed 与present 等效,latest 表示安装 yum 中最新的版本,absent 和 removed 等效,表示删除对应的软件包。
disable_gpg_check参数:用于禁用对 rpm 包的公钥 gpg 验证。默认值为 no,表示不禁用验证,设置为 yes 表示禁用验证,即不验证包,直接安装。在对应的 yum 源没有开启 gpg 验证的情况下,需要将此参数的值设置为 yes,否则会报错而无法进行安装。
enablerepo参数:用于指定安装软件包时临时启用的 yum 源。假如你想要从A源中安装软件,但是你不确定A源是否启用了,你可以在安装软件包时将此参数的值设置为 yes,即使A源的设置是未启用,也可以在安装软件包时临时启用A源。
disablerepo参数:用于指定安装软件包时临时禁用的 yum 源。某些场景下需要此参数,比如,当多个 yum 源中同时存在要安装的软件包时,你可以使用此参数临时禁用某个源,这样设置后,在安装软件包时则不会从对应的源中选择安装包。enablerepo 参数和 disablerepo 参数可以同时使用


name			   所安装的包的名称
state              present--->安装, latest--->安装最新的, absent---> 卸载软件。
update_cache       强制更新yum的缓存
conf_file          指定远程yum安装时所依赖的配置文件(安装本地已有的包)。
disable_pgp_check  是否禁止GPG checking,只用于presentor latest。
disablerepo        临时禁止使用yum库。 只用于安装或更新时。
enablerepo         临时使用的yum库。只用于安装或更新时

范例:

ansible web -m yum -a 'name=httpd state=present'  #安装
ansible web -m yum -a 'name=nginx state=present enablerepo=epel'  #启用epel源
进行安装
ansible websrvs -m yum -a 'name=* state=lastest exclude=kernel*,foo*' #升级除
kernel和foo开头以外的所有包
ansible websrvs -m yum -a 'name=httpd state=absent'   #删除



ansible 192.168.91.101 -m yum -a "name=tree"

2.6.14 yum_repository 模块

功能:建立yum仓库模块

关键字:

name参数:			必须参数,用于指定要操作的唯一的仓库ID,也就是”.repo”配置文件中每个仓库对应的”中括号”内的仓库ID。
baseurl参数:		此参数用于设置 yum 仓库的 baseurl。
description参数:	此参数用于设置仓库的注释信息,也就是”.repo”配置文件中每个仓库对应的”name字段”对应的内容。
file参数:			此参数用于设置仓库的配置文件名称,即设置”.repo”配置文件的文件名前缀,在不使用此参数的情况下,默认以 name 参数的仓库ID作					  为”.repo”配置文件的文件名前缀,同一个”.repo” 配置文件中 可以存在多个 yum 源。
enabled参数:		此参数用于设置是否激活对应的 yum 源,此参数默认值为 yes,表示启用对应的 yum 源,设置为 no 表示不启用对应的 yum 源。
gpgcheck参数:		此参数用于设置是否开启 rpm 包验证功能,默认值为 no,表示不启用包验证,设置为 yes 表示开启包验证功能。
gpgcakey参数:		当 gpgcheck 参数设置为 yes 时,需要使用此参数指定验证包所需的公钥。
state参数:		默认值为 present,当值设置为 absent 时,表示删除对应的 yum 源。

例子:

新建
ansible web -m yum_repository -a 'name=epel description=epel  baseurl=https://download.fedoraproject.org/pub/epel/$releasever/$basearch/ gpgcheck=no file=epel'


删除
ansible web -m yum_repository -a 'name=epel description=epel  baseurl=https://download.fedoraproject.org/pub/epel/$releasever/$basearch/ gpgcheck=no file=epel  state=absent'



- name: Add multiple repositories into the same file (1/2)
 yum_repository:
   name: epel
   description: EPEL YUM repo
   file: external_repos
   baseurl: https://download.fedoraproject.org/pub/epel/$releasever/$basearch/
   
   
   


2.6.15 Service 模块

功能:管理服务 启动 关闭 重启 reload 开机自启

关键字:

name参数:		此参数用于指定需要操作的服务名称,比如 nginx。
state参数:	此参数用于指定服务的状态,比如,我们想要启动远程主机中的 nginx,则可以将 state 的值设置为 started;如果想要停止远程主机中的服			   务,则可以将 state 的值设置为 stopped。此参数的可用值有 started、stopped、restarted、reloaded。
enabled参数:	此参数用于指定是否将服务设置为开机 启动项,设置为 yes 表示将对应服务设置为开机启动,设置为 no 表示不会开机启动。

管理服务例子:

ansible web -m yum -a 'name=httpd  state=present'
ansible web -m service -a 'name=httpd  state=started enabled=yes'





ansible all -m service -a 'name=httpd state=started enabled=yes'
ansible all -m service -a 'name=httpd state=stopped'
ansible all -m service -a 'name=httpd state=reloaded'
ansible all -m shell -a "sed -i 's/^Listen 80/Listen 8080/' /etc/httpd/conf/httpd.conf"
ansible all -m service -a 'name=httpd state=restarted'


ansible 192.168.91.101 -m service -a 'name=httpd state=started enabled=yes'

2.6.16 mount 挂载和卸载

功能: 挂载和卸载文件系统

范例

#临时挂载
ansible websrvs -m mount -a 'src="UUID=b3e48f45-f933-4c8e-a700-22a159ec9077" path=/home fstype=xfs opts=noatime state=present'
#临时取消挂载
ansible websrvs -m mount -a 'path=/home fstype=xfs opts=noatime state=unmounted'
#永久挂载
ansible websrvs -m mount -a 'src=10.0.0.8:/data/wordpress path=/var/www/html/wp-content/uploads opts="_netdev" state=mounted'
#永久卸载
ansible websrvs -m mount -a 'src=10.0.0.8:/data/wordpress path=/var/www/html/wp-content/uploads state=absent'


ansible web -m mount -a "src=/dev/sr0 path=/mnt state=present  fstype=iso9660"


ansible web -m mount -a "src=/dev/sr0 path=/mnt state=mounted fstype=iso9660"
#永久挂载  光盘
ansible web -m mount -a "src=/dev/sr0 path=/mnt state=absent"
##永久卸载


2.6.17 User 模块

功能:管理用户

comment         用户的描述信息
createhome      是否创建家目录
force           在使用state=absent时, 行为与userdel –force一致.
group           指定基本组
groups          指定附加组,如果指定为(groups=)表示删除所有组
home            指定用户家目录
move_home       如果设置为home=时, 试图将用户主目录移动到指定的目录
name            指定用户名
non_unique      该选项允许改变非唯一的用户ID值
password        指定用户密码,使用 SHA512 hash
remove          在使用state=absent时, 行为是与userdel –remove一致
shell           指定默认shell
state           设置帐号状态,不指定为创建,指定值为absent表示删除
system          当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户
uid             指定用户的uid
update_ password 
  always      如果password参数设置的值与用户当前的加密过的密码字符串不一致,则直接更新用户的密码,默认值即为always
  on_create   如果password参数设置的值与用户当前的加密过的密码字符串不一致,则不会更新用户的密码字符串,保持之前的密码设定

范例

#创建用户
ansible all -m user -a 'name=user1 comment="test user" uid=2048 home=/app/user1 group=root‘



nsible web  -m user  -a 'name=user3  createhome=no  group=root  system=yes shell=/bin/nologin'

#删除用户
ansible all -m user -a 'name=user1 state=absent‘

2.6.18Group 模块

功能:管理组

范例

#创建组
ansible websrvs -m group  -a 'name=nginx gid=88 system=yes'
#删除组
ansible websrvs -m group  -a 'name=nginx state=absent'

2.6.19reboot模块

[root@ansible ~]#ansible websrvs -m reboot

sed

2.6.20 Lineinfile 模块

ansible在使用sed进行替换时,经常会遇到需要转义的问题,而且ansible在遇到特殊符号进行替换时,存在问题,无法正常进行替换 。其实在ansible自身提供了两个模块:lineinfile模块和replace模块,可以方便的进行替换一般在ansible当中去修改某个文件的单行进行替换的时候需要使用lineinfile模块

regexp参数 :使用正则表达式匹配对应的行,当替换文本时,如果有多行文本都能被匹配,则只有最后面被匹配到的那行文本才会被替换,当删除文本时,如果有多行文本都能被匹配,这么这些行都会被删除。

如果想进行多行匹配进行替换需要使用replace模块

功能:相当于sed,可以修改文件内容

关键字:

path	        指定要操作的文件
regexp	        使用正则表达式匹配对应的行
line	        修改为新的内容
insertafter	    将文本插入到“指定的行”之后
insertbefore	将文本插入到“指定的行”之前
state	        删除对应的文本时,需要state=absent
backrefs	    1.支持后向引用、2.当未匹配到内容则不操作文件
backup	        是否在修改文件之前对文件进行备份
create	        当要操作的文件并不存在时,是否创建对应的文件

范例:

ansible web -m lineinfile -a "path=/etc/httpd/conf/httpd.conf regexp='^Listen' line='Listen 80'"

ansible all -m   lineinfile -a "path=/etc/selinux/config regexp='^SELINUX=' line='SELINUX=disabled'"

ansible all -m lineinfile  -a 'dest=/etc/fstab state=absent regexp="^#"'

2.6.21replace 模块

该模块有点类似于sed命令,主要也是基于正则进行匹配和替换,建议使用

ansible all -m replace -a "path=/etc/fstab regexp='^(UUID.*)' replace='#\1'"  

ansible all -m replace -a "path=/etc/fstab regexp='^#(UUID.*)' replace='\1'"


ansible web -m replace -a "path=/etc/httpd/conf/httpd.conf regexp='^Listen.*' replace='Listen 80'"

2.6.22 setup模块

功能: setup 模块来收集主机的系统信息,这些 facts 信息可以直接以变量的形式使用,但是如果主机较多,会影响执行速度可以使用 gather_facts: no 来禁止 Ansible 收集 facts 信息

范例:

ansible all -m setup
ansible all -m setup -a "filter=ansible_nodename"
ansible all -m setup -a "filter=ansible_hostname"
ansible all -m setup -a "filter=ansible_domain"
ansible all -m setup -a "filter=ansible_memtotal_mb"
ansible all -m setup -a "filter=ansible_memory_mb"
ansible all -m setup -a "filter=ansible_memfree_mb"
ansible all -m setup -a "filter=ansible_os_family"
ansible all -m setup -a "filter=ansible_distribution_major_version"
ansible all -m setup -a "filter=ansible_distribution_version"
ansible all -m setup -a "filter=ansible_processor_vcpus"
ansible all -m setup -a "filter=ansible_all_ipv4_addresses"
ansible all -m setup -a "filter=ansible_architecture"
ansible all -m setup -a "filter=ansible_uptime_seconds"
ansible all -m setup -a "filter=ansible_processor*"
ansible all -m setup -a 'filter=ansible_env'

3 Playbook

建议修改vim配置

vim   ~/.vimrc
set ai
set ts=2

三种常见的数据格式

  • XML:Extensible Markup Language,可扩展标记语言,可用于数据交换和配置
  • JSON:JavaScript Object Notation, JavaScript 对象表记法,主要用来数据交换或配置,不支持注释
  • YAML:YAML Ain't Markup Language YAML 不是一种标记语言, 主要用来配置,大小写敏感,不支持tab

3.1 playbook 特点

  • playbook 剧本是由一个或多个"play"组成的列表
  • play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的任务角色。Task实际是调用ansible的一个module,将多个play组织在一个playbook中,即可以让它们联合起来,按事先编排的机制执行预定义的动作
  • Playbook 文件是采用YAML语言编写的

3.2 YAML 语言介绍

YAML:YAML Ain't Markup Language,即YAML不是标记语言。不过,在开发的这种语言时,YAML的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)

YAML是一个可读性高的用来表达资料序列的格式。YAML参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822等。Clark Evans在2001年在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者,目前很多最新的软件比较流行采用此格式的文件存放配置信息,如:ubuntu,anisble,docker,kubernetes等

YAML 官方网站:http://www.yaml.org

ansible 官网: https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html

3.2.1YAML 语言特性

  • YAML的可读性好
  • YAML和脚本语言的交互性好
  • YAML使用实现语言的数据类型
  • YAML有一个一致的信息模型
  • YAML易于实现
  • YAML可以基于流来处理
  • YAML表达能力强,扩展性好

3.2.2YAML语法简介

  • 在单一文件第一行,用连续三个连字号"-" 开始,还有选择性的连续三个点号( ... )用来表示文件的结尾
  • 次行开始正常写Playbook的内容,一般建议写明该Playbook的功能
  • 使用#号注释代码
  • 缩进必须是统一的,不能空格和tab混用
  • 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的
  • YAML文件内容是区别大小写的,key/value的值均需大小写敏感
  • 多个key/value可同行写也可换行写,同行使用,分隔
  • key后面冒号要加一个空格 比如: key: value
  • value可是个字符串,也可是另一个列表
  • YAML文件扩展名通常为yml或yaml

3.2.3支持的数据类型

  • YAML 支持以下常用几种数据类型:
  • 标量:单个的、不可再分的值
  • 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
  • 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
3.2.4.1 scalar标量

key对应value

name: wang

使用缩进的方式

name: 
 wang

标量是最基本的,不可再分的值,包括:

  • 字符串
  • 布尔值
  • 整数
  • 浮点数
  • Null
  • 时间
  • 日期
3.2.4.2 Dictionary 字典

字典由多个key与value构成,key和value之间用 :分隔, 并且 : 后面有一个空格,所有k/v可以放在一
行,或者每个 k/v 分别放在不同行
格式

account: { name: wang, age: 30 }

使用缩进方式

account: 
 name: wang
 age: 30

例子:

#不同行
# An employee record
name: Example Developer
job: Developer
skill: Elite(社会精英)



#同一行,也可以将key:value放置于{}中进行表示,用,分隔多个key:value
# An employee record
{name: "Example Developer", job: "Developer", skill: "Elite"}
3.2.4.2 List列表

列表由多个元素组成,每个元素放在不同行,且元素前均使用"-"打头,并且 - 后有一个空格, 或者将所

有元素用 [ ] 括起来放在同一行

course:
 - linux
 - golang
 - python

也可以使用[ ]

course: [ linux , golang , python ]

数据里面也可以包含对象

course:
 - linux: manjaro
 - golang: gin
 - python: django

范例:

#不同行,行以-开头,后面有一个空格
# A list of tasty fruits
- Apple
- Orange
- Strawberry
- Mango
#同一行
[Apple,Orange,Strawberry,Mango]

范例:YAML 表示一个家庭

name: John Smith
age: 41
gender: Male
spouse:
 name: Jane Smith
 age: 37
 gender: Female
children:
 - name: Jimmy Smith
   age: 17
   gender: Male
 - {name: Jenny Smith, age: 13, gender: Female}
 - {name: hao Smith, age: 20, gender: Male }  

3.3Playbook 核心组件

一个playbook 中由多个组件组成,其中所用到的常见组件类型如下:

  • Hosts 执行的远程主机列表
  • Tasks 任务集,由多个task的元素组成的列表实现,每个task是一个字典,一个完整的代码块功能需最少元素需包括 name 和 task,一个name只能包括一个task
  • Variables 内置变量或自定义变量在playbook中调用
  • Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
  • Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
  • tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断

tips

ansible-doc yum
#查看模块 用ansible-doc  加上 模块名  可以查看模块的使用方法和例子

3.3.1 host 组件

Hosts: playbook 中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts用 于指定要执行指定任务的主机,须事先定义在主机清单中

one.example.com one.example.com:two.example.com 192.168.1.50
192.168.1.*
Websrvs:dbsrvs	#或者,两个组的并集W
ebsrvs:&dbsrvs	#与,两个组的交集
webservers:!dbsrvs	#在websrvs组,但不在dbsrvs组

案例

- hosts: websrvs:appsrvs

3.3.2 remote_user 组件

remote_user: 可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户

- hosts: websrvs 
  remote_user: zhangsan                    
  
  tasks:
    - name: test connection 
      ping:
      remote_user: wang
      sudo: yes
      #默认sudo为root
      sudo_user:wang
      #sudo为wang

3.3.3 task列表和action组件

play的主体部分是task list,task list中有一个或多个task,各个task 按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个task后,再开始第二个task

task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。 如果未提供name,则action的结果将用于输出。

task两种格式:

action: module arguments	
#示例: action: shell wall hello

module: arguments	
#示例: shell: wall hello

注意:shell和command模块后面跟命令,而非key=value 

案例第一个yml 文件 发送广播

#This  is  a play book 

- hosts: web
  remote_user: root

  tasks:
    - name: ping
      ping:
    - name: wall
      shell: wall hello

第二个案例

---
# first yaml file
- hosts: web
  remote_user: root
  gather_facts: no	#不收集系统信息,提高执行效率

  tasks:
    - name: test network connection 
      ping:
    - name: excute command 
      command: wall "hello world!"
     

案例 安装 httpd 再启动服务

#This  is  a play book 

- hosts: web
  remote_user: root

  tasks:
    - name: ping
      ping:
    - name: wall
      shell: wall hello

- hosts: db

  tasks:
    - name: install httpd
      yum: name=httpd
    - name: start service
      service: name=httpd state=started  enabled=yes

案例 新建mysql用户

---
- hosts: web

  tasks:
  - name: create user
    user: name=test uid=2000  shell=/sbin/nologin  system=yes create_home=no

3.3.4 gather_facts

收集信息

gather_facts: no

表示不收集信息, 但是使用变量时需要收集

2 安装httpd并启动

---
- hosts: websrvs 
  remote_user: root
  gather_facts: no
  
  tasks:
    -name: install httpd 
     yum: name=httpd
    -name: start httpd
     service: name=httpd state=started enabled=yes



---
- hosts: websrvs 
  remote_user: root
  gather_facts: no
  
  tasks:
    -name: install httpd 
     yum: name=httpd
    -name: start httpd
     service: 
       name:httpd 
       state:started 
       enabled:yes

案例3安装nginx并启动

---
- hosts: web

  tasks:
  - name: Add repository
    yum_repository:
      name: epel
      description: EPEL YUM repo
      baseurl: https://download.fedoraproject.org/pub/epel/$releasever/$basearch/
      gpgcheck: no

  - name: install nginx
    yum: name=nginx  state=present
  - name: config file
    copy: src=/data/nginx.conf   dest=/etc/nginx/nginx.conf
  - name: web page
    copy: src=/data/index.html  dest=/usr/share/nginx/html/index.html
  - name: start nginx
    service: name=nginx state=started enabled=yes

案例4 停止服务,并卸载nginx

---
- hosts: web
  
  tasks:
  - name: stop nginx
    service: name=nginx state=stopped
  - name: remove nginx
    yum: name=nginx  state=absent

3.3. 5 Handlers notify

Handlers本质是task list ,类似于MySQL中的触发器触发的行为,其中的task与前述的task并没有本质上的不同,主要用于当关注的资源发生变化时,才会采取一定的操作。而Notify对应的action可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作

注意:

  • 如果多个task通知了相同的handlers, 此handlers仅会在所有tasks结束后运行一 次。
  • 只有notify对应的task发生改变了才会通知handlers, 没有改变则不会触发handlers
  • handlers 是在所有前面的tasks都成功执行才会执行,如果前面任何一个task失败,会导致handler跳过执行,可以使用force_handlers: yes 强制执行handler

例子: 安装nginx

---
- hosts: web
  gather_facts: no

  tasks:
    - name: add group
      group: name=nginx state=present
    - name: add user
      user: name=nginx state=present group=nginx
    - name: web page
      copy: src=/etc/yum.repos.d/epel.repo  dest=/etc/yum.repos.d
    - name: install nginx
      yum: name=epel-release.noarch
      yum: name=nginx  state=present
    - name: config  file
      copy: src=/data/nginx.conf  dest=/etc/nginx/
      notify:
        - restart nginx
    - name: web page
      copy: src=/data/index.html  dest=/usr/share/nginx/html
    - name: start nginx
      service: name=nginx state=started  enabled=yes
  
  handlers:
    - name: restart nginx
      service: name=nginx state=restarted
   -  name:   stop  nginx
      service: name=nginx state=restarted 

3.3.6 ignore_errors

如果一个task出错,默认将不会继续执行后续的其它task

利用 ignore_errors: yes 可以忽略此task的错误,继续向下执行playbook其它task

[root@ansible ansible]#cat test_ignore.yml
---
- hosts: websrvs
  
 tasks:
   - name: error
     command: /bin/false
     ignore_errors: yes
   - name: continue
     command: wall continue

3.3.7第一个 yml文件

---
#第一个playbook

- hosts: web
  
  tasks:
    - name: ping
      ping:
    - name: wall
      shell: wall hello

######辅助设置################
[root@localhost ~]#vim .vimrc 
set ai ts=2 sw=2
####################################


##########################检查语法#####################################################
[root@localhost data]#ansible-playbook --help |grep check
 #检查语法
                        [--skip-tags SKIP_TAGS] [-C] [--syntax-check] [-D]
  --syntax-check        perform a syntax check on the playbook, but do not
  -C, --check           don't make any changes; instead, try to predict some
                        differences in those files; works great with --check

ansible-playbook --syntax-check f.yml 
ansible-playbook -C f.yml 
####################################################################################


############            运行             #####################

[root@localhost data]#ansible-playbook f.yml
#加playbook 




---
#第一个playbook

- hosts: web
  gather_facts: no #收集信息,当不使用时可以不收集加快速度
  
  tasks:
    - name: ping
      ping:
    - name: wall
      shell: wall hello


- hosts: cloud

  tasks:
    - name: install httpd
      yum:
        name: httpd
    - name: start httpd
      service:
        name: httpd
        state: started
        enabled: yes




编译安装nginx

cd /opt
wget  http://nginx.org/download/nginx-1.18.0.tar.gz  

---
- hosts:  web
  gather_facts:  no


  tasks: 
    - name:  install  packages
      yum: 
        name:  
          - gcc 
          - pcre-devel 
          - openssl-devel 
          - zlib-devel 
          - openssl  
          - openssl-devel
        state:  present   
    - name:  unarchive
      unarchive: src=/opt/nginx-1.18.0.tar.gz  dest=/opt
    - name:  bianyi
      command: ./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
      args:
        chdir: /opt/nginx-1.18.0

    - name:   make
      command: make
      args:
        chdir: /opt/nginx-1.18.0
    
    - name:   make  install
      command: make  install
      args:
        chdir: /opt/nginx-1.18.0

    - name: cpoy  service
      copy:  src=/usr/lib/systemd/system/nginx.service    dest=/usr/lib/systemd/system/nginx.service
    
    - name:   reload
      command: systemctl  daemon-reload
    
    - name: link
      shell:  ln -s  /apps/nginx/sbin/nginx   /usr/bin       
      

    - name:  start  nginx
      service:  name=nginx  state=started  enabled=yes
    
    - name:  web page
      copy:  src=/data/index.html    dest=/usr/share/nginx/html

一键编译安装 mysql 5.7


3.4playbook 命令

ansible-playbook <filename.yml> ... [options]

--syntax-check      #语法检查,可缩写成--syntax, 相当于bash -n 
-C --check #模拟执行,只检测可能会发生的改变,但不真正执行操作,dry run 
--list-hosts    #列出运行任务的主机
--list-tags #列出tag
--list-tasks #列出task
--limit 主机列表 #只针对主机列表中的特定主机执行  --limit  主机地址
-i INVENTORY        #指定主机清单文件,通常一个项对应一个主机清单文件
--start-at-task START_AT_TASK #从指定task开始执行,而非从头开始,START_AT_TASK为任务的name
-v -vv  -vvv #显示过程
[root@localhost ~]#vim .vimrc 
set ai ts=2 sw=2
其中ai:自动换行;ts:tab的字符长度;sw:空格的长度    1 yum安装httpd   2 service 开启服务   3 copy 传一个 主页文件过去  4能访问
---
# this is a test file

- hosts: kg         
  remote_user: root
  gather_facts: no   
  
  tasks:
    - name: ping
      ping:
    - name: test
      shell: wall hello

#创建用户
- hosts: accp
  gather_facts: no

  tasks:
    - name: create user
      user:
        name: mysql
        shell: /sbin/nologin
        system: yes
        create_home: no






[root@localhost ~]#ansible-playbook --help
[root@localhost ~]#ansible-playbook --syntax-check hello.yml 
#语法检查

playbook: hello.yml
[root@localhost ~]#ansible-playbook -C hello.yml
- hosts: accp

  tasks:
    - name: install httpd
      yum: name=httpd
    - name: start httpd
      service: name=httpd state=started enabled=yes


- hosts: web
  tasks:
    - name: install httpd
      yum:
        name: httpd
    - name: config file
      copy:
        src: files/index.html
        dest: /var/www/html
    - name: start httpd
      service:
        name: httpd
        state: started
        enabled: yes
    - name: stop firewalld
      service:
        name: firewalld
        state: stopped
        enabled: no


ansible all -m yum -a 'name=httpd state=absent'
#卸载httpd






- hosts: web
  remote_user: root
  gather_facts: no

  tasks:
    - name: add group nginx
      group:
        name: nginx
        state: present
    - name: add user nginx
      user:
        name: nginx
        state: present
        group: nginx
    - name: Install Nginx
      yum:
        name: nginx
        state: present
    - name: web page
      copy:
        src: files/index.html
        dest: /usr/share/nginx/html/index.html
    - name: Start Nginx
      service:
        name: nginx
        state: started
        enabled: yes

3.5 tags 标签

在playbook文件中,可以利用tags组件,为特定 task 指定标签,当在执行playbook时,可以只执行特定tags的task,而非整个playbook文件

tags: [ test1,test2 ]  # 写在一行

tags:
  - test1
  - test2 

案例:

vim httpd.yml
---
# tags example
- hosts: websrvs
 remote_user: root
 gather_facts: no
  
 tasks:
    - name: Install httpd
     yum: name=httpd state=present
    - name: Install configure file
     copy: src=files/httpd.conf dest=/etc/httpd/conf/
     tags: conf
    - name: start httpd service
     tags: service
      service: name=httpd state=started enabled=yes
      
      
[root@ansible ~]#ansible-playbook –t conf,service httpd.yml

3.6 指定清单文集 hosts

[root@localhost data]#ansible-playbook  --list-hosts    install_nginx.yml 

playbook: install_nginx.yml

  play #1 (web): web	TAGS: []
    pattern: [u'web']
    hosts (2):
      192.168.91.102
      192.168.91.101
[root@localhost data]#ansible-playbook  --list-hosts    install_nginx.yml  -i hosts 

playbook: install_nginx.yml

  play #1 (web): web	TAGS: []
    pattern: [u'web']
    hosts (3):
      192.168.91.102
      192.168.91.103
      192.168.91.101

3.7 Playbook中使用变量

变量名:仅能由字母、数字和下划线组成,且只能以字母开头

变量定义:

variable=value
例子:
http_port=80

变量调用方式:

通过{{ variable_name }} 调用变量,且变量名前后建议加空格,有时用"{{ variable_name }}"才生效

变量来源:

  1. ansible 的 setup facts 远程主机的所有变量都可直接调用

  2. 通过命令行指定变量,优先级最高

ansible-playbook -e varname=value test.yml

3.7.1 使用setup模块中变量

本模块自动在playbook调用,不要用ansible命令调用,生成的系统状态信息, 并存放在facts变量中

facts 包括的信息很多,如: 主机名,IP,CPU,内存,网卡等

facts 变量的实际使用场景案例

  • 通过facts变量获取被控端CPU的个数信息,从而生成不同的Nginx配置文件
  • 通过facts变量获取被控端内存大小信息,从而生成不同的memcached的配置文件
  • 通过facts变量获取被控端主机名称信息,从而生成不同的Zabbix配置文件

案例:使用setup变量

  • 查看所有变量
[root@localhost data]#ansible  localhost  -m setup
localhost | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.122.1", 
            "192.168.91.100"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80::fe7:ca03:81f:2887"
        ], 
        "ansible_apparmor": {
            "status": "disabled"
        }, 
        "ansible_architecture": "x86_64", 
        "ansible_bios_date": "07/29/2019", 
.............................................
  • 查看 本机的内存大小
[root@localhost data]#ansible  localhost  -m setup  -a "filter=ansible_memtotal_mb"
localhost | SUCCESS => {
    "ansible_facts": {
        "ansible_memtotal_mb": 1823
    }, 
    "changed": false
}

  • 查看本机的主版本号
[root@localhost data]#ansible localhost -m setup -a "filter=ansible_distribution_major_version"
localhost | SUCCESS => {
    "ansible_facts": {
        "ansible_distribution_major_version": "7"
    }, 
    "changed": false
}

  • 查看cpu核数
[root@localhost data]#ansible 192.168.91.101 -m setup -a "filter=ansible_processor_vcpus"
192.168.91.101 | SUCCESS => {
    "ansible_facts": {
        "ansible_processor_vcpus": 2, 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}

  • 利用setup 模块中的变量生成日志文件
---
- hosts:  web
  remote_user: root
  gather_facts: yes


  tasks:
    - name: create log file
      file: name=/data/{{ ansible_nodename }}.log state=touch owner=zhangsan mode=600


#ansible_nodename
  • 显示 es33 网卡的 IP 地址
---
- hosts:  web
  remote_user: root
  gather_facts: yes


  tasks:
    - name: create log file
      debug:
        msg: IP address {{ ansible_ens33.ipv4.address }}
        #msg: IP address {{ ansible_facts["ens33"]["ipv4"]["address"] }}
        #msg: IP address {{ ansible_facts.ens33.ipv4.address }}
        #msg: IP address {{ ansible_default_ipv4.address }}
        #msg: IP address {{ ansible_ens33.ipv4.address }}
        #msg: IP address {{ ansible_ens33.ipv4.address.split('.')[-1] }} #取IP中的最后一个数字

3.7.2 在playbook 命令行中定义变量

"{{ 变量名 }}"

使用 ansible-playbook -e 选项

例子: 在使用命令时定义变量

vim  test2.yml

---
- hosts: websrvs
 remote_user: root
 tasks:
   - name: install package
     yum: name={{ pkname }} state=present
     


ansible-playbook   -e  pkname=httpd  var2.yml
     

新建用户

---
- hosts: web
  gather_facts: no


  tasks:
    - name: create  user
      user: name={{ myname }}   system=yes  create_home=no
    - name: create  user
      user: name={{ myname1 }}   system=yes  create_home=no


ansible-playbook   -e  myname=cxk  -e myname1=wyf  playbook名字

3.7.3 定义变量文件

例子:

[root@localhost data]#vim var
# 定义变量  pkname1  pkname2
pkname1: tree
pkname2: telnet


vim   test1.yml
---
- hosts: web
  gather_facts: no
  
  tasks:
    - name: install  {{pkname1}}
      yum:  name={{pkname1}}  state=present
    - name: install {{pkname2}}
      yum: name={{pkname2}}  state=present

[root@localhost data]#ansible-playbook -e "@var"  test1.yml 
#  @代表文件    var 即是文件名

3.7.4直接在 playbook 文件 中建立变量

例子:

使用 vars组件

---
- hosts: web
  vars:
    username: test1
    groupname: group1


  tasks:
    - name: create group
      group: name={{ groupname }}  state=present
    - name: create user
      user: name={{ username }} state=present

例子: 安装多个软件包

- hosts: web 
  vars:
    web: httpd
    db: mariadb-server
    
  tasks:
    - name: install {{ web }} {{ db }}
     yum:
       name:
          - "{{ web }}"
          - "{{ db }}"
       state: latest  

例子: 变量之间的互相调用

---
- hosts: web
  vars:
    collect_info: "/data/test/{{ansible_default_ipv4['address']}}/"

  tasks:
    - name: create ip  directory
      file: name="{{collect_info}}"  state=directory





---
- hosts: webs
 vars: 
   suffix: "txt"
   file: "{{ ansible_nodename }}.{{suffix}}"
  
 tasks:
    - name: test var
     file: path="/data/{{file}}" state=touch

3.7.5 使用独立的变量文件

可以在一个独立的playbook文件中定义变量,在另一个playbook文件中引用变量文件中的变量,比playbook中定义的变量优化级高

#先写一个变量文件
vim vars.yml
---
# variables file
package_name: mariadb-server
service_name: mariadb







#调用这个文件
vim var5.yml
---
#install package and start service
- hosts: dbsrvs
 remote_user: root
 vars_files:
    - vars.yml
    
tasks:
    - name: install package
     yum: name={{ package_name }}
     tags: install
    - name: start service
      service: name={{ service_name }} state=started enabled=yes

3.7.6 针对主机和主机组的变量

3.7.6.1 在主机清单中针对所有项目的主机和主机分组的变量所有项目的主机变量

在inventory 主机清单文件中为指定的主机定义变量以便于在playbook中使用

[websrvs]
www1.kgc.com http_port=80   maxRequestsPerChild=808
www2.kgc.com http_port=8080 maxRequestsPerChild=909
#只是针对单个主机

所有项目的组(公共)变量

在inventory 主机清单文件中赋予给指定组内所有主机上的在playbook中可用的变量,如果和主机变是同名,优先级低于主机变量

范例:

[websrvs:vars]
http_port=80
ntp_server=ntp.kgc.com
nfs_server=nfs.kgc.com
======================================
######################################
[all:vars]
# --------- Main Variables ---------------
# Cluster container-runtime supported: docker, containerd
CONTAINER_RUNTIME="docker"
# Network plugins supported: calico, flannel, kube-router, cilium, kube-ovn
CLUSTER_NETWORK="calico"
# Service proxy mode of kube-proxy: 'iptables' or 'ipvs'
PROXY_MODE="ipvs"
# K8S Service CIDR, not overlap with node(host) networking
SERVICE_CIDR="192.168.0.0/16"
# Cluster CIDR (Pod CIDR), not overlap with node(host) networking
CLUSTER_CIDR="172.16.0.0/16"
# NodePort Range
NODE_PORT_RANGE="20000-60000"
# Cluster DNS Domain
CLUSTER_DNS_DOMAIN="magedu.local."

例子:

[root@localhost data]#vim /etc/ansible/hosts 
[web]
192.168.91.101   hname=www1   domain=accp.com
192.168.91.102   hname=www2


[web:vars]
mark="-"

[all:vars]
domain=www.kgc.com


[root@localhost data]#ansible web -m hostname  -a 'name={{ hname }}{{ mark }}{{ domain }}'
192.168.91.102 | CHANGED => {
    "ansible_facts": {
        "ansible_domain": "sollutium.com", 
        "ansible_fqdn": "dedicated.sollutium.com", 
        "ansible_hostname": "www2-kgc", 
        "ansible_nodename": "www2-kgc.com", 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "name": "www2-kgc.com"
}
192.168.91.101 | CHANGED => {
    "ansible_facts": {
        "ansible_domain": "sollutium.com", 
        "ansible_fqdn": "dedicated.sollutium.com", 
        "ansible_hostname": "www1-kgc", 
        "ansible_nodename": "www1-kgc.com", 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "name": "www1-kgc.com"
}

3.8 template 模板技术

模板是一个文本文件,可以做为生成文件的模版,并且模板文件中还可嵌套jinja2语法

Jinja2 是一个现代的,设计者友好的,仿照 Django 模板的 Python 模板语言。 它速度快,被广泛使用,并且提供了可选的沙箱模板执行环境保证安全:

特性:

  • 沙箱中执行
  • 强大的 HTML 自动转义系统保护系统免受 XSS
  • 模板继承
  • 及时编译最优的 python 代码
  • 可选提前编译模板的时间
  • 易于调试。异常的行数直接指向模板中的对应行。
  • 可配置的语法

官方文档

http://jinja.pocoo.org/
https://jinja.palletsprojects.com/en/2.11.x/

官方中文文档

http://docs.jinkan.org/docs/jinja2/
https://www.w3cschool.cn/yshfid/

jinja2 语言支持多种数据类型和操作:

字面量,如: 字符串:使用单引号或双引号,数字:整数,浮点数

列表:[item1, item2, ...]

元组:(item1, item2, ...)

字典:{key1:value1, key2:value2, ...}

布尔型:true/false

算术运算:+, -, *, /, //, %, **

比较操作:==, !=, >, >=, <, <=

逻辑运算:and,or,not

流表达式:For,If,When

字面量:

表达式最简单的形式就是字面量。字面量表示诸如字符串和数值的 Python 对象。如"Hello World"双引号或单引号中间的一切都是字符串。无论何时你需要在模板中使用一个字符串(比如函数调用、过滤器或只是包含或继承一个模板的参数),如42,42.23数值可以为整数和浮点数。如果有小数点,则为浮点数,否则为整数。在 Python 里, 42 和 42.0 是不一样的

算术运算:

Jinja 允许用计算值。支持下面的运算符

+:把两个对象加到一起。通常对象是素质,但是如果两者是字符串或列表,你可以用这 种方式来衔接

它们。无论如何这不是首选的连接字符串的方式!连接字符串见 ~ 运算符。 {{ 1 + 1 }} 等于 2

-:用第一个数减去第二个数。 {{ 3 - 2 }} 等于 1

/:对两个数做除法。返回值会是一个浮点数。 {{ 1 / 2 }} 等于 0.5

//:对两个数做除法,返回整数商。 {{ 20 // 7 }} 等于 2

%:计算整数除法的余数。 {{ 11 % 7 }} 等于 4

*:用右边的数乘左边的操作数。 {{ 2 * 2 }} 会返回 4 。也可以用于重 复一个字符串多次。 {{ '=' * 80 }}

会打印 80 个等号的横条\

**:取左操作数的右操作数次幂。 {{ 2**3 }} 会返回 8

比较操作符

== 比较两个对象是否相等

!= 比较两个对象是否不等

> 如果左边大于右边,返回 true

>= 如果左边大于等于右边,返回 true

< 如果左边小于右边,返回 true

<= 如果左边小于等于右边,返回 true

逻辑运算符

对于 if 语句,在 for 过滤或 if 表达式中,它可以用于联合多个表达式

and 如果左操作数和右操作数同为真,返回 true

or 如果左操作数和右操作数有一个为真,返回 true

not 对一个表达式取反

(expr)表达式组

true / false true 永远是 true ,而 false 始终是 false

3.8.1template

template功能:可以根据和参考模块文件,动态生成相类似的配置文件 template文件必须存放于templates目录下,且命名为 .j2 结尾 yaml/yml 文件需和templates目录平级,目录结构如下示例:

范例:利用template 同步nginx配置文件

#准备templates/nginx.conf.j2文件
mkdir   templates

vim   nginx.conf.j2
worker_processes {{ ansible_processor_vcpus }};
worker_processes {{ ansible_processor_vcpus+1s }};




[root@ansible ~]#vim temnginx.yml
---
- hosts:  web
  gather_facts:  yes


  tasks:
    - name: config file
      tags:  page
      #copy:  src=/data/index.html    dest=/apps/nginx/html 
      template:  src=nginx.conf.j2    dest=/apps/nginx/conf/nginx.conf
      notify:
        - restart nginx


  handlers:
    - name: restart nginx
      service: name=nginx  state=restarted

[root@ansible ~]#ansible-playbook temnginx.yml




#去节点上查看
[root@localhost ~]# pstree -p|grep nginx
           |-nginx(54233)-+-nginx(54234)
           |              |-nginx(54235)
           |              `-nginx(54236)

3.8.2 template中使用流程控制for和 if

template中也可以使用流程控制 for 循环和 if 条件判断,实现动态生成文件功能

3.8.2.1 for循环

格式

{% for i in EXPR %}
 ...
{% endfor %}




示例:
{% for i in range(1,10) %}
 server_name web{{i}};
{% endfor %}

例子1:

vim    templates/for.j2
{% for i in range(1,10) %}
servername {{i}};
{% endfor %}


vim     test.yml
---
- hosts: web

  tasks:
    - name: template
      template: src=for.j2   dest=/data/test.txt



[root@node2 data]#cat test.txt 
servername 1;
servername 2;
servername 3;
servername 4;
servername 5;
servername 6;
servername 7;
servername 8;
servername 9;


例子2 : 生成nginx多虚拟主机

[root@localhost data]#vim templates/for1.j2 
#  准备  j2 文件

{% for vhost in nginx_vhosts %}
server {
   listen {{ vhost }}
}
{% endfor %}




[root@localhost data]#vim  test.yml
# 准备 yml 文件
---
- hosts: web
  vars:
    nginx_vhosts:
      - 81
      - 82
      - 83
  tasks:
    - name: template config
      template: src=for1.j2    dest=/data/test.conf


[root@node2 data]#cat test.conf 
server {
   listen 81
}
server {
   listen 82
}
server {
   listen 83
}

3.9 循环迭代

迭代:当有需要重复性执行的任务时,可以使用迭代机制

3.9.1 迭代with_items(loop)

对迭代项的引用,固定内置变量名为"item"

要在task中使用with_items给定要迭代的元素列表

注意: ansible2.5版本后,可以用loop代替with_items

列表元素格式:

  • 字符串
  • 字典

例子: 批量建立用户

---
- hosts: web
  gather_facts: no

  tasks:
    - name: create user
      user: name={{ item }}  state=present groups=wheel
      with_items:
        - testuser1
        - testuser2
        - testuser3
#注意= 号后不要空格
        
        
 #上面语句的功能等同于下面的语句
    - name: add several users  
      user: name=testuser1 state=present groups=wheel
    - name: add several users
      user: name=testuser2 state=present groups=wheel
    - name: add several users
      user: name=testuser3 state=present groups=wheel

例子: 批量删除文件

---
- hosts: web
  gather_facts: no

  tasks:
    - name: delete  file
      file: path={{ item }}  state=absent
      with_items:
          - /data/file1
          - /data/file2
          - /data/file3

例子:批量安装软件

---
- hosts: web
  gather_facts: no

  tasks:
    - name: install packeages
      yum: name={{ item }}  state=present
      #yum: name=nginx,ftp,memcached
      with_items:
          - vsftpd
          - ftp
          - tree

例子:批量复制文件

---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: copy file
      copy: src={{ item }} dest=/tmp/{{ item }}
      with_items:
        - file1
        - file2
        - file3

3.9.2 迭代嵌套子变量

在迭代中,还可以嵌套子变量,关联多个变量在一起使用

例子: 建立用户

---
- hosts: web
  gather_facts: no



  tasks:
    - name: create group
      group: name={{ item }} state=present
      with_items:
        - nginx
        - mysql
        - tomcat
    - name: create user
      user: name={{ item.user }} group={{ item.group }} uid={{ item.uid }} state=present
      with_items:
        - { user: 'nginx', group: 'nginx' , uid: '80' }
        - { user: 'mysql', group: 'mysql' , uid: '3306' }
        - { user: 'tomcat', group: 'tomcat' , uid: '8080' }

例子: 复制文件

#ansible-doc file
- name: Create two hard links
 file:
   src: '/tmp/{{ item.src }}'
   dest: '{{ item.dest }}'
   state: hard
 loop:
    - { src: x, dest: y }
    - { src: m, dest: n }

例子: 批量修改密码

---
- hosts: ssh-host
  gather_facts: false
  tasks:
    - name: change user passwd
      user: name={{ item.name }} password={{ item.chpass | password_hash('sha512') }}  update_password=always
      with_items:
           - { name: 'root', chpass: '123456' }
           - { name: 'app', chpass: '654321' }

3.10 逐行处理

范例: with_lines 逐行处理

- hosts: localhost
 tasks:
    - debug: msg={{ item }}
     with_lines: ps aux

3.11 playbook使用 when

when语句可以实现条件测试。如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试,通过在task后添加when子句即可使用条件测试,jinja2的语法格式

范例:条件判断

---
- hosts: websrvs
 remote_user: root
 tasks:
   - name: "shutdown RedHat flavored systems"
     command: /sbin/shutdown -h now
     when: ansible_os_family == "RedHat"

例子:

[root@localhost data]#ansible web -m setup -a "filter=ansible_os_family"
192.168.91.102 | SUCCESS => {
    "ansible_facts": {
        "ansible_os_family": "RedHat", 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}
192.168.91.101 | SUCCESS => {
    "ansible_facts": {
        "ansible_os_family": "RedHat", 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}
192.168.91.11 | SUCCESS => {
    "ansible_facts": {
        "ansible_os_family": "Debian", 
        "discovered_interpreter_python": "/usr/bin/python3"
    }, 
    "changed": false
}




---
- hosts: web

  tasks:
    - name: install sl "{{ ansible_os_family }}"
      yum:  name=sl
      when: ansible_os_family == "RedHat"
    - name: install   sl   "{{ ansible_os_family }}"
      apt: name=sl
      when: ansible_os_family == "Debian"

#ansible_os_family

4 role 角色

角色是ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中

运维复杂的场景:建议使用 roles,代码复用度高

roles:多个角色的集合目录, 可以将多个的role,分别放至roles目录下的独立子目录中,如下示例

roles/
    mysql/
    nginx/
    tomcat/
    redis/

默认roles存放路径

/root/.ansible/roles
/usr/share/ansible/roles
/etc/ansible/roles

官方文档:

https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html

4.1 Ansible Roles目录编排

roles目录结构如下所示

每个角色,以特定的层级目录结构进行组织

roles目录结构

playbook1.yml
playbook2.yml
roles/
  project1/
    tasks/
    files/
    vars/       
    templates/
    handlers/
    default/    
    meta/       
  project2/
    tasks/
    files/
    vars/       
    templates/
    handlers/
    default/    
    meta/

Role各目录作用

  • roles/project/ :项目名称,有以下子目录
  • files/ :存放由copy或script模块等调用的文件
  • templates/:template模块查找所需要模板文件的目录
  • tasks/:定义task,role的基本元素,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
  • handlers/:至少应该包含一个名为main.yml的文件;此目录下的其它的文件需要在此文件中通过include进行包含
  • vars/:定义变量,至少应该包含一个名为main.yml的文件;此目录下的其它的变量文件需要在此文件中通过include进行包含
  • meta/:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml的文件,其它文件需在此文件中通过include进行包含
  • default/:设定默认变量时使用此目录中的main.yml文件,比vars的优先级低

4.2 建立role

创建role的步骤

1 创建role的目录结构.在以roles命名的目录下分别创建以各角色名称命名的目录,如mysql等,在每个角色命名的目录中分别创建相关的目录和文件,比如tasks、files、handlers、templates和vars等目录;用不到的目录可以创建为空目录,也可以不创建

2 编写和准备role的功能文件

3 编写playbook文件调用需要的角色应用于指定的主机

针对大型项目使用Roles进行编排

范例: 利用 ansible-galaxy 创建角色目录的结构

[root@localhost roles]#mkdir -pv  /etc/ansible/roles/nginx/{tasks,templates,handlers,files} 
mkdir: 已创建目录 "/etc/ansible/roles/nginx/tasks"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/templates"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/handlers"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/files"
[root@localhost roles]#tree
.
└── nginx
    ├── files
    ├── handlers
    ├── tasks
    └── templates

5 directories, 0 files


[root@localhost nginx]#vim tasks/main.yml
[root@localhost nginx]#cat tasks/main.yml 
- include: group.yml
- include: user.yml
- include: install.yml
- include: config.yml
- include: webpage.yml
- include: service.yml


[root@localhost nginx]#vim tasks/group.yml
- name: groups
  group: name=nginx  state=present


[root@localhost nginx]#vim tasks/user.yml
- name: user
  user: name=nginx  state=present


[root@localhost nginx]#vim tasks/install.yml
- name: install epel
  yum: name=epel-release.noarch  state=present
- name: install nginx
  yum: name=nginx   state=present

[root@localhost nginx]#vim tasks/config.yml
- name: web file
  copy: src=/data/index.html   dest=/usr/share/nginx/html/

[root@localhost nginx]#vim  tasks/service.yml 
- name: start nginx
  service: name=nginx state=started


[root@localhost nginx]#tree
.
├── files
├── handlers
├── tasks
│   ├── config.yml
│   ├── group.yml
│   ├── install.yml
│   ├── main.yml
│   ├── service.yml
│   └── user.yml
└── templates

标签:web,name,ansible,nginx,state,ANSIBLE,root
From: https://www.cnblogs.com/zhj0708/p/18276913

相关文章

  • 自动化部署ansible
    ANSIBLE自动化部署安装ANSIBLE########yum源安装###############[[email protected]]#vimCentOS-Base.repo#加入epel源[epel]name=gnbaseurl=https://mirrors.aliyun.com/epel/$releasever/x86_64https://mirrors.cloud.tencent.com/epel/$releasever/x86_6......
  • Ansible fact变量与魔法变量
    目录fact变量1.1fact变量的引用ansible的魔法变量1.魔法变量的使用1.1魔法变量的实际使用fact变量在常用模块里就提到过setup模块,这个模块会收集被控端的信息,而这个模块收集信息的方式就是依赖于fact,返回的是json格式的数据[ansible@masteransible]$ansibleall-msetup......
  • Ansible的变量
    目录Ansible的变量1.在主机清单中定义1.1定义内置变量1.2定义内置变量使用提权1.3给主机组定义变量1.4定义自定义变量2.通过vars定义变量3.通过vars_files定义变量4.通过host_vars和group_vars定义变量5.注册变量Ansible的变量ansible支持变量,用于存储会在整个项目中重......
  • Ansible playbook
    目录Playbook(剧本)1.yaml1.1yaml的语法规则1.2yaml的数据类型1.3yaml的示例2.ansible-playbook2.1playbook入门2.2执行playbook2.3使用playbook安装软件3.更多示例Playbook(剧本)我们之前执行ansble是通过ad-hoc的方式来执行的,这样执行的好处就是我的任务只有1个的时......
  • Ansible的常用模块
    目录ansible常用模块1.file模块1.1file模块的选项1.2file模块的使用1.2.1使用file模块在远程主机创建文件1.2.2创建目录1.2.3删除文件/目录2.copy模块2.1copy模块的选项2.2copy模块的使用3.yum_repository模块3.1yum_repository的选项3.2yum_repository的使用4.yum......
  • Ansible笔记
    1、Ansible基本介绍Ansible是一个自动化的管理IT资源的工具。1)Ansible基本介绍Ansible功能Ansbile优点Ansible缺点系统环境配置无客户的效率低、易挂起安装仁济推送式持续集成丰富的module热回滚基于YAML的Playbook2)Ansible与其他软件的对比......
  • 10、ansible-YAML-非标记语言-剧本的编写-.yaml -剧本执行ansible-playbook-handlers
     ============================================================剧本的编写==================================================通过YAML编写一个剧本,完成web的部署,配置,启动的全过程1、先将目标主机的网站服务卸载ansibleall-myum-a'name=httpdstate=removed'-o·a......
  • 9、ansible-Ad-Hoc-点对点模式--m shell-shell模块(执行的就是linux命令)
    作用:可以执行任何有效的shell命令,包括管道、重定向和其他shell特性。该模块将在远程主机上启动一个shell,然后在该shell中执行命令。执行结果可以作为任务的输出返回,也可以将其保存到文件或变量中供后续任务使用。请注意,与其他模块相比,shell模块的执行效率较低,因为它需要在......
  • 13、ansible-shell、command、script使用
    command模块简介command模块用于在给的的节点上运行系统命令,比如echohello。它不会通过shell处理命令,因此不支持像$HOME这样的变量和,以及<, >, |, ;和&等都是无效的。也就是在command模块中无法使用管道符。模块参数名称必选备注chdirno运行command命令前......
  • Ansible(ubuntu)
    1.安装Ansiblesudoaptupdatesudoaptinstallansible2.配置ansible主机1.将本机的密钥添加到目标服务器上2.追加公钥echo'$(cat~/.ssh/id_rsa.pub)'>>~/.ssh/authorized_keys远程追加sshusername@remote_host"echo'$(cat~/.ssh/id_rsa.pub)'>>~......