运维自动化工具之Ansible
发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,1 安装和入门1.1 ansible安装# ansible的安装方式有多种,比如编译安装、git方式和pip安装等,这里使用yum方式安装,此种方式需要现有epel源[root@ansible ~]#
千家信息网最后更新 2025年01月31日运维自动化工具之Ansible
1 安装和入门
1.1 ansible安装
# ansible的安装方式有多种,比如编译安装、git方式和pip安装等,这里使用yum方式安装,此种方式需要现有epel源[root@ansible ~]#yum install epel-release -y[root@ansible ~]#yum install ansible -y
1.2 确认安装
[root@ansible ~]#ansible --versionansible 2.9.1 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, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
1.3 ansible相关文件
1.3.1 配置文件
- /etc/ansible/ansible.cfg 主配置文件,配置ansible的工作特性
- /etc/ansible/hosts 主机清单
- /etc/ansible/roles/ 存放角色的目录
1.3.2 ansible主配置文件说明
[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 #默认模块,可以修改为shell模块
1.3.3 inventory主机清单说明
- ansible的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名
- 默认的inventory file为/etc/ansible/hosts
- inventory file可以有多个,且也可以通过Dynamic Inventory来动态生成
1.3.4 主机清单文件格式
- inventory文件遵循INI文件风格,中括号中的字符为组名。可以将同一个主机同时归并到多个不同的组中
- 如果目标主机使用非默认的SSH端口,还可以在主机名称之后使用冒号加端口号的格式来标明
- 如果主机名称遵循相似的命名模式,还可以使用列表的方式标识各主机
【范例】:
ntp.aliyun.com[webservers]www1.abc.com:2222www2.abc.com[dbservers]db1.abc.comdb2.abc.com[websrvs]www[1:100].example.com[dbsrvs]db-[a:f].example.com[appsrvs]10.0.0.[1:100]
1.4 ansible相关工具
- /usr/bin/ansible #主程序,临时命令执行工具
- /usr/bin/ansible-doc #查看配置文档,模块功能查看工具
- /usr/bin/ansible-galaxy #下载/上传优秀代码或Roles模块的官网平台
- /usr/bin/ansible-playbook #定制自动化任务,编排剧本工具
- /usr/bin/ansible-pull #远程执行命令的工具
- /usr/bin/ansible-vault #文件加密工具
- /usr/bin/ansible-console #基于Console界面与用户交互的执行工具
利用ansible实现管理的主要方式
- Ad-Hoc 即利用ansible命令,主要用于临时命令使用场景
- Ansible-playbook 主要用于长期规划好的,大型项目的场景,需要有前期的规划过程
1.4.1 ansible-doc
功能:用来显示各模块的帮助信息
语法:
ansible-doc [options] [module...]-l, --list #列出可用模块-s, --snippet #显示指定模块的playbook片段
【范例】:
#列出所有模块ansible-doc -l#查看指定模块帮助用法ansible-doc ping#查看指定模块帮助用法ansible-doc -s ping
1.4.2 ansible
功能:通过ssh协议,实现对远程主机的配置管理、应用部署、任务执行等功能,建议使用前配置好key验证
语法:
ansible [-m module_name] [-a args]
选项说明:
--version #显示版本-m module #指定模块,默认为command-v #详细过程 -vv -vvv更详细--list-hosts #显示主机列表,可简写 --list-k, --ask-pass #提示输入ssh连接密码,默认Key验证-C, --check #检查,并不执行-T, --timeout=TIMEOUT #执行命令的超时时间,默认10s-u, --user=REMOTE_USER #执行远程执行的用户-b, --become #代替旧版的sudo 切换--become-user=USERNAME #指定sudo的runas用户,默认为root-K, --ask-become-pass #提示输入sudo时的口令
1.4.2.1 ansible的host-pattern
用于匹配被控制的主机的列表All :表示所有Inventory中的所有主机
【范例】:
# allansible all -m ping# *:通配符ansible "*" -m pingansible 192.168.1.* -m ping# 或关系ansible "websrvs:appsrvs" -m pingansible "192.168.1.1:192.168.1.2" -m ping# 逻辑与#在websrvs组并且在dbsrvs组中的主机ansible "websrvs:&dbsrvs" -m ping#逻辑非#在websrvs组,但不在dbsrvs组中的主机#注意:此处为单引号ansible 'websrvs:!dbsrvs' -m ping#综合逻辑ansible 'websrvs:dbsrvs:&appsrvs:!ftpsrvs' -m ping#正则表达式ansible "websrvs:&dbsrvs" -m pingansible "~(web|db).*\.abc\.com" -m ping
1.4.2.2 ansible命令执行过程
1.加载自己的配置文件 默认/etc/ansible/ansible.cfg2.加载自己对应的模块文件,如:command3.通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件4.给文件+x执行5.执行并返回结果6. 删除临时py文件,退出
1.4.2.3 ansible的执行状态
[root@ansible ~]#grep -A 14 '\[colors\]' /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#diff_remove = red#diff_lines = cyan绿色:执行成功并且不需要做改变的操作黄色:执行成功并且对目标主机做变更红色:执行失败
1.4.2.4 ansible使用范例
#以zhangsan用户执行ping存活检测ansible all -m ping -u zhangsan -k#以zhangsan sudo至root执行ping存活检测ansible all -m ping -u zhangsan -k -b#以zhangsan sudo至lisi用户执行ping存活检测ansible all -m ping -u zhangsan -k -b --become-user=lisi#以zhangsan sudo至root用户执行lsansible all -m command -u zhangsan -a 'ls /root' -b --become-user=root -k -K
1.4.3 ansible-galaxy
功能:连接https://galaxy.ansible.com 下载相应的roles
【范例】:
#列出所有已安装的galaxyansible-galaxy list#安装galaxyansible-galaxy install geerlingguy.redis#删除galaxyansible-galaxy remove geerlingguy.redis
1.4.4 ansible-pull
功能:推送ansible的命令至远程,效率无限提升,对运维要求较高
1.4.5 ansible-playbook
功能:具用于执行编写好的playbook任务
【范例】:
ansible-playbook hello.ymlcat hello.yml---# hello world yml file- hosts: websrvs remote_user: root tasks: - name: hello world command: /usr/bin/wall hello world
1.4.6 ansible-vault
功能:用于加解密yml文件
语法:
ansible-vault [create|decrypt|edit|encrypt|rekey|view]
【范例】:
ansible-vault encrypt hello.yml #加密ansible-vault decrypt hello.yml #解密ansible-vault view hello.yml #查看ansible-vault edit hello.yml #编辑加密文件ansible-vault rekey hello.yml #修改口令ansible-vault create new.yml #创建新文件
1.4.7 ansible-console
功能:
可交互执行命令,支持tab补全,ansible 2.0+新增
提示符格式:
执行用户@当前操作的主机组 (当前组的主机数量)[f:并发数]$
常用子命令:
设置并发数: forks n 例如: forks 10切换组: cd 主机组 例如: cd web列出当前组主机列表: list列出所有的内置命令: ?或help
【范例】:
[root@ansible ansible]#ansible-consoleWelcome to the ansible console.Type help or ? to list commands.root@all (3)[f:5]$ list192.168.7.71192.168.7.72192.168.7.73root@all (3)[f:5]$ cd websrvsroot@websrvs (3)[f:5]$ list192.168.7.71192.168.7.72192.168.7.73root@websrvs (3)[f:5]$ yum name=httpd state=present
1.5 ansible常用模块
参考资料:https://docs.ansible.com/ansible/latest/modules/modules_by_category.html
1.5.1 command模块
功能:在被控机执行命令,ansible的默认模块,可忽略-m选项
注意:此模块的命令不支持$VARNAME < > | ; &等,需要用shell模块实现
【范例】:
[root@ansible ~]#ansible websrvs -m command -a 'echo 123.com | passwd --stdin zhangsan'[root@ansible ~]#ansible websrvs -a 'wall echo hello'
1.5.2 shell模块
功能:近似command,用shell执行命令
【范例】:
[root@ansible ~]#ansible websrvs -m shell -a 'echo 123.com | passwd --stdin zhangsan'
1.5.3 script模块
功能:在被控机上运行ansible服务器上的脚本
【范例】:
[root@ansible ~]#ansible websrvs -m script -a '/data/test.sh'
1.5.4 copy模块
功能:从ansible服务器复制文件到被控机
【范例】:
#如目标存在,默认覆盖,此处指定先备份[root@ansible ~]#ansible websrvs -m copy -a "src=/data/test.sh dest=/tmp/test2.sh owner=zhangsan mode=600 backup=yes" #指定内容,直接生成目标文件[root@ansible ~]#ansible websrvs -m copy -a "content='test content\n' dest=/tmp/test.txt"#复制/etc/下的文件,不包括/etc/目录自身ansible srv -m copy -a "src=/etc/ dest=/backup"# 注:如果目标目录不存在会自动创建
1.5.5 fetch模块
功能:从被控机提取文件至ansible主控端,copy相反,目前不支持目录
【范例】:
[root@ansible ~]#ansible websrvs -m fetch -a 'src=/tmp/test.txt dest=/data'
1.5.6 file模块
功能:管理文件和文件属性
【范例】:
# 创建空文件[root@ansible ~]#ansible websrvs -m file -a 'path=/data/test.sh state=touch owner=hechunping mode=755'# 创建目录[root@ansible ~]#ansible websrvs -m file -a 'path=/data/dir1 state=directory owner=hechunping group=hechunping'# 创建软连接[root@ansible ~]#ansible websrvs -m file -a 'src=/data/test.sh dest=/data/test.sh-link state=link'
1.5.7 unarchive模块
功能:解包解压缩
实现有两种用法:1.将ansible主机上的压缩包传到远程主机后解压缩至特定目录,设置copy=yes2.将远程主机上的某个压缩包解压缩到指定路径下,设置copy=no
常见参数:
- copy:默认为yes,当copy=yes,拷贝的文件是从ansible主机复制到远程主机上,如果设置为copy=no,会在远程主机上寻找src源文件
- remote_src:和copy功能一样且互斥,yes表示在远程主机,不在ansible主机,no表示文件在ansible主机上
- src:源路径,可以是ansible主机上的路径,也可以是远程主机上的路径,如果是远程主机上的路径,则需要设置copy=no
- dest:远程主机上的目标路径
- mode:设置解压缩后的文件权限
【范例】:
# 将ansible服务器上的压缩文件解压缩到被控机上[root@ansible ~]#ansible websrvs -m unarchive -a 'src=/data/test.sh.tar.gz dest=/usr/local'# 解压被控机上的压缩文件到它本地[root@ansible ~]#ansible 192.168.7.72 -m unarchive -a 'src=/data/test.sh.tar.gz dest=/usr/local copy=no mode=0777'# 解压网络压缩文件到被控机[root@ansible ~]#ansible websrvs -m unarchive -a 'src=https://nginx.org/download/nginx-1.14.2.tar.gz dest=/usr/local copy=no'
1.5.8 archive模块
功能:打包压缩
【范例】:
[root@ansible ~]#ansible websrvs -m archive -a 'path=/var/log/ dest=/data/log.tar.bz2 format=bz2 owner=hechunping mode=0600'
1.5.9 hostname模块
功能:管理主机名
【范例】:
[root@ansible ~]#ansible 192.168.7.71 -m hostname -a 'name=web'
1.5.10 cron模块
功能:计划任务
支持时间:minute,hour,day,month,weekday
【范例】:
# 创建任务,周一至周五每天2:30执行mysql_backup.sh脚本ansible dbsrvs -m cron -a 'hour=2 minute=30 weekday=1-5 name="backupmysql" job=/root/mysql_backup.sh'# 禁用计划任务ansible dbsrvs -m cron -a 'hour=2 minute=30 weekday=1-5 name="backupmysql" job=/root/mysql_backup.sh disabled=yes'# 启用计划任务ansible dbsrvs -m cron -a 'hour=2 minute=30 weekday=1-5 name="backupmysql" job=/root/mysql_backup.sh disabled=no'# 删除任务ansible dbsrvs -m cron -a "name='backup mysql' state=absent"
1.5.11 yum模块
功能:管理软件包
【范例】:
# 安装[root@ansible ~]#ansible websrvs -m yum -a 'name=redis state=present'# 删除[root@ansible ~]#ansible websrvs -m yum -a 'name=redis state=absent'
1.5.12 service模块
功能:管理服务
【范例】:
# 启动,并设置开机启动[root@ansible ~]#ansible websrvs -m service -a 'name=redis state=started enabled=yes'# 停止[root@ansible ~]#ansible websrvs -m service -a 'name=redis state=stopped'# 重启[root@ansible ~]#ansible websrvs -m service -a 'name=redis state=restarted'
1.5.13 user模块
功能:管理用户
【范例】:
# 创建[root@ansible ~]#ansible websrvs -m user -a 'name=user1 comment="test user" uid=2048 home=/app/user1 group=root'# 删除用户及其及目录等数据[root@ansible ~]#ansible websrvs -m user -a 'name=user1 state=absent remove=yes'
1.5.14 group模块
功能:管理组
【范例】:
# 创建[root@ansible ~]#ansible websrvs -m group -a 'name=nginx gid=88 system=yes'# 删除[root@ansible ~]#ansible websrvs -m group -a 'name=nginx state=absent'
1.5.15 setup模块
功能:返回系统状态信息
【范例】:
ansible websrvs -m setupansible websrvs -m setup -a "filter=ansible_nodename"ansible websrvs -m setup -a "filter=ansible_hostname"ansible websrvs -m setup -a "filter=ansible_domain"ansible websrvs -m setup -a "filter=ansible_memtotal_mb"ansible websrvs -m setup -a "filter=ansible_memory_mb"ansible websrvs -m setup -a "filter=ansible_memfree_mb"ansible websrvs -m setup -a "filter=ansible_os_family"ansible websrvs -m setup -a "filter=ansible_distribution_major_version"ansible websrvs -m setup -a "filter=ansible_distribution_version"ansible websrvs -m setup -a "filter=ansible_processor_vcpus"ansible websrvs -m setup -a "filter=ansible_all_ipv4_addresses"ansible websrvs -m setup -a "filter=ansible_architecture"
2 Playbook
2.1 Playbook介绍
1.playbook 剧本是由一个或多个"play"组成的列表2.play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。Task实际是调用ansible的一个module,将多个play组织在一个playbook中,即可以让它们联合起来,按事先编排的机制执行预定义的动作3.Playbook文件是采用YAML语言编写的
2.2 Playbook核心元素
- Hosts 执行的远程主机列表
- Tasks 任务集
- Variables 内置变量或自定义变量在playbook中调用
- Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
- Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
- tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断
2.2.1 hosts组件
功能:playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机,须事先定义在主机清单中
one.example.comone.example.com:two.example.com192.168.1.50192.168.1.*Websrvs:dbsrvs #或者,两个组的并集Websrvs:&dbsrvs #与,两个组的交集websrvs:!dbsrvs #在websrvs组,但不在dbsrvs组
【范例】:
- hosts: websrvs:dbsrvs
2.2.2 remote_user组件
功能:可用于host和task中。也可以指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户
- hosts: websrvs remote_user: root tasks: - name: test connection ping: remote_user: zhangsan sudo: yes #默认sudo为root sudo_user: lisi #sudo为lisi
2.2.3 task列表和action组件
1.play的主体部分是task list,task list中有一个或多个task,各个task按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个task后,再开始第二个task2.task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致3.每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出
task两种格式:
1)action:module arguments2)module:arguments (推荐使用)
注:shell和command模块后面跟命令,而非key=value
【范例】:
---- hosts: websrvs remote_user: root tasks: - name: install httpd yum: name=httpd - name: start httpd service: name=httpd state=started enabled=yes
2.2.4 其它组件
某任务的状态在运行后为changed时,可通过"notify"通知给相应的handlers任务可以通过"tags"打标签,可在ansible-playbook命令上使用-t指定进行调用
2.2.5 shell scripts VS playbook案例
### 安装Apache ####SHELL脚本实现#!/bin/bashyum install --quiet -y httpd# 复制配置文件cp /tmp/httpd.conf /etc/httpd/conf/httpd.confcp/tmp/vhosts.conf /etc/httpd/conf.d/# 启动Apache,并设置开机启动systemctl enable --now httpd#Playbook实现---- hosts: websrvs remote_user: root tasks: - name: "安装Apache" yum: name=httpd - name: "复制配置文件" copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/ - name: "复制配置文件" copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/ - name: "启动Apache,并设置开机启动" service: name=httpd state=started enabled=yes
2.3 Playbook命令
语法:
ansible-playbook ... [options]
常用选项
--check -C #只检测可能会发生的改变,但不真正执行操作--list-hosts #列出运行任务的主机--list-tags #列出tag--list-tasks #列出task--limit 主机列表 #只针对主机列表中的主机执行-v -vv -vvv #显示过程
【范例】:
ansible-playbook file.yml --check #只检测ansible-playbook file.ymlansible-playbook file.yml --limit websrvs
2.4 Playbook初步
【范例】:yum安装httpd
#install_httpd.yml---- hosts: websrvs remote_user: root tasks: - name: "安装httpd" yum: name=httpd state=present - name: "复制httpd.conf配置文件" copy: src=files/httpd.conf dest=/etc/httpd/conf - name: "启动httpd,并设置开机启动" service: name=httpd state=started enabled=yes
【范例】:卸载yum安装的httpd
#remove_httpd.yml---- hosts: websrvs remote_user: root tasks: - name: remove httpd package yum: name=httpd state=absent - name: remove apache user user: name=apache state=absent - name: remove data file file: name=/etc/httpd state=absent
【范例】:创建MySQL组和用户
---# 创建MySQL组和用户- hosts: dbsrvs remote_user: root tasks: - {name: 创建组, group: name=mysql system=yes gid=306} - name: 创建用户 user: name=mysql shell=/sbin/nologin system=yes group=mysql uid=306 create_home=no
【范例】:安装mysql-5.6.46-linux-glibc2.12
[root@ansible ~]#ll /data/ansible/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz -rw-r--r-- 1 root root 403177622 Dec 4 13:05 /data/ansible/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz[root@ansible ~]#cat /data/ansible/files/my.cnf [mysqld]socket=/tmp/mysql.sockuser=mysqlsymbolic-links=0datadir=/data/mysqlinnodb_file_per_table=1log-bin[client]port=3306socket=/tmp/mysql.sock[mysqld_safe]log-error=/var/log/mysqld.log[root@ansible ~]#cat /data/ansible/install_mysql.yml ---# install mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz- hosts: websrvs remote_user: root tasks: - name: "安装依赖包" yum: name=libaio,perl-Data-Dumper,perl-Getopt-Long - name: "创建mysql组" group: name=mysql gid=306 - name: "创建mysql用户" user: name=mysql uid=306 group=mysql shell=/sbin/nologin system=yes create_home=no home=/data/mysql - name: "将本地二进制安装包解压缩到目标主机的/usr/local目录下,并修改属主、属组为root" unarchive: src=/data/ansible/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz dest=/usr/local owner=root group=root - name: "为解压缩的二进制包目录创建软连接" file: src=/usr/local/mysql-5.6.46-linux-glibc2.12-x86_64 dest=/usr/local/mysql state=link - name: "初始化数据库" shell: chdir=/usr/local/mysql ./scripts/mysql_install_db --datadir=/data/mysql --user=mysql tags: data - name: "复制本地my.cnf配置文件到被控主机" copy: src=/data/ansible/files/my.cnf dest=/etc/my.cnf - name: "复制本地的mysql服务脚本到被控主机的/etc/init.d目录下" shell: /bin/cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld - name: "启动mysql服务,并且设置开机启动" shell: /etc/init.d/mysqld start;chkconfig --add mysqld;chkconfig mysqld on tags: service - name: "将mysql的二进制可执行程序添加到PATH变量" copy: content='PATH=/usr/local/mysql/bin:$PATH' dest=/etc/profile.d/mysql.sh - name: "执行安全加固脚本" script: /data/ansible/files/secure_mysql.sh tags: script
2.5 Playbook中使用handlers和notify
Handlers本质是task list ,其中的task与前述的task并没有本质上的不同,用于当关注的资源发生变化时,才会采取一定的操作.Notify对应的action可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作
【范例】:
---- hosts: websrvs remote_user: root tasks: - name: "安装httpd" yum: name=httpd state=present - name: "复制httpd.conf配置文件,并且重启httpd" copy: src=files/httpd.conf dest=/etc/httpd/conf notify: restart httpd - name: "启动httpd,并设置开机启动" service: name=httpd state=started enabled=yes handlers: - name: restart httpd service: name=httpd state=restarted
2.6 Playbook中使用tags组件
功能:在playbook文件中,可以利用tags组件,为特定task指定标签,当在执行playbook时,可以只执行特定tags的task,而非整个playbook文件
【范例】:
[root@ansible ansible]#cat install_httpd.yml---- hosts: websrvs remote_user: root tasks: - name: "安装httpd" yum: name=httpd state=present - name: "复制httpd.conf配置文件,并且重启httpd" copy: src=files/httpd.conf dest=/etc/httpd/conf tags: conf - name: "启动httpd,并设置开机启动" service: name=httpd state=started enabled=yes tags: service[root@ansible ansible]#ansible-playbook -t conf,service install_httpd.yml
2.7 Playbook中使用变量
变量名:仅能由字母、数字和下划线组成,且只能以字母开头
变量定义:
key=value
【范例】:
http_port=80
变量调用方式:
通过{{ variable_name }} 调用变量,且变量名前后建议加空格,有时用"{{ variable_name }}"才生效
变量来源
1)ansible的setup facts远程主机的所有变量都可以直接调用
2)通过命令行指定变量,优先级最高
ansible-playbook -e varname=value
3)在playbook文件中定义
vars: - var1: value1 - var2: value2
4)在独立的变量yml文件中定义
- hosts: all vars_files: - vars.yml
5)在/etc/ansible/hosts文件中定义
主机(普通)变量:主机组中主机单独定义,优先级高于公共变量组(公共)变量:针对主机组中所有主机定义同一变量
6)在role中定义
2.7.1 使用setup模块中变量
【范例】:
[root@ansible ansible]#cat var.yml ---# var.yml- hosts: websrvs remote_user: root tasks: - name: "创建日志文件" file: name=/var/log/{{ ansible_fqdn }} state=touch[root@ansible ansible]#ansible-playbook var.yml
2.7.2 在playbook命令行中定义变量
【范例】:
[root@ansible ansible]#cat var.yml---# var.yml- hosts: websrvs remote_user: root tasks: - name: "安装包变量" yum: name={{ pkname }} state=absent[root@ansible ansible]#ansible-playbook -e pkname=httpd var.yml
2.7.3 在playbook文件中定义变量
【范例】:
[root@ansible ansible]#cat var.yml---- hosts: websrvs remote_user: root vars: - username: user1 - groupname: group1 tasks: - name: create group group: name={{ groupname }} state=present - name: create user user: name={{ username }} state=present[root@ansible ansible]#ansible-playbook var.yml
2.7.4 使用变量文件
可以在一个独立的playbook文件中定义变量,在另一个playbook文件中引用变量文件中的变量,比playbook中定义的变量优化级高
【范例】:
[root@ansible ansible]#cat vars.yml ---# variables filevar1: vsftpdvar2: nginx[root@ansible ansible]#cat var2.yml ---- hosts: websrvs remote_user: root vars_files: vars.yml tasks: - name: "vsftpd日志文件" file: name=/data/{{ var1 }}.log state=touch - name: "nginx日志文件" file: name=/data/{{ var2 }}.log state=touch
2.7.5 主机清单文件中定义变量
2.7.5.1 主机变量
在inventory主机清单文件中为指定的主机定义变量以便于在playbook中使用
【范例】:
[websrvs]www1.abc.com http_port=80www2.abc.com http_port=8080
2.7.5.2 组(公共)变量:
在inventory主机清单文件中赋予给指定组内所有主机在playbook中可用的变量
【范例】:
[websrvs]www1.abc.comwww2.abc.com[websrvs:vars]ntp_server=ntp.aliyun.com
【范例】:
[root@ansible ansible]#vim /etc/ansible/hosts[websrvs]192.168.7.71 hname=ansible192.168.7.72 hname=web1192.168.7.73 hname=web2[websrvs:vars]http_port=808mark="-"[root@ansible ansible]#ansible websrvs -m hostname -a 'name={{ hname }}{{ mark }}{{ http_port }}'# 命令行指定变量[root@ansible ansible]#ansible websrvs -e http_port=8000 -m hostname -a 'name={{ hname }}{{ mark }}{{ http_port }}'
2.8 Template模板
模板是一个文本文件,可以作为生成文件的模板,并且模板文件中还可以嵌套jinja语法
2.8.1 jinja语言
jinja2语言使用字面量,有下面形式:字符串:使用单引号或双引号数字:整数,浮点数列表:[item1,item2,...]元组:(item1,item2,...)字典:{key1:value1,key2:value2,...}布尔型:true/false算术运算:+, -, *, /, //, %, **比较操作:==, !=, >, >=, <, <=逻辑运算:and,or,not流表达式:For,If,Whenjinja2相关说明:字面量:表达式最简单的形式就是字面量。字面量表示诸如字符串和数值的 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 如果左操作数和右操作数同为真,返回 trueor 如果左操作数和右操作数有一个为真,返回 truenot 对一个表达式取反(expr)表达式组true / false true 永远是 true ,而 false 始终是 false
2.8.2 template
template功能:可以根据和参考模块文件,动态生成相类似的配置文件template文件必须存放于templates目录下,且命名为 .j2 结尾yaml/yml 文件需和templates目录平级,目录结构如下:./├── temnginx.yml└── templates └── nginx.conf.j2
【范例】:利用template同步nginx配置文件
# 准备templates/nginx.conf.j2文件[root@ansible ansible]#cat temnginx.yml---- hosts: websrvs remote_user: root tasks: - name: "利用template模板文件配置被控主机" template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf[root@ansible ansible]#ansible-playbook temnginx.yml
【范例】:template变更替换
#修改templates/nginx.conf.j2文件[root@ansible ansible]#vim templates/nginx.conf.j2worker_processes {{ ansible_processor_vcpus }};[root@ansible ansible]#cat temnginx.yml---- hosts: websrvs remote_user: root tasks: - name: "利用template模板文件配置被控主机" template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf[root@ansible ansible]#ansible-playbook temnginx.yml
【范例】:template算术运算
[root@ansible ansible]#vim templates/nginx.conf.j2worker_processes {{ ansible_processor_vcpus * 2}};worker_processes {{ ansible_processor_vcpus + 2}};
【范例】:template中使用流程控制for和if
for循环
【例1】:
[root@ansible ansible]#cat temnginx1.yml ---- hosts: websrvs remote_user: root vars: nginx_vhosts: - listen: 8081 server_name: www.hechunping.tech tasks: - name: "template模板文件配置被控主机" template: src=nginx.conf1.j2 dest=/data/nginx.conf[root@ansible ansible]#cat templates/nginx.conf1.j2 {% for vhost in nginx_vhosts %}server { listen {{ vhost.listen }}; server_name {{ vhost.server_name }};}{% endfor %}# 生成结果[root@ansible ansible]#ansible-playbook temnginx1.yml [root@ansible ansible]#cat /data/nginx.conf server { listen 8081; server_name www.hechunping.tech;}
【例2】:
[root@ansible ansible]#cat temnginx3.yml ---- hosts: websrvs remote_user: root vars: nginx_vhosts: - listen: 8081 server_name: "web1.hechunping.tech" root: "/var/www/nginx/web1" - listen: 8082 server_name: "web2.hechunping.tech" root: "/var/www/nginx/web2" - listen: 8083 server_name: "web3.hechunping.tech" root: "/var/www/nginx/web3" tasks: - name: "template模板文件配置被控主机" template: src=nginx.conf3.j2 dest=/data/nginx2.conf[root@ansible ansible]#cat templates/nginx.conf3.j2 {% for vhost in nginx_vhosts %}server { listen {{ vhost.listen }}; server_name {{ vhost.server_name }}; root {{ vhost.root }};}{% endfor %}# 生成结果[root@ansible ansible]#ansible-playbook temnginx3.yml[root@ansible ansible]#cat /data/nginx2.conf server { listen 8081; server_name web1.hechunping.tech; root /var/www/nginx/web1;}server { listen 8082; server_name web2.hechunping.tech; root /var/www/nginx/web2;}server { listen 8083; server_name web3.hechunping.tech; root /var/www/nginx/web3;}
if判断
【例1】:
[root@ansible ansible]#cat temnginx4.yml ---- hosts: websrvs remote_user: root vars: nginx_vhosts: - web1: listen: 8080 root: "/var/www/nginx/web1" - web2: listen: 8080 server_name: "web2.hechunping.tech" root: "/var/www/nginx/web2" tasks: - name: "template模板文件配置被控主机" template: src=nginx.conf2.j2 dest=/data/nginx3.conf[root@ansible ansible]#cat templates/nginx.conf2.j2 {% for vhost in nginx_vhosts %}server{ listen {{ vhost.listen }}; {% if vhost.server_name is defined %}server_name {{ vhost.server_name }}; {% endif %}root {{ vhost.root }}}{% endfor %}#生成结果[root@ansible ansible]#ansible-playbook temnginx4.yml[root@ansible ansible]#cat /data/nginx3.conf server{ listen 8080; root /var/www/nginx/web1}server{ listen 8080; server_name web2.hechunping.tech; root /var/www/nginx/web2}
2.9 Playbook使用when
功能:when语句,可以实现条件测试。如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试,通过在task后添加when子句即可使用条件测试
【范例】:
[root@ansible ansible]#cat when.yml ---- hosts: websrvs remote_user: root tasks: - name: "打印hello redhat" command: /usr/bin/wall hello redhat when: ansible_os_family == "RedHat"
2.10 Playbook使用迭代with_items
迭代:当有需要重复性执行的任务时,可以使用迭代机制对迭代项的引用,固定变量名为"item"要在task中使用with_items给定要迭代的元素列表
列表元素格式:
- 字符串
- 字典
【范例】:
---- hosts: 192.168.7.71 remote_user: root tasks: - name: "备份文件" copy: src=/data/{{ item }} dest=/backup/{{ item }} with_items: - nginx.conf - nginx2.conf#上面语句的功能等同于下面的语句- name: "备份/data/nginx.conf文件到/backup目录" copy: src=/data/nginx.conf dest=/backup- name: "备份/data/nginx2.conf文件到/backup目录" copy: src=/data/nginx2.conf dest=/backup
迭代嵌套子变量:在迭代中,还可以嵌套子变量,关联多个变量在一起使用
【范例】:
---- hosts: websrvs remote_user: root tasks: - name: "创建组" group: name={{ item }} state=present with_items: - a1 - a2 - a3 - name: "创建用户" user: name={{ item.name }} group={{ item.group }} state=present with_items: - { name: 'a1',group: 'a1' } - { name: 'a2',group: 'a2' } - { name: 'a3',group: 'a3' }
3 roles角色
角色是ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中
roles:多个角色的集合,可以在roles目录下为每个role建立单独的子目录
roles├── httpd├── mysql├── nginx└── redis
3.1 Ansible Roles目录编排
roles目录结构如下所示
每个角色,以特定的层级目录结构进行组织
roles目录结构
playbook.ymlroles/ project/ tasks/ handlers/ files/ templates/ vars/ defaults/ meta/
注:playbook文件需要和roles目录同级
roles各目录作用
/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文件
3.2 创建role
创建role的步骤
(1) 创建以roles命名的目录(2) 在roles目录中分别创建以各角色名称命名的目录,如webservers等(3) 在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates和vars目录;用不到的目录可以创建为空目录,也可以不创建(4) 在playbook文件中,调用各角色
【范例】:roles的目录结构
role_httpd.ymlroles/├── httpd│ ├── files│ │ ├── httpd.conf│ │ └── index.html│ ├── handlers│ │ └── main.yml│ └── tasks│ ├── config.yml│ ├── index.yml│ ├── install.yml│ ├── main.yml│ └── service.yml
3.3 playbook调用角色
调用角色方法1:
---- hosts: websrvs remote_user: root roles: - mysql - memcached - nginx
调用角色方法2:
键role用于指定角色名称,后续的k/v用于传递变量给角色
---- hosts: all remote_user: root roles: - mysql - { role: nginx, username: nginx }
调用角色方法3:
还可以基于条件测试实现角色调用
---- hosts: all remote_user: root roles: - { role: nginx, username: nginx, when: ansible_distribution_major_version == '7' }
3.4 roles中tags使用
#nginx-role.yml---- hosts: websrvs remote_user: root roles: - { role: nginx ,tags: [ 'nginx','web' ], when: ansible_distribution_major_version == "6" } - { role: httpd ,tags: [ 'httpd','web' ] } - { role: mysql ,tags: [ 'mysql','db' ] } - { role: mariadb ,tags: [ 'mariadb','db' ] }[root@ansible ansible]#ansible-playbook --tags="nginx,httpd,mysql" nginx-role.yml
3.5 实战案例
3.5.1 案例1:实现httpd角色
[root@ansible ansible]#pwd/data/ansible[root@ansible ansible]#ls roles/httpd/files handlers tasks# 创建角色[root@ansible ansible]#cd roles/httpd/[root@ansible httpd]#cat tasks/main.yml - include: install.yml- include: config.yml- include: index.yml- include: service.yml[root@ansible httpd]#cat tasks/install.yml - name : install httpd package yum: name: httpd[root@ansible httpd]#cat tasks/config.yml - name: config file copy: src: httpd.conf dest: /etc/httpd/conf backup: yes[root@ansible httpd]#cat tasks/index.yml - name: index.html copy: src: index.html dest: /var/www/html[root@ansible httpd]#cat tasks/service.yml - name: start service service: name: httpd state: started enabled: yes[root@ansible httpd]#cat handlers/main.yml - name: restart service: name: httpd state: restarted# 在files目录下准备两个文件[root@ansible httpd]#ls files/httpd.conf index.html[root@ansible httpd]#tree ././├── files│ ├── httpd.conf│ └── index.html├── handlers│ └── main.yml└── tasks ├── config.yml ├── index.yml ├── install.yml ├── main.yml └── service.yml3 directories, 8 files# 在playbook中调用角色[root@ansible httpd]#cat ../../role_httpd.yml ---# httpd role- hosts: appsrvs remote_user: root roles: - role: httpd# 运行playbook[root@ansible httpd]#ansible-playbook ../../role_httpd.yml
3.5.2 案例2:实现nginx角色
[root@ansible ~]#ls /data/ansible/roles/nginx/files handlers tasks templates vars# 创建task文件[root@ansible ~]#cd /data/ansible/roles/nginx/[root@ansible nginx]#cat tasks/main.yml - include: install.yml- include: config.yml- include: file.yml- include: service.yml[root@ansible nginx]#cat tasks/install.yml - name: install yum: name=nginx[root@ansible nginx]#cat tasks/config.yml - name: config file for centos7 template: src: nginx7.conf.j2 dest: /etc/nginx/nginx.conf when: ansible_distribution_major_version=="7" notify: restart- name: config file for centos8 template: src: nginx8.conf.j2 dest: /etc/nginx/nginx.conf when: ansible_distribution_major_version=="8" notify: restart[root@ansible nginx]#cat tasks/file.yml - name: index.html copy: src: index.html dest: /usr/share/nginx/html[root@ansible nginx]#cat tasks/service.yml - name: start service service: name: nginx state: started enabled: yes# 创建handlers文件[root@ansible nginx]#cat handlers/main.yml - name: restart service: name: nginx state: restarted# 创建两个template文件[root@ansible nginx]#cat templates/nginx7.conf.j2# For more information on configuration, see:# * Official English Documentation: http://nginx.org/en/docs/# * Official Russian Documentation: http://nginx.org/ru/docs/user {{user}}; #修改此行worker_processes {{ansible_processor_vcpus**2}}; #修改此行error_log /var/log/nginx/error.log;pid /run/nginx.pid;# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.include /usr/share/nginx/modules/*.conf;events { worker_connections 1024;}http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }# Settings for a TLS enabled server.## server {# listen 443 ssl http2 default_server;# listen [::]:443 ssl http2 default_server;# server_name _;# root /usr/share/nginx/html;## ssl_certificate "/etc/pki/nginx/server.crt";# ssl_certificate_key "/etc/pki/nginx/private/server.key";# ssl_session_cache shared:SSL:1m;# ssl_session_timeout 10m;# ssl_ciphers HIGH:!aNULL:!MD5;# ssl_prefer_server_ciphers on;## # Load configuration files for the default server block.# include /etc/nginx/default.d/*.conf;## location / {# }## error_page 404 /404.html;# location = /40x.html {# }## error_page 500 502 503 504 /50x.html;# location = /50x.html {# }# }}[root@ansible nginx]#cat templates/nginx8.conf.j2# For more information on configuration, see:# * Official English Documentation: http://nginx.org/en/docs/# * Official Russian Documentation: http://nginx.org/ru/docs/user nginx;worker_processes {{ansible_processor_vcpus+2}}; #修改此行error_log /var/log/nginx/error.log;pid /run/nginx.pid;# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.include /usr/share/nginx/modules/*.conf;events { worker_connections 1024;}http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }# Settings for a TLS enabled server.## server {# listen 443 ssl http2 default_server;# listen [::]:443 ssl http2 default_server;# server_name _;# root /usr/share/nginx/html;## ssl_certificate "/etc/pki/nginx/server.crt";# ssl_certificate_key "/etc/pki/nginx/private/server.key";# ssl_session_cache shared:SSL:1m;# ssl_session_timeout 10m;# ssl_ciphers HIGH:!aNULL:!MD5;# ssl_prefer_server_ciphers on;## # Load configuration files for the default server block.# include /etc/nginx/default.d/*.conf;## location / {# }## error_page 404 /404.html;# location = /40x.html {# }## error_page 500 502 503 504 /50x.html;# location = /50x.html {# }# }}# 创建变量文件[root@ansible nginx]#cat vars/main.yml user: daemon# 在files目录下创建index.html文件[root@ansible nginx]#cat files/index.html hello nginx
# 目录结构如下[root@ansible nginx]#tree ././├── files│ └── index.html├── handlers│ └── main.yml├── tasks│ ├── config.yml│ ├── file.yml│ ├── install.yml│ ├── main.yml│ └── service.yml├── templates│ ├── nginx7.conf.j2│ └── nginx8.conf.j2└── vars └── main.yml5 directories, 10 files# 在playbook中调用角色[root@ansible nginx]#cat ../../role_nginx.yml ---# nginx role- hosts: appsrvs roles: - role: nginx# 运行playbook[root@ansible nginx]#ansible-playbook /data/ansible/role_nginx.yml
3.5.3 案例3:实现多角色的选择
[root@ansible nginx]#cat /data/ansible/role_httpd_nginx.yml---- hosts: appsrvs roles: - { role: httpd,tags: [httpd,web], when: ansible_distribution_major_version=="7" } - { role: nginx,tags: [nginx,web], when: ansible_distribution_major_version=="8" }[root@ansible nginx]#ansible-playbook -t nginx /data/ansible/role_httpd_nginx.yml
文件
主机
范例
变量
模块
目录
功能
角色
命令
配置
任务
用户
模板
服务
多个
方式
结构
结果
生成
管理
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
网络安全团队口号
考研英语作文网络安全
龙江健康码提交显示服务器错误
网络安全措施媒体
手机远程网络服务器
大数据java软件开发
软件开发试用期被劝退
戴尔服务器硬盘上线
浦东新区电话网络技术创新服务
怒江租房软件开发
软件开发实施过程管理规范
如何下载开源数据库
自主手机软件开发
软件开发师基础知识
中国能源数据库eia
沭阳大型网络技术联系方式
服务器6年更新
data连接数据库
枣庄智慧养老软件开发
广告播放需要走服务器吗
为什么要数据库
电子商务与网络安全技术
安全风险清单和数据库资料
网络安全生产自查工作总结
数据库语音端口
数据库课程设计超市购物系统
分布式应用数据库锁
东莞软件开发 常平
简单易上手的软件开发工具包
国家网络安全周简报