大型企业中如何批量管理千万台服务器之 ansible 自动化运维工具详解
宝山的博客 已于 2023-01-01 21:58:16 修改
ansible 自动化运维工具 详解
前言
在早期的自动化运维工具中,常见的有 puppet、saltstack、ansible 等软件,目前常用的就是 ansible 和 saltstack 2 款工具。saltstack 与 puppet 都是基于 C/S 模式工作的,他们需要安装服务端与客户端,基于 Python 编写,加入 MQ 消息同步,可以是执行命令和执行结果高效返回,但执行过程需要等客户端返回。所以如果客户端没有及时返回或响应,就可能导致部分机器没有执行结果。目前用的较少。
本文就主要分享 ansible 自动化运维工具。我将详细的从概念、到基础搞高级,层层递进,让你轻松掌握 ansible 自动化运维
当然,每一篇文章都不是 100% 的全,我能做的就是将我会的,最大限度的分享给你,让你也可以掌握。
一、ansible 概述
1.1 ansible 概述
- Ansible是一款自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
- Ansible 是一种安装在控制节点上的无代理自动化工具。Ansible 从控制节点远程管理机器和其他设备(默认情况下,通过 SSH 协议)。Ansible 与Saltstack均是基于Python 语言开发,Ansible只需要在一台普通的服务器上运行即可,不需要在客户端服务器上安装客户端。因为 Ansible是基于SSH远程管理,而Linux 服务器大都离不开SSH,所以Ansible不需要为配置工作添加额外的支持。
- Ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是Ansible所运行的模块,Ansible只是提供一种框架。主要包括:
- (1) 连接插件connection plugins:负责和被监控端实现通信;
(2) host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;
(3) 各种模块核心模块、command模块、自定义模块;
(4) 借助于插件完成记录日志邮件等功能;
(5) playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务
- (1) 连接插件connection plugins:负责和被监控端实现通信;
- 架构图
- ansible 官网
1.2 为什么要使用 ansible
- 提高工作的效率
- 提高工作准确度
- 减少维护的成本
- 减少重复性工作
1.3 ansible 功能
- 可以实现批量系统操作配置
- 可以实现批量软件服务部署
- 可以实现批量文件数据分发
- 可以实现批量系统信息收集
1.4 ansible 优点
- 管理端不需要启动服务程序(no server)
- 管理端不需要编写配置文件(/etc/ansible/ansible.cfg)
- 受控端不需要安装软件程序(libselinux-python)
- 受控端不需要启动服务程序(no agent)
- 服务程序管理操作模块众多(module)
- 利用剧本编写来实现自动化(playbook)
- 支持sudo 普通用户
1.5 ansible工作机制
-
# 由上面的图可以看到 Ansible 的组成由 5 个部分组成: #Ansible : ansible核心 #Modules : 包括 Ansible 自带的核心模块及自定义模块 #Plugins : 完成模块功能的补充,包括连接插件、邮件插件等 #Playbooks : 剧本;定义 Ansible 多任务配置文件,由Ansible 自动执行 #Inventory : 定义 Ansible 管理主机的清单 [ˈɪnvəntri] 清单
1.6 ansible 工作原理/流程图
二、ansible 批量管理服务部署
2.1 实验环境
-
实验环境
名称 系统 ip地址 ansible_server Centos 7.6 10.0.0.61 Host-01 Centos 7.6 10.0.0.5 Host-02 Centos 7.6 10.0.0.6 Host-03 Centos 7.6 10.0.0.7 -
实验拓扑
2.2 官网安装教程
2.2.1 ansible 安装
-
# Centso 需要设置EPEL仓库 [root@ansible_server~]# yum install epel-release # 使用yum 安装ansible [root@ansible_server~]# yum install ansible # 查看ansible 安装版本 [root@ansible_server~]# ansible --version ansible 2.9.25 config file = /etc/ansible/ansible.cfg configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python2.7/site-packages/ansible executable location = /usr/bin/ansible python version = 2.7.5 (default, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
2.2.2 ansible 命令参数介绍
-
ansible 常见参数
# ansible 命令参数 # anisble命令语法: ansible [-i 主机文件] [-f 批次] [组名] [-m 模块名称] [-a 模块参数] ansible详细参数: -v,-verbose # 详细模式,如果命令执行成功,输出详细的结果 (-vv –vvv -vvvv) -i PATH, -inventory=PATH # 指定 host 文件的路径,默认是在 /etc/ansible/hosts inventory [ˈɪnvəntri] 库存 -f NUM,-forks=NUM # NUM 是指定一个整数,默认是 5 ,指定 fork 开启同步进程的个数。 -m NAME,-module-name=NAME # 指定使用的 module 名称,默认使用 command模块 -a,MODULE_ARGS #指定 module 模块的参数 -k,-ask-pass #提示输入 ssh 的密码,而不是使用基于 ssh 的密钥认证 -sudo # 指定使用 sudo 获得 root 权限 -K,-ask-sudo-pass #提示输入 sudo 密码,与 -sudo 一起使用 -u USERNAME,-user=USERNAME # 指定移动端的执行用户 -C,-check #测试此命令执行会改变什么内容,不会真正的去执行 # ansible-doc详细参数: ansible-doc -l #列出所有的模块列表 ansible-doc -s 模块名 #查看指定模块的参数 -s, snippet [ˈsnɪpɪt] 片断 [root@ansible_server~]# ansible-doc -s service #列出模块使用简介 [root@ansible_server~]# ansible-doc -l # 指定一个模块详细说明 [root@ansible_server~]# ansible-doc -s fetch # 查询模块在剧本中应用方法 [root@ansible_server~]# ansible-doc fetch
-
Ansible基于多模块管理,常用的Ansible工具管理模块包括:
command
、shell
、script
、yum
、copy
、File
、async
、docker
、cron
、mysql_user
、ping
、sysctl
、user
、acl
、add_host
、easy_install
、haproxy
_等。 -
command 不支持管道符,可以使用shell模块
-
可以使用
ansible-doc -l more
查看ansible支持的模块,也可以查看每个模块的帮助文档,ansible-doc module name
2.2.3 定义主机清单
-
定义主机清单
[root@ansible_server~]# cd /etc/ansible/ [root@ansible_server/etc/ansible]# ll total 24 -rw-r--r-- 1 root root 19985 Aug 22 04:07 ansible.cfg -rw-r--r-- 1 root root 1016 Aug 22 04:07 hosts drwxr-xr-x 2 root root 6 Aug 22 04:07 roles # 操作配置文件前,习惯先备份 [root@ansible_server/etc/ansible]# cp -f hosts hosts.backup [root@ansible_server/etc/ansible]# ll total 28 -rw-r--r-- 1 root root 19985 Aug 22 04:07 ansible.cfg -rw-r--r-- 1 root root 1016 Aug 22 04:07 hosts -rw-r--r-- 1 root root 1016 Sep 14 15:34 hosts.backup drwxr-xr-x 2 root root 6 Aug 22 04:07 roles # 情况hosts 配置文件内容,写hosts文件 [root@ansible_server/etc/ansible]# cat /dev/null > hosts [root@ansible_server/etc/ansible]# cat hosts # 写入主机IP ,这些写了[webserver]、[docker] 等都是分组,可以不写(这样不方便管理) [root@ansible_server/etc/ansible]# cat hosts [webserver] 10.0.0.5 10.0.0.6 # 管理10.0.0.7 docker服务器 [docker] 10.0.0.7 # 本机也可以管理自己管自己 [manager] 10.0.0.61 [root@ansible_server/etc/ansible]#
2.2.4 基于ssh 免密登录
-
ssh 免密登录
# 第一个历程: 创建秘钥对(管理端服务器) sh-keygen -t 秘钥的类型(dsa|rsa) #第二个历程: 将公钥进行分发(被管理端服务器) ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.0.0.5 # 本地生成rsa 密钥对 [root@ansible_server~]# ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): # 直接回车 Enter passphrase (empty for no passphrase): # 直接回车 Enter same passphrase again: # 直接回车 Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:HhsjmGY6DJoSREojVpJmSI63vuoXKy6sK2ESh/eQJr0 root@ansible_server The key's randomart image is: +---[RSA 2048]----+ |+Bo. | |X+o | |==.. | |=.B. o | |o*.+= . S | |+BE=. o = | |B.= o o | |+o = | |X=+ | +----[SHA256]-----+ # 上传到被管理端 [root@web01_server~]# ssh-copy-id root@10.0.0.5 [root@web01_server~]# ssh-copy-id root@10.0.0.6 [root@web01_server~]# ssh-copy-id root@10.0.0.7
2.2.5 管理端 运行命令测试
-
ping模块检查网络连通性
# 常用参数 -i # 指定 host 文件的路径,默认是在 /etc/ansible/hosts ,用的时候可以省略 -m # 指定使用的ping模块 [root@ansible_server~]# ansible -i /etc/ansible/hosts 'www' -m ping 10.0.0.5 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } 10.0.0.6 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } [root@ansible_server~]#
三、ansible 批量管理服务 应用
3.1 ansible ping 模块实战
3.1.0 ping模块参数介绍
-
模块介绍
Ansible最基础的模块为ping模块,主要用于判断远程客户端是否在线,用于ping本身服务器,返回值为changed、ping。 1
3.1.1 ansible 实现自己管理自己
-
自己管理自己
# ansible基于ssh连接-i (inventory)参数后指定的远程主机时,也可以写端口,用户,密码。 格式:ansible_ssh_port:指定ssh端口 ansible_ssh_user:指定 ssh 用户 ansible_ssh_pass:指定 ssh 用户登录是认证密码(明文密码不安全) ansible_sudo_pass:指明 sudo 时候的密码 [root@ansible_server~]# cat /etc/ansible/hosts [www] 10.0.0.5 10.0.0.6 [docker] 10.0.0.7 [manager] [root@ansible_server~]# # 同时还可以基于SSH 免密登录,2种方式选一种。 # 将自己的密钥拷贝到本地,然后ssh 连接一下即可。 [root@web01_server~]# ssh-copy-id root@10.0.0.61
3.1.2 ansible 匹配一个网段机器进行管理
-
ping 网段的连通性
# ping 某一个网段 [root@ansible_server~]# ansible 10.0.0.* -m ping # 路径是可以省略的 -i ,因为默认路径就是 /etc/ansible/hosts [root@ansible_server~]# ansible -i /etc/ansible/hosts "docker" -m ping 10.0.0.7 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } [root@ansible_server~]#
3.2 ansible shell 模块实战
3.2.0 shell模块介绍
-
模块介绍
# Ansible shell模块主要用于远程客户端上执行各种Shell命令或者运行脚本,远程执行命令通过/bin/sh环境来执行,支持比command更多的指令,Shell模块使用详解: # 常用参数 chdir 执行命令前,切换到目录; creates 当该文件存在时,则不执行该步骤; executable 换用shell环境执行命令; free_form 需要执行的脚本; removes 当该文件不存在时,则不执行该步骤; warn 如果在ansible.cfg中存在告警,如果设定了False,不会警告此行。
3.2.1通过ansible 在docker 服务器上创建/查看目录
-
创建/查看目录
# 在docker服务器上 ,在/opt 目录下创建一个名字为rivers+当前时间的目录 [root@ansible_server~]# ansible docker -m shell -a "mkdir /opt/rivers`date +%F`;ls /opt" [WARNING]: Consider using the file module with state=directory rather than running 'mkdir'. 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. 10.0.0.7 | CHANGED | rc=0 >> rivers2021-09-16 # 通过ls 查看是否创建 [root@ansible_server~]# ansible docker -m shell -a "ls /opt" 10.0.0.7 | CHANGED | rc=0 >> rivers2021-09-16 [root@ansible_server~]#
3.2.2 通过ansible shell 模块远程查看nginx 服务是否启动
-
远程查看nginx 服务状态
# 远程查看docker服务器上nginx 进程信息 [root@ansible_server~]# ansible docker -m shell -a "ps -ef|grep nginx" 10.0.0.7 | CHANGED | rc=0 >> root 11711 1 0 15:25 ? 00:00:00 nginx: master process nginx nginx 11712 11711 0 15:25 ? 00:00:00 nginx: worker process root 11775 11770 3 15:26 pts/0 00:00:00 /bin/sh -c ps -ef|grep nginx root 11777 11775 0 15:26 pts/0 00:00:00 grep nginx [root@ansible_server~]#
3.2.3 通过ansible shell 模块远程查看防火墙状态
-
远程查看docker 服务器上的防火墙状态
# ansible 服务器上远程查看 dockerf 服务器行的防火墙状态是否运行 [root@ansible_server~]# ansible docker -m shell -a "firewall-cmd --state" 10.0.0.7 | CHANGED | rc=0 >> running [root@ansible_server~]#
3.2.4 通过ansible 批量修改 用户密码
-
批量修改用户密码
# 通通过shell 远程批量修改密码 10.0.0.5 | CHANGED | rc=0 >> Changing password for user root. passwd: all authentication tokens updated successfully. 10.0.0.6 | CHANGED | rc=0 >> Changing password for user root. passwd: all authentication tokens updated successfully.
3.3 ansible command 模块实战
3.3.0 command 模块介绍
-
command 模块介绍
# Ansible command模块为ansible默认模块,主要用于执行Linux基础命令,可以执行远程服务器命令执行、任务执行等操作。Command模块使用详解: Chdir 执行命令前,切换到目录; Creates 当该文件存在时,则不执行该步骤; Executable 换用shell环境执行命令; Free_form 需要执行的脚本; Removes 当该文件不存在时,则不执行该步骤; Warn 如果在ansible.cfg中存在告警,如果设定了False,不会警告此行。
3.3.1 通过ansible 使用df -h 查看磁盘空间使用信息
-
查看磁盘空间
# 使用df -h 查看 docker组中机器的磁盘使用情况 [root@ansible_server~]# ansible -i /etc/ansible/hosts 10.0.0.7 -m command -a "df -h" 10.0.0.7 | CHANGED | rc=0 >> Filesystem Size Used Avail Use% Mounted on /dev/sda3 99G 1.7G 97G 2% / devtmpfs 442M 0 442M 0% /dev tmpfs 453M 0 453M 0% /dev/shm tmpfs 453M 7.2M 446M 2% /run tmpfs 453M 0 453M 0% /sys/fs/cgroup /dev/sda1 197M 105M 93M 54% /boot tmpfs 91M 0 91M 0% /run/user/0 [root@ansible_server~]# # 简便方式写(效果一样的) [root@ansible_server~]# ansible docker -m command -a "df -h" # 能否使用shell 查看呢 ? [root@ansible_server~]# ansible docker -m shell -a "df -h" # 答案:可以查看,shell 本质上和command 区别不大,知识支持的命令更多
3.3.2 ansible 远程查看 系统时间
-
使用date 命令查看时间
# 查看docker 服务器上的时间 [root@ansible_server~]# ansible docker -m command -a "date %F" 10.0.0.7 | FAILED | rc=1 >> date: invalid date ‘%F’non-zero return code [root@ansible_server~]#
3.3.3 Ansible 远程执行下载http安装包
-
远程下载
# 先远程查看docker服务器上有没有httpd安装包 [root@ansible_server~]# ansible docker -m command -a "ls" 10.0.0.7 | CHANGED | rc=0 >> anaconda-ks.cfg # 在docker 服务器上远程下载httpd-2.4.46.tar.bz2 [root@ansible_server~]# ansible docker -m command -a "wget https://downloads.apache.org/httpd/httpd-2.4.46.tar.bz2"
3.4 ansible copy 模块实战
3.4.0 copy 模块介绍
-
模块介绍
# Ansible copy模块主要用于文件或者目录拷贝,支持文件、目录、权限、用户组功能,copy模块使用详解: # 常用参数 src Ansible端源文件或者目录,空文件夹不拷贝; content 用来替代src,用于将指定文件的内容,拷贝到远程文件内; dest 客户端目标目录或者文件,需要绝对路径; backup # 拷贝之前,先备份远程节点上的原始文件;backup=yes directory_mode 用于拷贝文件夹,新建的文件会被拷贝,而老旧的不会被拷贝; follow 支持link文件拷贝; force 覆盖远程主机不一致的内容; group 设定远程主机文件夹的组名; mode 指定远程主机文件及文件及的权限; owner 设定远程主机文件夹的用户名,拥有者。
3.4.1 将 ansible 服务器上的 httpd安装包远程考到ip为10.0.0.5 服务器上
-
远程拷贝
#将ansible 服务器上的http 安装包远程 拷贝到 10.0.0.5 服务器上,且权限设置为 755 [root@ansible_server~]# ansible -i /etc/ansible/hosts 10.0.0.5 -m command -a "ls" 10.0.0.5 | CHANGED | rc=0 >> anaconda-ks.cfg [root@ansible_server~]# ansible -i /etc/ansible/hosts 10.0.0.5 -m copy -a "src=/root/httpd-2.4.46.tar.bz2 dest=/root mode=755" 10.0.0.5 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "1b7cd10ff3a2a07a576d77e34f0204d95fa4aceb", "dest": "/root/httpd-2.4.46.tar.bz2", "gid": 0, "group": "root", "md5sum": "7d661ea5e736dac5e2761d9f49fe8361", "mode": "0755", "owner": "root", "size": 7187805, "src": "/root/.ansible/tmp/ansible-tmp-1631779035.15-12735-92572188724853/source", "state": "file", "uid": 0 } [root@ansible_server~]# # 查看10.0.0.5 文件是否拷贝成功 [root@ansible_server~]# ansible -i /etc/ansible/hosts 10.0.0.5 -m command -a "ls" 10.0.0.5 | CHANGED | rc=0 >> anaconda-ks.cfg httpd-2.4.46.tar.bz2 [root@ansible_server~]# # 查看同一个www组中的 10.0.0.6 是否也有 [root@ansible_server~]# ansible -i /etc/ansible/hosts 10.0.0.6 -m command -a "ls" 10.0.0.6 | CHANGED | rc=0 >> anaconda-ks.cfg [root@ansible_server~]#
3.5 ansible yum 模块实战
3.5.0 yum 模块介绍
-
yum 模块介绍
#Ansible yum 模块主要用于软件的安装、升级、卸载,支持红帽.rpm软件的管理,YUM模块使用详解: # 常用参数 conf_file 设定远程yum执行时所依赖的yum配置文件 disable_gpg_check 安装软件包之前是否坚持gpg key; name 需要安装的软件名称,支持软件组安装; update_cache 安装软件前更新缓存; enablerepo 指定repo源名称; skip_broken 跳过异常软件节点; state #软件包状态,包括:installed、present、latest、absent、removed。
3.5.1 ansible 服务器上 远程在 10.0.0.6 服务器上安装/启动/卸载 httpd 服务
-
远程安装/卸载
# 远程在 10.0.0.6 服务器上安装 httpd 服务 [root@ansible_server~]# ansible -i /etc/ansible/hosts 10.0.0.6 -m yum -a "name=httpd state=installed" # 远程启动 httpd 服务 [root@ansible_server~]# ansible -i /etc/ansible/hosts 10.0.0.6 -m command -a "systemctl start httpd" 10.0.0.6 | CHANGED | rc=0 >> # 远程查看http服务进程 [root@ansible_server~]# ansible -i /etc/ansible/hosts 10.0.0.6 -m shell -a "ps -ef|grep httpd" 10.0.0.6 | CHANGED | rc=0 >> root 10924 1 0 16:11 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND apache 10925 10924 0 16:11 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND apache 10926 10924 0 16:11 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND apache 10928 10924 0 16:11 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND apache 10929 10924 0 16:11 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND apache 10930 10924 0 16:11 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND root 11066 11061 0 16:12 pts/0 00:00:00 /bin/sh -c ps -ef|grep httpd root 11068 11066 0 16:12 pts/0 00:00:00 grep httpd # 停止 httpd 服务 [root@ansible_server~]# ansible -i /etc/ansible/hosts 10.0.0.6 -m command -a "systemctl stop httpd" 10.0.0.6 | CHANGED | rc=0 >> # 远程卸载 httpd [root@ansible_server~]# ansible -i /etc/ansible/hosts 10.0.0.6 -m yum -a "name=httpd state=removed"
3.5.2 将www 组服务器中的所有yum 进程都杀掉
-
停止yum 进程
# 停止正在工作的yum进程 [root@ansible_server~]# ansible www -m shell -a "pkill -yum" # 查看进程 [root@ansible_server~]# ansible www -m shell -a "ps -ef|grep yum" 10.0.0.6 | CHANGED | rc=0 >> root 12032 12027 0 09:12 pts/1 00:00:00 /bin/sh -c ps -ef|grep yum root 12034 12032 0 09:12 pts/1 00:00:00 grep yum 10.0.0.5 | CHANGED | rc=0 >> root 12260 12255 0 09:12 pts/0 00:00:00 /bin/sh -c ps -ef|grep yum root 12262 12260 0 09:12 pts/0 00:00:00 grep yum [root@ansible_server~]#
3.6 ansible file 模块实战(创建、删除、修改、权限、属性的维护和管理)
3.6.0 ansible file 模块介绍
-
file 模块介绍
# Ansible file模块主要用于对文件的创建、删除、修改、权限、属性的维护和管理,File模块使用详解: # 常用参数介绍 src Ansible端源文件或者目录; follow 支持link文件拷贝; force 覆盖远程主机不一致的内容; group 设定远程主机文件夹的组名; mode 指定远程主机文件及文件及的权限; owner 设定远程主机文件夹的用户名; path 目标路径,也可以用dest,name代替; state #状态包括:file、link、directory、hard、touch、absent; attributes 文件或者目录特殊属性。
3.6.1 在 docker 服务器上 /usr/local 目录下面创建一个rivers的目录
-
使用file模块创建目录
# 在 docker 服务器上 /usr/local 目录下面创建一个rivers的目录,名字为 rivers,属主为nginx [root@ansible_server~]# ansible docker -m file -a "path=/usr/local/rivers state=directory mode=644 owner=nginx" 10.0.0.7 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 0, "group": "root", "mode": "0644", "owner": "nginx", "path": "/usr/local/rivers", "size": 6, "state": "directory", "uid": 998 } # 查看常见的目录 [root@ansible_server~]# ansible docker -m command -a "ls /usr/local/rivers" 10.0.0.7 | FAILED | rc=2 >> # path表示目录的名称和路径, state=directory表示创建目录
3.6.2 在docker 服务器上远程创建一 脚本文件
-
远程创建文件
#在/usr/local/rivers/script.sh文件 [root@ansible_server~]# ansible docker -m file -a "path=/usr/local/rivers/script.sh state=touch mode=777" 10.0.0.7 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/usr/local/rivers/script.sh", "gid": 0, "group": "root", "mode": "0777", "owner": "root", "size": 0, "state": "file", "uid": 0 } [root@ansible_server~]# # path表示目录的名称和路径, state=touch 表示创建文件
3.7 ansible cron 模块实战
3.7.0 cron 模块介绍
-
cron 模块介绍
# Ansible cron模块主要用于添加、删除、更新操作系统Crontab任务计划,Cron模块使用详解: # 常用参数 name 任务计划名称; cron_file 替换客户端该用户的任务计划的文件; minute 分( 0-59 ,* ,*/2 ); hour 时( 0-23 ,* ,*/2 ); day 日( 1-31 ,* ,*/2 ); month 月( 1-12 ,* ,*/2 ); weekday 周( 0-6 或 1-7 ,* ); job 任何计划执行的命令,state要等于present; backup 是否备份之前的任务计划; user 新建任务计划的用户; state 指定任务计划present、absent。
3.7.1 利用cron 模块创建/删除计划任务—时间同步(阿里云)
-
基本同步用法
# docker 服务器 自动同步 阿里云 [root@ansible_server~]# ansible 10.0.0.7 -m cron -a "minute=0 hour=2 job='/usr/sbin/ntpdate ntp1.aliyun.com >/dev/null 2>&1'" [DEPRECATION WARNING]: The 'name' parameter will be required in future releases.. This feature will be removed in version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. 10.0.0.7 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [ "None" ] } # 如何删除定时任务 [root@ansible_server~]# ansible docker -m cron -a "name='#Ansible' state=absent"
3.7.2 给定时任务设置注释信息
-
添加定时任务 名称注释
# 添加注释信息 [root@ansible_server~]# ansible 10.0.0.6 -m cron -a "name='time sync' minute=0 hour=2 job='/usr/sbin/ntpdate ntp1.aliyun.com >/dev/null 2>&1'" 10.0.0.6 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [ "time sync" ] } #如何查看10.0.0.6这台服务器上的定时任务 [root@ansible_server~]# ansible 10.0.0.6 -m shell -a "cat /var/spool/cron/root" 10.0.0.6 | CHANGED | rc=0 >> #time sync by lidao at 2017-03-08 */5 * * * * /usr/sbin/ntpdate ntp.aliyun.com >/dev/null 2>&1 #Ansible: time sync 0 2 * * * /usr/sbin/ntpdate ntp1.aliyun.com >/dev/null 2>&1
3.8 ansible user 模块实战
3.8.0 模块介绍
-
user 模块介绍
# Ansible user模块主要用于操作系统用户、组、权限、密码等操作,user模块使用详解: system 默认创建为普通用户,为yes则创建系统用户; append 添加一个新的组; comment 新增描述信息; createhome 给用户创建家目录; force 用于删除强制删除用户; group 创建用户主组; groups 将用户加入组或者附属组添加; home 指定用户的家目录; name 表示状态,是否create、remove、modify; password 指定用户的密码,此处为加密密码; remove 删除用户; shell 设置用户的shell登录环境; uid 设置用户id; update_password 修改用户密码; state 用户状态,默认为present表示新建用户。absent表示删除
3.8.1 给docker 服务器创建一个用户名称 dock普通管理用户
-
创建普通用户
# 在docker 服务器上创建一个普通用户 nidaye。name=用户名,home=用户家目录 [root@ansible_server~]# ansible docker -m user -a "name=nidaye home=/home/admin" 10.0.0.7 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "comment": "", "create_home": true, "group": 1001, "home": "/home/admin", "name": "nidaye", "shell": "/bin/bash", "state": "present", "system": false, "uid": 1001 } # 查看刚新建的用户 nidaye [root@ansible_server~]# ansible docker -m shell -a "id nidaye" 10.0.0.7 | CHANGED | rc=0 >> uid=1001(nidaye) gid=1001(nidaye) groups=1001(nidaye) [root@ansible_server~]#
3.8.2 给web 服务器上的apache 服务创建/删除一个apache用户
-
创建apache用户
# 在10.0.0.5 服务器上 创建一个 名字apache ,shell /sbin/nologin 家目录为/opt [root@ansible_server~]# ansible 10.0.0.5 -m user -a "name=apache home=/opt shell=/sbin/nologin" 10.0.0.5 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "comment": "", "create_home": true, "group": 1001, "home": "/opt", "name": "apache", "shell": "/sbin/nologin", "state": "present", # 删除apache用户 [root@ansible_server~]# ansible 10.0.0.5 -m user -a "name=apache state=absent force=yes" 10.0.0.5 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "force": true, "name": "apache", "remove": false, "state": "absent" } [root@ansible_server~]#
3.9 Ansible service模块实战
3.9.0 service 模块介绍
-
service 模块介绍
# Ansible service模块主要用于远程客户端各种服务管理,包括启动、停止、重启、重新加载等,service模块使用详解: # 常用参数 enabled 是否开启启动服务; name 服务名称; runlevel 服务启动级别; arguments 服务命令行参数传递; state 服务操作状态,状态包括started, stopped, restarted, reloaded。
3.9.1 远程重启web服务器上的防火墙 服务
-
远程重启/关闭firewalld服务
# 远程重启10.0.0.5 服务器上的 firewalld 服务器 [root@ansible_server~]# ansible 10.0.0.5 -m service -a "name=firewalld state=restarted" 10.0.0.5 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "name": "firewalld", "state": "started", "status": { "ActiveEnterTimestampMonotonic": "0", "ActiveExitTimestampMonotonic": "0", "ActiveState": "inactive", …… [root@ansible_server~]# # 远程关闭防火墙 [root@ansible_server~]# ansible 10.0.0.5 -m service -a "name=firewalld state=stopped"
3.9.2 远程重启eht0 网卡(平滑启动)
-
平滑启动 10.0.0.5 服务器上的网卡
# 远程启动 eht0 网卡 [root@ansible_server~]# ansible 10.0.0.5 -m service -a "name=network args=eth0 state=restarted" [WARNING]: Ignoring "args" as it is not used in "systemd" 10.0.0.5 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "name": "network", "state": "started", "status": { "ActiveEnterTimestamp": "Fri 2021-08-27 16:30:41 CST", ……
3.9.3 远程设置nfs 开启自启动,启动级别3,5级别
-
远程设置开机自启动
# 远程开机启动nfs服务,设置3,5级别自动启动 root@ansible_server~]# ansible -k all -m service -a "name=nfs enabled=yes runlevel=3,5" SSH password: [WARNING]: Ignoring "runlevel" as it is not used in "systemd" [WARNING]: Ignoring "runlevel" as it is not used in "systemd" [WARNING]: Ignoring "runlevel" as it is not used in "systemd"
3.10 ansible synchronize 实战模块
3.10.0 synchronize 模块介绍
-
模块介绍
# Ansible synchronize模块主要用于目录、文件同步,基于Rsync命令同步目录,Synchronize模块使用详解: # 常用参数 compress 开启压缩,默认为开启; archive 是否采用归档模式同步,保证源和目标文件属性一致; checksum 是否效验; dirs 以非递归的方式传输目录; links 同步链接文件; recursive 是否递归yes/no; rsync_opts 使用rsync 的参数; copy_links 同步的时候是否复制连接; delete 删除源中没有而目标存在的文件; src 源目录及文件; dest 目标目录及文件; dest_port 目标接受的端口; rsync_path 服务的路径,指定 rsync 命令来在远程服务器上运行; rsync_timeout 指定rsync操作的IP超时时间; set_remote_user 设置远程用户名; --exclude=.log 忽略同步.log结尾的文件; mode 同步的模式,rsync同步的方式PUSH、PULL,默认都是推送push。
3.10.1 将源目录同步至目标目录(增量同步)
-
将源目录同步至目标目录(增量同步)
# 将本地/tmp 目录远程同步到 docker服务器上(增量同步) [root@ansible_server~]# ansible docker -m synchronize -a 'src=/tmp/ dest=/tmp/' 10.0.0.7 | CHANGED => { "changed": true, "cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh=/usr/bin/ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null --out-format=<<CHANGED>>%i %n%L /tmp/ 10.0.0.7:/tmp/", "msg": ".d..t...... ./\n<f+++++++++ xxx.xx\ncd+++++++++ ansible_synchronize_payload_Bxuy_S/\n<f+++++++++ ansible_synchronize_payload_Bxuy_S/ansible_synchronize_payload.zip\ncd+++++++++ vmware-root_6044-692160431/\n", "rc": 0, "stdout_lines": [ ".d..t...... ./", "<f+++++++++ xxx.xx", "cd+++++++++ ansible_synchronize_payload_Bxuy_S/", "<f+++++++++ ansible_synchronize_payload_Bxuy_S/ansible_synchronize_payload.zip", "cd+++++++++ vmware-root_6044-692160431/" ] } [root@ansible_server~]#
3.10.2 将源目录同步至目标目录(完全同步)
-
将源目录同步至目标目录(增量同步)
# 完全同步,尾巴后添加 delete=yes [root@ansible_server/tmp]# ansible docker -m synchronize -a 'src=/tmp/ dest=/tmp/ delete=yes'
四、ansible 批量管理服务
4.1 ansible 剧本 介绍
4.1.0 ansible playbook剧本介绍和基础使用说明
-
剧本介绍
# 通过Playbook任务,能够集中管理多个任务,将多个任务关联起来,从而实现更加复杂工作,满足生产环境的各个需求,提高运维人员管理服务器效率 # Playbook剧本的产物YAML文件,类似XML接口(Tomcat)文件,内部有固定语法、参数等,要掌握常用的YAML语法编写,掌握满足运维管理方向的语法即可
-
playbook 语法
# yaml 格式语法 # Playbook是以YAML格式编写的文本文件,通常使用扩展名yml保存。Playbook使用空格字符缩进来表示其数据结构。YAML对用于缩进的空格数量没有严格的要求,但有两个基本的规则: 处于层次结构中同一级别的数据元素(例如同一列表中的项目)必须具有相同的缩进量。 如果项目属于其他项目的子项,其缩进量必须大于父项 # 只有空格字符可用于缩进,不允许使用tab键。约定俗成的缩进量一般是一级2个空格。 # Playbook开头的一行由三个破折号(---)组成,这是文档开始标记。其末尾可能使用三个圆点(...)作为文档结束标记,尽管在实践中这通常会省略。
-
playbook 运行/语法检查
# 运行 lnmp文件 [root@ansible_server~]# ansible-playbook lnmp.yml # 检查lnmp 语法 [root@ansible_server~]# ansible-playbook --syntax-check lnmp.yml playbook是一个不同于使用ansible命令行执行方式的模式,功能更强大更灵活。 1、在playbooks 中常见的定义任务: name: task description #任务描述信息 module_name: module_args #需要使用的模块名字: 模块参数 files:存放需要同步到异地服务器的源码文件及配置文件; handlers:当服务的配置文件发生变化时需要进行的操作,比如:重启服务,重新加载配置文件, handlers meta:角色定义,可留空; tasks:需要进行的执行的任务; templates:用于执行lamp安装的模板文件,一般为脚本 vars:本次安装定义的变量 #playbook是由一个或多个"play"组成的列表。play的主要功能在于将事先归为一组的主机装扮成事先通过ansible中的task定义好的角色。 #github上提供了大量的实例供大家参考 https://github.com/ansible/ansible-examples
4.1.1 playbook 常见的组件及作用
- playbook 组件
- Target 定义playbook的远程主机组;
- 常用参数:
- hosts 定义远程主机组;
- user 执行该任务的用户;
- sudo 设置为yes的时候,执行任务的时候使用root权限;
- sudo_user 指定sudo普通用户;
- connection 默认基于SSH连接客户端;
- gather_facks 获取远程主机facts基础信息。
- 常用参数:
- Variable 定义playbook使用的变量;
- 常用参数:
- vars 定义格式,变量名:变量值;
- vars_files 指定变量文件;
- vars_prompt 用户交互模式自定义变量;
- setup 模块去远程主机的值;
- 常用参数:
- Task 定义远程主机上执行的任务列表;
- 常用参数:
- name 任务显示名称也即屏幕显示信息;
- action 定义执行的动作;
- copy 复制本地文件到远程主机;
- template 复制本地文件到远程主机,可以引用本地变量;
- service 定义服务的状态。
- 常用参数:
- Handler 当服务的配置文件发生变化时需要进行的操作,比如:
重启服务,重新加载配置
- Target 定义playbook的远程主机组;
4.1.2 远程主机安装httpd-2.4.46.tar.bz2 web服务案例演示
-
远程安装演示
# 通过ansible 给www组服务器里面的 10.0.0.5 这台服务器安装httpd-2.4.46.tar.bz2服务 [root@ansible_server~]# cat httpd_install.yaml #author rivers --- - hosts: 10.0.0.5 remote_user: root tasks: - name: install httpd-2.4.tar.bz2 yum: name=apr,apr-devel,apr-util,apr-util-devel,gcc-c++,bzip2 state=installed - name: apache httpd-2.4 install process shell: cd /opt/; rm -rf httpd-2.4.46.tar.bz2; wget https://downloads.apache.org/httpd/httpd-2.4.46.tar.bz2; tar xjf httpd-2.4.46.tar.bz2 -C /usr/local/; cd /usr/local/httpd-2.4.46/; ./configure --prefix=/usr/local/apache --with-pmp=worker; make -j4; make install; ...
-
检查 httpd_install.yaml 语法文件
# 检查 httpd_install.yaml 语法,下面是正确通过的 [root@ansible_server~]# ansible-playbook --syntax-check httpd_install.yaml playbook: httpd_install.yaml # 常见报错提示 [root@ansible_server~]# ansible-playbook --syntax-check httpd_install.yaml ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each: JSON: No JSON object could be decoded Syntax Error while loading YAML. mapping values are not allowed in this context The error appears to be in '/root/httpd_install.yaml': line 8, column 10, but may be elsewhere in the file depending on the exact syntax problem. The offending line appears to be: -name: install httpd-2.4.tar.bz2 yum: name=apr apr-devel apr-util apr-util-devel gcc-c++ bzip2 state=installed ^ here
-
安装 成功
4.2 playbook 企业案列实战
4.2.0 使用 ansible playbook 安装 nginx WEB服务,安装完并启动Nginx 实战
-
playbook剧本
# 判断是否安装有安装后的nginx目录,如果有直接启动,如果没有安装nginx #author rivershosts: 10.0.0.7 remote_user: root tasks: - name: install yum_package yum: name=pcre-devel,openssl,openssl-devel,gd-devel,gcc,gcc-c++ state=installed - name: echo -e "\033[44;37m 判断是否存在nginx安装目录 \033[0m" file: path=/usr/local/nginx state=directory notify: - nginx start - nginx install handlers: - name: nginx install shell: cd /opt/; rm -rf nginx-1.20.1.tar.gz; wget http://nginx.org/download/nginx-1.20.1.tar.gz; tar xf nginx-1.20 .1.tar.gz -C /usr/local/; useradd -M -s /sbin/nologin nginx; mkdir -p /var/log/nginx;cd /usr/local/nginx-1.20.1; ./confi gure --user=nginx --prefix=/usr/local/nginx --with-http_ssl_module --with-http_realip_module --with-http_image_filter_mo dule --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/ng inx/access.log --error-log-path=/var/log/nginx/error.log --without-http_rewrite_module; make && make install; /usr/local /nginx/sbin/nginx -t; - name: nginx start shell: /usr/local/nginx/sbin/nginx
4.2.1 使用ansible playbook 批量创建系统用户
-
批量创建系统用户
# 使用 user 模块批量创建rivers01、02、03用户 # author rivers - hosts: 10.0.0.7 remote_user: root tasks: - name: Add User list. user: name={{ item }} state=present with_items: - rivers01 - rivers02 - rivers03 - name: check system user shell: num= `tail -3 /etc/passwd|grep -c rivers`; if [ $num ge 3 ]; then echo is ok!; fi
五、ansible 综合应用实战 —部署lnmp架构
5.1 实验环境介绍
-
实验环境介绍
名称 系统 ip地址 部署服务 ansible_server Centos 7.6 10.0.0.61 ansible Host01 Centos 7.6 10.0.0.5 nginx+php Host02 Centos 7.6 10.0.0.6 mysql
5.1.1 使用ansible playbook 搭建一键部署lnmp架构
-
分布式部署 lnmp 架构
#编写 ansible-playbook lnmp.yaml 剧本 [root@ansible_server~]# cat lnmp_install.yaml # author # 任务1:安装nginx - hosts: 10.0.0.5 remote_user: root tasks: - name: 修改主机名,判断、安装/启动nginx shell: hostnamectl set-hostname Hosts-01 - name: install yum_package yum: name=pcre-devel,openssl,openssl-devel,gd-devel,gcc,gcc-c++ state=installed - name: echo -e "\033[44;37m 判断是否存在nginx安装目录 \033[0m" file: path=/usr/local/nginx state=directory notify: - nginx start - nginx install handlers: - name: nginx install shell: cd /opt/; rm -rf nginx-1.20.1.tar.gz; wget http://nginx.org/download/nginx-1.20.1.tar.gz; tar xf nginx-1.20.1.tar.gz -C /usr/local/; useradd -M -s /sbin/nologin nginx; mkdir -p /var/log/nginx;cd /usr/local/nginx-1.20.1; ./configure --user=nginx --prefix=/usr/local/nginx --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --without-http_rewrite_module; make && make install; /usr/local/nginx/sbin/nginx -t; - name: nginx start shell: /usr/local/nginx/sbin/nginx # 任务2 安装mysql - hosts: 10.0.0.6 remote_user: root tasks: - name: install yum_package yum: name=pcre-devel,openssl,openssl-devel,gd-devel,gcc,gcc-c++,ncurses-devel state=installed - name: 下载安装包、并解压 shell: cd /opt/; tar -xf mysql-5.1.63.tar.gz -C /usr/local/ - name: 开始编译安装 shell: cd /usr/local/mysql-5.1.63/; ./configure --prefix=/usr/local/mysql --enable-assembler; make -j8&&make -j8 install; \cp /usr/local/mysql/share/mysql/my-medium.cnf /etc/my.cnf; \cp /usr/local/mysql/share/mysql/mysql.server /etc/rc.d/init.d/mysqld; - name: 配置启动/重启 shell: chkconfig --add mysqld;chkconfig --level 35 mysqld on; service mysqld restart # 任务3 安装php - hosts: 10.0.0.5 remote_user: root tasks: - name: install php_package yum: name=libxml2,libxml2-devel,openssl,openssl-devel,bzip2,bzip2-devel,libcurl,libcurl-devel,libjpeg,libjpeg-devel,libpng,libpng-devel,freetype,freetype-devel,gmp,gmp-devel,libmcrypt,libmcrypt-devel,readline,readline-devel,libxslt,libxslt-devel,pcre-devel,ncurses,ncurses-devel,bison,cmake state=installed - name: 下载安装包、并解压 shell: cd /opt/; wget http://mirrors.sohu.com/php/php-7.2.10.tar.gz; tar xf php-7.2.10.tar.gz -C /usr/local/; cd /usr/local/php-7.2.10/; ./configure --prefix=/usr/local/php --disable-fileinfo --enable-fpm --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-openssl --with-zlib --with-curl --enable-ftp --with-gd --with-xmlrpc --with-jpeg-dir --with-png-dir --with-freetype-dir --enable-gd-native-ttf --enable-mbstring --with-mcrypt=/usr/local/libmcrypt --enable-zip --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-mysql-sock=/var/lib/mysql/mysql.sock --without-pear --enable-bcmath; make && make install; ln -s /usr/local/php/bin/* /usr/local/bin/; \cp php.ini-production /etc/php.ini; \cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf; \cp /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf; \cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm; chmod +x /etc/init.d/php-fpm; chkconfig --add php-fpm - name: 启动php服务 shell: systemctl start php-fpm
5.1.2 整合 lnmp 架构、进行测试
-
修改nginx 配置文件
# 修改 /usr/local/nginx/conf/nginx.conf 文件 # 1.将user 改为 nginx # 2.添加一下内容 location / { root html; index index.php index.html index.htm; } location ~ \.php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name; include fastcgi_params; } # 设置php 网站文件 vim /usr/local/nginx/html/index.php [root@hosts-01/usr/local/nginx/html]# cat index.php <?php phpinfo(); ?> [root@hosts-01/usr/local/nginx/html]# # 重启nginx 服务 /usr/local/nginx/sbin/nginx
-
浏览器输入 10.0.0.5 访问测试
六、ansible 调优
6.1 ansible 配置文件详解
-
配置文件说明
# Ansible默认配置文件为/etc/ansible/ansible.cfg,配置文件中可以对ansible进行各项参数的调整,包括并发线程、用户、模块路径、配置优化等,如下为Ansible.cfg常用参数详解: [defaults] 通用默认配置段; inventory = /etc/ansible/hosts 被控端IP或者DNS列表; library = /usr/share/my_modules/ Ansible默认搜寻模块的位置; remote_tmp = $HOME/.ansible/tmp Ansible远程执行临时文件; pattern = * 对所有主机通信; forks = 5 并行进程数; poll_interval = 15 回频率或轮训间隔时间; sudo_user = root sudo远程执行用户名; ask_sudo_pass = True 使用sudo,是否需要输入密码; ask_pass = True 是否需要输入密码; transport = smart 通信机制; remote_port = 22 远程SSH端口; module_lang = C 模块和系统之间通信的语言; gathering = implicit 控制默认facts收集(远程系统变量); roles_path= /etc/ansible/roles 用于playbook搜索Ansible roles; host_key_checking = False 检查远程主机密钥; #sudo_exe = sudo sudo远程执行命令; #sudo_flags = -H 传递sudo之外的参数; timeout = 10 SSH超时时间; remote_user = root 远程登陆用户名; log_path = /var/log/ansible.log 日志文件存放路径; module_name = command Ansible命令执行默认的模块; #executable = /bin/sh 执行的Shell环境,用户Shell模块; #hash_behaviour = replace 特定的优先级覆盖变量; #jinja2_extensions 允许开启Jinja2拓展模块; #private_key_file = /path/to/file 私钥文件存储位置; #display_skipped_hosts = True 显示任何跳过任务的状态; #system_warnings = True 禁用系统运行ansible潜在问题警告; #deprecation_warnings = True Playbook输出禁用“不建议使用”警告; #command_warnings = False command模块Ansible默认发出警告; #nocolor = 1 输出带上颜色区别,开启/关闭:0/1; pipelining = False 开启pipe SSH通道优化; [accelerate] accelerate缓存加速。 accelerate_port = 5099 accelerate_timeout = 30 accelerate_connect_timeout = 5.0 accelerate_daemon_timeout = 30 accelerate_multi_key = yes
6.2 ansible 常见优化介绍
6.1.1 关闭ssh 密钥检测
-
关闭ssh 检测密钥
# 在ansible 配置文件中加入以下代码: host_key_checking = False 12
6.1.2 openssh 连接优化
-
关闭DNS解析
# 使用OpenSSH服务时,默认服务器端配置文件UseDNS=YES状态,该选项会导致服务器根据客户端的IP地址进行DNS PTR反向解析,得到客户端的主机名,然后根据获取到的主机名进行DNS正向A记录查询,并验证该IP是否与原始IP一致。关闭DNS解析 sed -i '/^GSSAPI/s/yes/no/g;/UseDNS/d;/Protocol/aUseDNS no' /etc/ssh/sshd_config /etc/init.d/sshd restart
6.1.3 加速 ansible 优化
-
SSH pipelining加速Ansible
# SSH pipelining是一个加速 Ansible 执行速度的简单方法,SSH pipelining 默认是关闭的,关闭是为了兼容不同的 sudo 配置,主要是requiretty 选项。 如果不使用Sudo建议开启该选项,打开此选项可以减少Ansible 执行没有文件传输时,SSH在被控机器上执行任务的连接数。使用Sudo操作的时候, 必须在所有被管理的主机上将配置文件/etc/sudoers中requiretty选项禁用。 sed -i '/^pipelining/s/False/True/g' /etc/ansible/ansible.cfg
总结
在里小编想说,其实ansible 不难,工具比较简单,其中的shell 模块是万能的模块,所以,如果其他模块掌握不好,那就用shell 去实现,小编写这篇文章花费了3天左右,通过构思、实践,完整的走了一遍,如果当你读到这篇文章后,请认真看完,因为这是运维必备的技能。
日常运维中,还有很多细节需要注意,这里不做过多描述,当然这里介绍的并不是非常全,往后的学习中,还是要多去查看官网的说明文档,上面介绍的最详细,最权威。学习是一个漫长的过程,如果你想从事运维行业,能参加一个好点的培训机构最好,如果经济有限,不想花钱,也可以自学,买一本好点的书籍,看一套完整的视频,然后做实验,反复去练习。同时如果对我的云计算专栏感兴趣,也可以订阅我的专栏,进行学习。
以梦为马,不负韶华,流年笑掷,未来可期 !
—黄昏
作者介绍
🍊 博客主页:作者主页
🍊 简介:云计算领域优质创作者🏆、何学长 公众号创作者🎓、在校期间参与众多计算机相关的省赛、国赛,斩获系列荣誉。考取华为资深工程师、红帽工程师等系列认证。
让生命像一团热烈燃烧的火,直到死亡才能使它熄灭
Ansible常用模块详解(附各模块应用实例和Ansible环境安装部署)
白幽幽白 已于 2023-10-27 10:03:37 修改
一、Ansible
1.1 简介
Ansible是自动化运维工具,能实现跨主机对应用编排管理部署。
Ansible能批量配置、部署、管理上千台主机,是应用级别的跨主机编排工具。
比如以前需要切换到每个主机上执行的一或多个操作,使用Ansible只需在固定的一台Ansible控制节点上去完成所有主机的操作。
1.2 工作原理
基于模块工作,通过模块实现在被控制节点上执行相应的命令操作。
1.3 Ansible的特性
1.3.1 特性一:Agentless,即无Agent的存在
1)无客户端agent存在,不需要在被控制的节点上安装额外的客户端应用;
2)通过ssh协议与被控制节点通信。
1.3.2 特性二:幂等性
所谓幂等性,指的是无论执行多少次同样的运算,结果都是相同的,即一条命令,任意多次执行所产生的影响均与一次执行的影响相同。
Ansible的很多模块具有幂等性,如果多次模块操作的状态没有发生改变,则不会重复执行。
1.4 Ansible的基本组件
- Inventory:Ansible管理的主机清单
/etc/anaible/hosts
,需要管理的服务清单 ; - Modules:Ansible执行命令的功能模块,多数为内置核心模块,也可自定义;
- Plugins:模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用;
- API:供第三方程序调用的应用程序编程接口。
- Playbook:基于YAML格式的文件,用于定义和描述一系列任务。
二、Ansible环境安装部署
角色 | IP | 安装工具 |
---|---|---|
管理端 | 192.168.2.100 | ansible |
被管理端1 | 192.168.2.102 | 无需安装 |
被管理端2 | 192.168.2.103 | 无需安装 |
2.1 安装ansible
在管理端安装 ansible。
#先安装 epel 源
yum install -y epel-release
#yum安装ansible
yum install -y ansible```
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/5199c32e1fc4b7102da2e2cd7f9f648e.png =900x)
```bash
#可选操作,修改被管理端的主机名,方便管理区分
hostnamectl set-hostname webserver
hostnamectl set-hostname dbserver```
### 2.2 查看基本信息
```bash
ansible --version```
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/1c910b9b43dd9351ad5ba60fce1bc1c2.png =900x)
```bash
#查看ansible 目录结构
tree /etc/ansible
├── ansible.cfg #ansible的配置文件,一般无需修改
├── hosts #ansible的主机清单,用于存储需要管理的远程主机的相关信息
└── roles/ #公共角色目录```
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/05edd66ab03cdbc4787841e601d14a98.png =900x)
### 2.3 配置远程主机清单
```bash
cd /etc/ansible
vim hosts
[webservers] #配置组名
192.168.2.102 #组里包含的被管理的主机IP地址或主机名(主机名需要先修改/etc/hosts文件)
[dbservers]
192.168.2.103```
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/537ec221ca56810cf2c01d572b7ea4c0.png =900x)
```bash
#配置密钥对验证
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
yum install -y sshpass
#免密登录测试,以被管理端1为例
ssh 192.168.2.102```
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d3606db90415c08669ad1ca343663612.png =900x)
## 三、Ansible的模块(很重要)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/02c84d944b45b3a2732900a988e933dc.png =900x)
### 3.1 ansible的命令格式
```bash
#ansible命令格式
ansible 组名 -m 模块名 -a '参数'
#-a 用于向模块传递参数
#查看当前系统中的ansible模块
ansible-doc -l```
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/106e0bd6de5ac1bf7ba6a3c81c47aafd.png =900x)
```bash
#查看特定模块的摘要信息
ansible-doc -s <module_name>```
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/a7a8179118993c8bccb7f5fd63e64d56.png =900x)
### 3.2 Command模块
功能:在远程主机执行命令,此为默认模块,可忽略 `-m` 选项。
注意:此命令不支持 $VARNAME < > | ; & 等,即不支持管道符、重定向符号。
注意:此模块不具有幂等性
#### 3.2.1 基本格式和常用参数
```bash
#基本格式
ansible <组名/IP> [-m command] -a '[参数] 命令'```
| 常用参数 | 功能 |
| -------- | ------------------------------------------------ |
| chdir | 在远程主机上运行命令前,提前进入目录 |
| creates | 判断指定文件是否存在,如果存在,不执行后面的操作 |
| removes | 判断指定文件是否存在,如果存在,执行后面的操作 |
#### 3.2.2 举个例子
```bash
#指定组/IP执行命令
ansible 192.168.2.102 -m command -a 'date'
ansible webservers -a 'date'
#忽略-m选项,默认使用command格式```
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/ab63ea0b3ebc1cbf32f8d9f6fe93459f.png =900x)
```bash
#chdir参数
ansible all -m command -a "chdir=/home ls ./"```
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/3ff6ed53fec771860fdc820328d9fac1.png =900x)
```bash
#creates参数
ansible all -m command -a "creates=/opt/test.txt ls ./"```
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/4847df613592e2261db0fdf7346d583e.png =900x)
```bash
#removes参数
ansible all -m command -a "removes=/opt/test.txt ls ./"```
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/2dcc0570c669a9950caf0ab60ae7483a.png =900x)
### 3.3 shell模块
功能:和command模块类似,在远程主机执行命令,相当于调用远程主机的shell进程,然后在该shell下打开一个子shell运行命令。
注意:此模块不具有幂等性
注意:此模块支持管道符号等功能
#### 3.3.1 基本格式和常用参数
```bash
ansible <组/IP/all> -m shell -a ' '```
| 常用参数 | 功能 |
| -------- | ------------------------------------------------ |
| chdir | 在远程主机上运行命令前,提前进入目录 |
| creates | 判断指定文件是否存在,如果存在,不执行后面的操作 |
| removes | 判断指定文件是否存在,如果存在,执行后面的操作 |
#### 3.3.2 举个例子
```bash
#shell模块能够使用管道符
ansible dbservers -m shell -a "ifconfig | awk 'NR==2 {print \$2}'"```
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/f426d15428e3a1110fdb0f8741ad643e.png =900x)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/66e6db5fb42abfdd49c4d4c1b16cbf97.png =900x)
### 3.4 cron模块
功能:在远程主机定义crontab任务计划。
```bash
ansible-doc -s cron #按 q 退出```
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/93fb1d02d3b3b2eec910bd3bdd354117.png =900x)
#### 3.4.1 基本格式和常用参数
```bash
#基本格式
ansible <组/IP/all> -m cron -a ' '
常用参数 | 功能 |
---|---|
minute/hour/day/month/weekday | 分/时/日/月/周 |
job | 任务计划要执行的命令 |
name | 任务计划的名称 |
user | 指定计划任务属于哪个用户,默认是root用户 |
state | present表示添加(可以省略),absent表示移除。 |
3.4.2 举个例子
1)周一到周五早八点半和晚八点半 执行 复制/var/log/messages 到 /opt
ansible dbservers -m cron -a 'minute=30 hour="8,20" weekday="1-5" job="/usr/bin/cp -f /var/log/message /opt" name="backup1"'
2)每两个月的5 15 25 执行复制
ansible webservers -m cron -a 'day="5-25/10" month="*/2" job="/usr/bin/cp -f /var/log/message /opt" name="backup1"'
5-15/10 #隔十天
3)删除
指定状态为absent就行
ansible webservers -m cron -a 'name="backup1" state=absent'
3.5 user模块
功能:在远程主机管理用户账户
3.5.1 基本格式和常用参数
ansible <组/IP/all> -m user -a ' '
常用参数 | 功能 |
---|---|
name | 用户名,必选参数 |
state=present|absent | 创建账号或者删除账号,present表示创建,absent表示删除 |
system=yes|no | 是否为系统账号 |
uid | 用户uid |
group | 用户基本组 |
groups | 用户所属附加组 |
shell | 默认使用的shell |
create_home=yes|no | 是否创建家目录 |
password | 是否用户的密码,建议使用加密后的字符串 |
remove=yes|no | 当state=absent时,是否删除用户的家目录 |
3.5.2 举个例子
ansible dbservers -m user -a 'name="test01"' #创建用户test01
ansible dbservers -m command -a 'tail -n1 /etc/passwd'
ansible dbservers -m user -a 'name="test01" state=absent' #删除用户test01
ansible dbservers -a 'tail -n1 /etc/passwd'
3.6 group模块
功能:在远程主机进行用户组管理的模块
3.6.1 常用参数
ansible <组/IP/all> -m group -a ' '
name:用户名,必选参数
state=present|absent:创建账号或者删除账号,present表示创建,absent表示删除
system=yes|no:是否为系统账号
gid:组id
3.6.2 举个例子
ansible dbservers -m group -a 'name=mysql gid=306 system=yes' #创建mysql组
ansible dbservers -m user -a 'name=test01 uid=306 system=yes group=mysql' #将test01用户添加到mysql组中
ansible dbservers -a 'id test01'
3.7 copy模块 (面试常问)
功能:从ansible服务器主控端复制文件到远程主机
注意:src=file 如果是没指明路径,则为当前目录或当前目录下的files目录下的file文件
3.7.1 基本格式和常用参数
#基本格式
ansible < > -m copy -a 'src= dest= [owner= ] [mode=] '
常用参数 | 功能 | 注意事项 |
---|---|---|
src | 指出源文件的路径,可以使用相对路径或绝对路径,支持直接指定目录 | 如果源是目录则目标也要是目录 |
dest | 指出复制文件的目标及位置,使用绝对路径 | 如果源是目录,指目标也要是目录,如果目标文件已经存在会覆盖原有的内容 |
mode | 指出复制时,目标文件的权限 | |
owner | 指出复制时,目标文件的属主 | |
group | 指出复制时,目标文件的属组 | |
content | 指出复制到目标主机上的内容 | 不能与src一起使用 |
3.7.2 举个例子
ansible dbservers -m copy -a 'src=/etc/fstab dest=/opt/fstab.bak owner=root mode=640'
ansible dbservers -a 'ls -l /opt'
ansible dbservers -a 'cat /opt/fstab.bak'
ansible dbservers -m copy -a 'content="helloworld" dest=/opt/hello.txt'
#将helloworld写入/opt/hello.txt文件中
ansible dbservers -a 'cat /opt/hello.txt'
3.8 file模块
功能:在远程主机管理文件属性、创建软链接等
3.8.1 常用参数
#基本格式
ansible < > -m file -a ''
常用参数 | 功能 |
---|---|
path | 指定远程服务器的路径,也可以写成"dest",“name” |
state | 状态,可以将值设定为directory表示创建目录,设定为touch表示创建文件,设定为link表示创建软链接,设定为hard表示创建硬连接,设定为absent表示删除目录文件或链接 |
mode | 文件复制到远程并设定权限,默认file=644,directory=755 |
owner | 文件复制到远程并设定属主,默认为root |
group | 文件复制到远程并设定属组,默认为root |
recurese | 递归修改 |
src | 指的是目标主机上的源文件。与copy模块不同。 |
3.8.2 举个例子
#修改文件的属主属组权限等
ansible dbservers -m file -a 'owner=test01 group=mysql mode=644 path=/opt/fstab.bak'
#软连接 state=link
ansible dbservers -m file -a 'path=/opt/fstab.link src=/opt/fstab.bak state=link'
#创建一个空文件,state=touch
ansible dbservers -m file -a "path=/opt/abc.txt state=touch"
#创建一个空目录,state=directory
ansible dbservers -m file -a "path=/data state=directory"
#删除一个文件,state=absent
ansible dbservers -m file -a "path=/opt/abc.txt state=absent"
ansible dbservers -a 'removes=/opt/abc.txt ls ./'
3.9 hostname模块
功能:用于管理远程主机上的主机名
#修改主机名
ansible dbservers -m hostname -a "name=mysql01"
3.10 ping模块
功能:测试远程主机的连通性。
ansible all -m ping
3.11 yum/apt 模块
功能:在远程主机上安装与卸载软件包
常用参数 | 功能 |
---|---|
name | 需要安装的服务名 |
state=present(缺省值)/absent | 状态,abasent表示卸载服务 |
ansible webservers -m yum -a 'name=httpd' #安装服务
#卸载服务
ansible webservers -m yum -a 'name=httpd state=absent'
3.12 service/systemd 模块
功能:用于管理远程主机上的管理服务的运行状态。
常用参数 | 功能 |
---|---|
name | 指定需要控制的服务名称 |
state | 指定服务状态,其值可以为stopped、started、reloaded、restarted、status |
enabled | 指定服务是否为开机启动,yes为启动,no为不启动 |
daemon_reload | yes:重启systemd服务,让unit文件生效 |
#先安装服务
ansible webservers -m yum -a 'name=httpd'
#启动httpd服务
ansible webservers -m service -a 'enabled=true name=httpd state=started'
#查看web服务器httpd运行状态
ansible webservers -a 'systemctl status httpd'
3.13 script 模块
功能:在远程主机执行shell脚本。
注意:script模块不具有幂等性,所以建议用剧本来执行。
#在本地写一个脚本
vim test.sh
#!/bin/bash
echo "hello ansible from script" > /opt/test2.txt、
chmod +x test.sh #给脚本执行权限
ansible dbservers -m script -a '/opt/test.sh' #远程运行本地脚本
ansible dbservers -a 'cat /opt/test2.txt' #查看生成的文件内容
3.14 mount 模块
功能:在远程主机挂载目录/设备文件
常用参数 | 功能 |
---|---|
src | 指定要挂载的设备或分区路径。 |
path | 指定要挂载到的目标路径。 |
fstype | 指定要挂载的文件系统类型。 |
state | 指定挂载状态,可选值为 mounted 、unmounted 或 absent 。 |
opts | 指定挂载选项,例如挂载选项或参数。 |
ansible dbservers -m mount -a 'src=/dev/sr0 path=/mnt state=mounted fstype=iso9660'
#使用 Ansible 的 mount 模块将设备 /dev/sr0 的内容挂载到目标路径 /mnt。
#文件系统类型为 iso9660,并将该设备标记为已挂载状态
3.15 archive 模块
功能:在远程主机压缩文件。
3.15.1 常用参数
常用参数 | 功能 |
---|---|
path | 指定要打包的源目录或文件的路径。 |
dest | 指定打包文件的输出路径。 |
format | 指定打包文件的格式,可以是 zip 、tar 、gz 或 bzip2 。默认为 tar 格式。 |
remove | 指定是否在打包文件之后,删除源目录或文件。可选值为 yes 或 no 。默认为 no ,即不删除源目录或文件。 |
3.15.2 举个例子
ansible dbservers -m archive -a "path=/etc/yum.repos.d/ dest=/opt/repo.zip format=zip"
#remove参数的使用,压缩后删除源文件
3.16 unarchive 模块
功能:将本地或远程主机的压缩包在远程主机解压缩 。
3.16.1 常用参数
常用参数 | 功能 |
---|---|
copy | 指定是否将打包文件复制到远程节点以进行解压缩。 |
remote_src | (已弃用)改用 copy 参数。 |
src | 指定要解压缩的打包文件路径,可以是本地路径或远程路径。 |
dest | 指定要将文件解压缩到的目标目录。 |
creates | 指定一个文件路径,如果该文件已经存在,则不进行解压缩操作。 |
remote_tmp | 用于制定远程节点上的临时目录。默认为 /tmp 。 |
#copy参数
copy参数的可选值为 `yes` 或 `no`。
默认为 `yes`,即先将文件从控制节点复制到远程节点,然后在远程节点上进行解压缩。
如果已经将文件分发到了目标节点并想要提高效率,可以将该值设置为 `no`。
反效果的参数为 `remote_src`。
3.16.2 举个例子
#现在ansible主机建立压缩包
tar cf test.tar.gz test.sh
#将 ansible 主机的压缩文件拷贝到到远程主机并解压,修改文件所属组和用户
ansible dbservers -m unarchive -a "src=/opt/test.tar.gz dest=/root copy=yes"
3.17 replace 模块
功能:在远程主机修改文件内容 。
类似于sed命令,主要也是基于正则进行匹配和替换。
3.17.1 常用参数
常用参数 | 功能 |
---|---|
path | 指定需要处理的文件路径 |
regexp | 用于匹配需要替换内容的正则表达式 |
replace | 用于替换匹配内容的字符串 |
after | 在哪个字符串之后进行替换,默认为空 |
before | 在哪个字符串之前进行替换,默认为空 |
backup | 是否备份文件,选项为 yes 或 no |
3.17.2 举个例子
#在db服务器的主机下创建测试文件
vim /opt/test.txt
11 22 33 44 55 66
aa bb cc dd ee ff
1a 2b 3c 4d 5e 6f
#匹配 33 并修改为 ccc
ansible dbservers -m replace -a "path=/opt/test.txt regexp='33' replace='cc'"
#查看
ansible dbservers -a "cat /opt/test.txt"
#匹配到任意一个或多个开头的行增加注释
ansible dbservers -m replace -a "path=/opt/test.txt regexp='^(.*)' replace='#\1'"
#取消注释
ansible dbservers -m replace -a "path=/opt/test.txt regexp='^#(.*)' replace='\1'"
#匹配以 a 开头的后面有一个或者多个字符的行,并在前面添加 # 注释
ansible dbservers -m replace -a "path=/opt/test.txt regexp='^(a.*)' replace='#\1'"
3.18 setup 模块
功能:使用facts组件获取远程主机的系统信息(facts信息)
常用参数 | 功能 |
---|---|
filter | 指定需要过滤的条件,仅返回满足条件的主机信息,默认为空 |
ansible webservers -m setup #获取mysql组主机的facts信息
ansible dbservers -m setup -a 'filter=*ipv4' #使用filter可以筛选指定的facts信息
facts信息
主机的各种信息,包括硬件、操作系统、网络等。
运行命令后,会返回一个包含主机 facts 信息的 JSON 格式输出。
从入门到精通Ansible Playbook,一篇就够了
白幽幽白 于 2023-10-28 12:33:41 发布
一、Host Inventory(主机清单)
1.1 简介
Inventory支持对主机进行分组,每个组内可以定义多个主机,每个主机都可以定义在任何一个或多个主机组内。
1.2 inventory 文件
默认路径为/etc/ansible/hosts
Ansible Inventory 文件是一个纯文本文件,用于定义 Ansible 执行命令的目标主机和组,以及这些主机和组的变量和属性。
Inventory 文件的构成包括:
1)主机与组
-
主机:一个主机就是目标机器,可以是 [IP 地址](https://so.csdn.net/so/search?q=IP 地址&spm=1001.2101.3001.7020)、域名或在 SSH 配置中定义的别名,也可以使用
ansible_host
指定。 -
组:可以将多个主机划分到同一个组中,并可以对组进行操作。
示例:
[WebServer]
192.168.1.10
192.168.1.11
192.168.1.12
[DatabaseServer]
192.168.1.20
192.168.1.21
注意:组名不能包含空格,并且主机和组名必须放在方括号中。
2)变量
-
主机变量:为单个主机指定变量,使用主机名或 IP 地址作为标识符,变量可以设置为一个或多个值。
示例:
[ServerA]
192.168.1.10 http_port=80 https_port=443
[ServerB]
- 组变量:在组名之后,使用
vars
关键字设置变量,可以在组间共享变量。示例:
#所有主机指定 `ansible_ssh_user` 变量,这意味着每个主机都具有该变量。
#为每个主机定义唯一的 `name` 变量。
[WebServer]
192.168.1.10 name=webserver1
192.168.1.11 name=webserver2
192.168.1.12 name=webserver3
[DatabaseServer]
192.168.1.20 name=dbserver1
192.168.1.21 name=dbserver2
[all:vars]
ansible_ssh_user=centos
3)组的嵌套
将一个组嵌套到另一个组中,在 Inventory 文件中使用 :children
关键字。
示例:
#将 `WebServer` 和 `DatabaseServer` 组嵌套到 `Production` 组中。
[WebServer]
192.168.1.10
192.168.1.11
192.168.1.12
[DatabaseServer]
192.168.1.20
[Production:children]
WebServer
DatabaseServer
4)别名
使用 Alias(别名)来引用 Inventory 中的主机。
示例:
#为 `WebServer` 和 `DatabaseServer` 组定义别名,并将它们作为两个分离的组 `Web` 和 `Db` 的成员
#创建了一个名为 `Production` 的组,该组由这两个组的别名组成。
[WebServer]
192.168.1.10
192.168.1.11
192.168.1.12
[DatabaseServer]
192.168.1.20
[Web:children]
WebServer
[Db:children]
DatabaseServer
[Production]
@Web
@Db
1.2 inventory 中的变量
在 hosts 文件
中为主机或组定义变量,在 playbook 中
可以直接调用变量。
Inventory 变量名 | 含义 |
---|---|
ansible_host | ansible 连接节点时的 IP 地址 |
ansible_port | 连接对方的端口号,ssh 连接时默认为 22 |
ansible_user | 连接对方主机时使用的用户名。不指定时,将使用执行 ansible 或 ansible-playbook 命令的用户 |
ansible_password | 连接时的用户的 ssh 密码,仅在未使用密钥对验证的情况下有效 |
ansible_ssh_private_key_file | 指定密钥认证 ssh 连接时的私钥文件 |
ansible_ssh_common_args | 提供给 ssh、sftp、scp 命令的额外参数 |
ansible_become | 允许进行权限提升 |
ansible_become_method | 指定提升权限的方式,例如可使用 sudo/su/runas 等方式 |
ansible_become_user | 提升为哪个用户的权限,默认提升为 root |
ansible_become_password | 提升为指定用户权限时的密码 |
举个例子
1)首先定义一个 my_port
变量,其值为 http_port
变量;
2)然后使用 uri
模块检查 defined myserver
主机上特定端口的服务是否运行,并将结果存储在 result
变量中;
3)最后使用 debug
模块输出该服务的响应内容。
#编辑清单文件,定义变量
vim /etc/ansible/hosts
[webservers]
192.168.2.102 ansible_host=192.168.2.102 http_port=8080
#在 playbook 中,用 `vars` 字段来使用变量:
- name: Example playbook using inventory variable
hosts: webservers
tasks:
- name: Ping the web server
uri:
url: "http://{{inventory_hostname}}:{{http_port}}"
return_content: yes
register: result
- name: Show the response
debug:
var: result.content
二、Playbook 剧本
2.1 简介
Playbook 剧本是由一个或多个play
组成的列表。
play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。
Task实际是调用ansible的一个module,将多个play组织在一个playbook中,即可以让它们联合起来,按事先编排的机制执行预定义的动作
Playbook 文件是采用YAML语言编写的。
2.2 Playbook的组成部分
1)Tasks:任务,即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行;
2)Variables:变量;
3)Templates:模板;
4)Handlers:处理器,当changed状态条件满足时,(notify)触发执行的操作;
5)Roles:角色。
2.3 如何编写Playbook?
2.3.1 基本格式
- 在单一文件第一行,用连续三个连字号“-” 开始,还有选择性的连续三个点号( … )用来表示文件的结尾;
- 次行开始正常写Playbook的内容,一般建议写明该Playbook的功能;
- 使用#号注释代码;
- 缩进必须是统一的,不能空格和tab混用;
- 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的;
YAML文件内容是区别大小写的,key/value的值均需大小写敏感; - 多个key/value可同行写也可换行写,同行使用,分隔;
- v可是个字符串,也可是另一个列表;
- 一个完整的代码块功能需最少元素需包括 name 和 task;
- 一个name只能包括一个task;
- YAML文件扩展名通常为yml或yaml
xxx.yaml/xxx.yml
--- #表示开始
- name: #指定play的名称
hosts: #指定主机清单中定义的主机组名
remote_user: #指定远程主机的执行用户
grather_facts: ture|fales #指定是否要收集远程主机的facts信息
vars: #自定义变量,只能在当前play有效
- 变量1: 值1 #格式为key: value
- 变量2: 值2
tasks: #定义任务列表,默认从上往下依次执行
- name: #定义任务的名称
模块名: 模块参数
ignore errors: true #忽略任务的失败
- name: #可以定义多个任务
模块名: 模块参数
notify: 任务名 #如以上操作后为changed的状态时,会通过notify指定的名称触发对应名称的handlers操作
##条件判断##
- name:
模块名: 模块参数
when: #定义条件表达式(== != > < >= <=),条件成立时执行此task任务,否则不执行任务
##循环##
- name:
模块名: 模块参数={{item}}
with_items: #定义循环列表
##tags模块,标签##
- name:
模块名: 模块参数
tags:
- 标签1
- 标签2
handlers:
- name: 任务名 #和notify中的任务名相同
模块名: 模块参数
#无注释版
---
- name:
hosts:
remote_user:
grather_facts: ture|fales
vars:
- 变量1: 值1
- 变量2: 值2
tasks:
- name:
模块名: 模块参数
ignore errors: true
- name:
模块名:
notify: 任务名
- name:
模块名:
when:
- name:
模块名: 模块参数={{item}}
with_items:
handlers:
- name: 任务名
模块名: 模块参数
Ansible在执行完某个任务之后并不会立即去执行对应的handler,而是在当前play中所有普通任务都执行完后再去执行handler。
这样的好处是可以多次触发notify,但最后只执行一次对应的handler,从而避免多次重启。
2.3.2 语句的横向/纵向写法
横向写法一般是数组类型
纵向写法一般是列表类型
task任务的模块语法格式
横向格式:
模块名: 参数1=值 参数2={{变量名}} ...
纵向格式:
模块名:
参数1: 值
参数2: "{{变量名}}"
...
with_items 和 vars 的语法格式
横向格式:
with_items: ["值1", "值2", "值3", ...]
值为对象(键值对字段)时:
with_items:
- {key1: "值1", key2: "值2"}
- {key1: "值3", key2: "值4"}
...
纵向格式:
with_items:
- 值1
- 值2
- 值3
...
值为对象(键值对字段)时:
with_items:
- key1: "值1"
key2: "值2"
- key1: "值3"
key2: "值4"
...
三、Playbook实例和知识点补充
3.1 编写yum安装nginx的playbook
1.先更新主机清单
2.编写剧本
cd /etc/ansible
#编写yaml文件,安装nginx的剧本
vim test.yaml
---
- name: first play
hosts: dbservers
remote_user: root
gather_facts: false
tasks:
- name: firewalld
service: name=firewalld state=stopped enabled=no
- name: selinux
command: '/usr/sbin/setenforce 0 '
ignore_errors: true
- name: mount
mount: src=/dev/sr0 path=/mnt state=mounted fstype=iso9660
- name: local.repo
copy: src=/etc/yum.repos.d/local.repo dest=/etc/yum.repos.d/
- name: epel.repo
copy: src=/etc/yum.repos.d/epel.repo dest=/etc/yum.repos.d/
- name: nginx install
yum: name=nginx state=latest
- name: configuration file
copy: src=/usr/local/nginx/conf/nginx.conf dest=/etc/nginx/nginx.conf
notify: "reload nginx"
- name: start nginx
service: name=nginx state=started enabled=yes
handlers:
- name: reload nginx
service: name=nginx state=reloaded
3.运行剧本
ansible-playbook test.yaml```
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e88c175047afdbf5176cd9c88606bde5.png =900x)
> 4.查看db服务器组的主机
```bash
systemctl status firewalld
getenforce
systemctl status nginx
3.2 参数补充
#执行playbook
ansible-playbook xx.yaml/yml [参数]```
| `常用参数` | `描述` | |
| :---- | :--- | :--- |
| `--syntax-check` | 检查yaml文件的语法是否正确 | |
| `--list-task` | 检查tasks任务 | |
| `--list-hosts` | 检查生效的主机 | |
| `--start-at-task=' name ' ` | 指定从某个task开始运行 | 一般用于剧本较长且不想从头重复执行的场景 |
| `-k` | 用来交互输入ssh密码 | `-ask-pass` |
| `-K` | 用来交互输入sudo密码 | `-ask-become-pass` |
| `-u` | 指定用户 | |
```bash
#检查yaml文件的语法是否正确
ansible-playbook test.yaml --syntax-check ```
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/c7f4745546180adaca64b0a9edd57e7b.png =900x)
```bash
#检查tasks任务
ansible-playbook test.yaml --list-task ```
```bash
#检查生效的主机
ansible-playbook test.yaml --list-hosts
#指定从 nginx install 开始运行
ansible-playbook test.yaml --start-at-task='nginx install'
3.3 变量的定义和引用
vars: #自定义变量,只能在当前play有效
- 变量1: 值1 #格式为key: value
- 变量2: 值2
tasks: #在任务列表中引用变量
-name:
module: {{变量1}}
方式一:在yaml文件中定义和引用
vim test2.yml
---
- name: second play
hosts: dbservers
remote_user: root
gather_facts: true
vars:
- groupname: mysql
- username: nginx
tasks:
- name: create group
group: name={{groupname}} system=yes gid=306 #使用 {{key}} 引用变量的值
- name: create user
user: name={{username}} uid=306 group={{groupname}}
- name: copy file
copy: content="{{ansible_default_ipv4.network}}" dest=/opt/vars.txt #在setup模块中可以获取facts变量信息
#ansible_default_ipv4为facts变量信息中的字段
#ansible_default_ipv4.network中的 .network表示只提取信息中network部分
ansible-play test2.yml
方式二:在命令行定义
ansible-playbook test1.yaml -e "username=nginx"
#通过 -e 参数传递一个额外的变量 "username=nginx" 给 playbook
#playbook 将会使用变量 "username" 的值设置为 "nginx"
3.4 指定远程主机sudo切换用户
使用-k
和 -K
参数实现。
1)先编写剧本
vim test2.yaml
---
- hosts: webservers
remote_user: test2
become: yes #2.6版本以后的参数,之前是sudo,意思为切换用户运行
become_user: root #指定sudo用户为root
tasks:
- name: ts
command: ls ./
2)执行剧本
#执行playbook,加上参数-k和-K
ansible-playbook test2.yml -k -K
3.5 when条件判断
3.5.1 用法
在Ansible中,提供的唯一一个通用的条件判断是when指令
。
当when指令的值为true
时,则该任务执行,否则不执行该任务。
When指令一个比较常见的应用场景是实现跳过某个主机不执行任务 或者 只有满足条件的主机执行任务。
3.5.2 实例
1.编写剧本,使用条件判断语句
#如果条件判断成功,则对应主机关机
vim test3.yaml
---
- hosts: all
remote_user: root
tasks:
- name: poweroff host
command: /usr/sbin/poweroff -r now
when: ansible_default_ipv4.address == "192.168.2.102"
#when指令中的变量名不需要手动加上 {{}}
或
when: inventory_hostname == "<主机名>"
2.执行剧本
#执行剧本
ansible-playbook test3.yaml
3.6 迭代(循环结构)
Ansible提供了很多种循环结构,一般都命名为with_items
,作用等同于 loop 循环。
vim test4.yaml
---
- name: play1
hosts: dbservers
gather_facts: false
tasks:
- name: create file
file:
path: "{{item}}"
state: touch
with_items: [ /opt/a, /opt/b, /opt/c, /opt/d ]
- name: play2
hosts: dbservers
gather_facts: false
vars:
test:
- /tmp/test1
- /tmp/test2
- /tmp/test3
- /tmp/test4
tasks:
- name: create directories
file:
path: "{{item}}"
state: directory
with_items: "{{test}}"
- name: play3
hosts: dbservers
gather_facts: false
tasks:
- name: add users
user: name={{item.name}} state=present groups={{item.groups}}
with_items:
- name: test1
groups: wheel
- name: test2
groups: root
或
with_items:
- {name: 'test1', groups: 'wheel'}
- {name: 'test2', goups: 'root'}
ansible-playbook test3.yaml
四、Playbook的模块
4.1 Template配置模板模块
用于生成配置模板文件,配合hosts中定义的变量,或者剧本中定义的变量,为不同主机生成不同的配置参数。
Jinja是基于Python的模板引擎。
Template类是Jinja的一个重要组件,可以看作是一个编译过的模板文件,用来产生目标文本,传递Python的变量给模板去替换模板中的标记。
4.1.1 怎么使用?
1)先准备一个xxx.j2
配置模板文件,在文件中使用{{变量名}}
引用主机变量或者vars字段
自定义的变量 以及 facts信息字段
做变量的值;
2)在playbook剧本中的task任务定义template模块配置。
template: src--xxx.j2 文件路径 dest-远程主机文件路径
4.1.2 实例
1)先准备一个以 .j2
为后缀的 template 模板文件,设置引用的变量
mkdir /etc/ansible/playbook
cp /usr/local/nginx/conf/nginx.conf /etc/ansible/playbook/nginx.conf.j2
vim /etc/ansible/playbook/nginx.conf.j2
2)修改主机清单文件,使用主机变量定义一个变量名相同,而值不同的变量
vim /etc/ansible/hosts
[webservers]
192.168.2.102 http_port=192.168.2.102:80 server_name=www.test1.com:80 root_dir=/var/www/html
192.168.2.103 http_port=192.168.2.103:80 server_name=www.test2.com:80 root_dir=/var/www/html
[dbservers]
192.168.2.106 http_port=192.168.2.103:80 server_name=www.test3.com:80 root_dir=/var/www/html
3)编写 playbook并执行
#编写剧本
vim nginx1.yaml
---
- name: new play
hosts: webservers:dbservers
remote_user: root
gather_facts: yes
tasks:
- name: disable firewalld
systemd:
name: firewalld
state: stopped
enabled: no
- name: disable selinux
command: '/usr/sbin/setenforce 0'
ignore_errors: true
- name: copy local repo file
copy:
src: /etc/yum.repos.d/repo.bak/local.repo
dest: /etc/yum.repos.d/
- name: mount cdrom
mount: src=/dev/sr0 path=/mnt state=mounted fstype=iso9660
- name: install dependent packages
with_items:
- gcc
- gcc-c++
- make
- pcre-devel
- zlib-devel
- openssl-devel
yum: name={{item}} state=present
#name: "gcc,gcc-c++,make,pcre-devel,zlib-devel,openssl-devel"
#state: present
- name: unarchive nginx package
unarchive: copy=yes src=/opt/nginx-1.24.0.tar.gz dest=/opt/
- name: install nginx
shell: chdir=/opt/nginx-1.24.0/ ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module && make && make install
- name: copy nginx config file
template: src=/etc/ansible/playbook/nginx.conf.j2 dest=/usr/local/nginx/conf/nginx.conf
notify: "reload nginx"
- name: copy nginx systemd control script
copy: src=/etc/ansible/playbook/nginx.service dest=/usr/lib/systemd/system/
- name: create nginx user
user: name=nginx shell=/sbin/nologin create_home=no
- name: start nginx
service: name=nginx state=started enabled=yes
- name: create root dir
file: path={{root_dir}} state=directory
- name: create index.html for 2.102
copy: content="this is test1" dest={{root_dir}}/index.html
when: ansible_default_ipv4.address == "192.168.2.102"
- name: create index.html for 2.103
copy: content="this is test2" dest={{root_dir}}/index.html
when: ansible_default_ipv4.address == "192.168.2.103"
- name: create index.html for 2.106
copy: content="this is test3" dest={{root_dir}}/index.html
when: ansible_default_ipv4.address == "192.168.2.106"
handlers:
- name: reload nginx
service: name=nginx state=reloaded
``
#执行剧本
ansible-playbook nginx1.yaml
4)切换到组内主机,查看是否配置了不同的参数
grep -v -e '^$' -e '#' /usr/local/nginx/conf/nginx.conf
#观察配置文件是否修改成功
4.2 tags模块
可以在一个playbook中为某个或某些任务定义“标签”,在执行此playbook时通过ansible-playbook命令使用–tags选项能实现仅运行指定的tasks。
playbook还提供了一个特殊的tags为always。
作用就是当使用always作为tags的task时,无论执行哪一个tags时,定义有always的tags都会执行。
4.3 Roles模块
Roles用于层次性、结构化地组织playbook,适用于代码复用度较高的场景。
4.3.1 Roles模块的作用(重要)
将playbook剧本中的各个play视作一个角色,将各个角色的tasks任务
、vars变量
、templates模板
、files文件
等内容放置在指定角色的目录中统一管理。
需要的时候可以在playbook中使用roles角色直接调用,即roles角色可以在playbook中实现代码的复用。
4.3.2 roles 的目录结构
cd /etc/ansible/
tree roles/
roles/
├── web/ #相当于 playbook 中的 每一个 play 主题
│ ├── files/
│ ├── templates/
│ ├── tasks/
│ ├── handlers/
│ ├── vars/
│ ├── defaults/
│ └── meta/
└── db/
├── files/
├── templates/
├── tasks/
├── handlers/
├── vars/
├── defaults/
└── meta/
4.3.3 roles 内各目录含义解释
目录 | 含义 |
---|---|
files | 用来存放由 copy 模块或 script 模块调用的文件 |
templates | 用来存放 jinjia2 模板,template 模块会自动在此目录中寻找 jinjia2 模板文件 |
tasks | 此目录应当包含一个 main.yml 文件,用于定义此角色的任务列表,此文件可以使用 include 包含其它的位于此目录的 task 文件 |
handlers | 此目录应当包含一个 main.yml 文件,用于定义此角色中触发条件时执行的动作 |
vars | 此目录应当包含一个 main.yml 文件,用于定义此角色用到的变量 |
defaults | 此目录应当包含一个 main.yml 文件,用于为当前角色设定默认变量。 这些变量具有所有可用变量中最低的优先级,并且可以很容易地被任何其他变量覆盖。所以生产中我们一般不在这里定义变量 |
meta | 此目录应当包含一个 main.yml 文件,用于定义此角色的元数据信息及其依赖关系 |
4.3.3 在一个 playbook 中使用 roles 的步骤
1)创建以 roles 命名的目录;
#举个例子
mkdir /etc/ansible/roles/ -p #yum装完默认就有```
2)创建全局变量目录(可选);
```bash
#举个例子
mkdir /etc/ansible/group_vars/ -p
touch /etc/ansible/group_vars/all #文件名自己定义,引用的时候注意
3)在 roles 目录中分别创建以各角色名称命名的目录,如 httpd、mysql;
#举个例子
mkdir /etc/ansible/roles/httpd
mkdir /etc/ansible/roles/mysql
4)在每个角色命名的目录中分别创建files、handlers、tasks、templates、meta、defaults和vars目录,用不到的目录可以创建为空目录,也可以不创建;
#举个例子
mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta}
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta}
5)在每个角色的 handlers、tasks、meta、defaults、vars 目录下创建 main.yml
文件,千万不能自定义文件名;
#举个例子
touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml
6)修改 site.yml
文件,针对不同主机去调用不同的角色;
#举个例子
vim /etc/ansible/site.yml
---
- hosts: webservers
remote_user: root
roles:
- httpd
- hosts: dbservers
remote_user: root
roles:
- mysql
7)ansible-playbook
运行剧本。
#举个例子
cd /etc/ansible
ansible-playbook site.yml
4.3.4 实例
1) 创建各角色的目录和main.yaml
文件
mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/php/{files,templates,tasks,handlers,vars,defaults,meta} -p
touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/php/{defaults,vars,tasks,meta,handlers}/main.yml
2)编写httpd模块
#写一个简单的tasks/main.yml
vim /etc/ansible/roles/httpd/tasks/main.yml
- name: install apache
yum: name={{pkg}} state=latest
- name: start apache
service: enabled=true name={{svc}} state=started
#定义变量:可以定义在全局变量中,也可以定义在roles角色变量中,一般定义在角色变量中存档
vim /etc/ansible/roles/httpd/vars/main.yml
pkg: httpd
svc: httpd
3)编写mysql模块
vim /etc/ansible/roles/mysql/tasks/main.yml
- name: install mysql
yum: name={{pkg}} state=latest
- name: start mysql
service: enabled=true name={{svc}} state=started
vim /etc/ansible/roles/mysql/vars/main.yml
pkg:
- mariadb
- mariadb-server
svc: mariadb
4)编写php模块
vim /etc/ansible/roles/php/tasks/main.yml
- name: install php
yum: name={{pkg}} state=latest
- name: start php-fpm
service: enabled=true name={{svc}} state=started
vim /etc/ansible/roles/php/vars/main.yml
pkg:
- php
- php-fpm
svc: php-fpm
5)编写roles示例
vim /etc/ansible/site.yml
---
- hosts: webservers
remote_user: root
roles:
- httpd
- mysql
- php
cd /etc/ansible
ansible-playbook site.yml
6)效果测试
切换到 webservers 组的主机
via:
-
大型企业中如何批量管理千万台服务器之ansible自动化运维工具详解 _服务器批量管理工具-CSDN博客
-
【Ansible自动化运维工具 1】Ansible常用模块详解(附各模块应用实例和Ansible环境安装部署)_ansible自动化运维实例-CSDN博客
-
从入门到精通 Ansible Playbook,一篇就够了_playbook入门-CSDN博客