博客主页:作者主页
简介:云计算领域优质创作者、学长的it故事 公众号创作者、在校期间参与众多计算机相关的省赛、国赛,斩获系列荣誉。考取华为资深工程师、红帽工程师等系列认证。
关注我:关注我简历模板、学习资料、文档下载、技术支持
让生命像一团热烈燃烧的火,直到死亡才能使它熄灭
前言
最近有老铁私信给我,让我出一份ansible的博文,今天小编就和带着学习新知识的思想,和大家一起复习自动化运维工具。在早起的自动化运维工具中,常见的有puppet、saltstack、ansible 等软件,目前常用的就是ansible 和saltstack 2款工具。saltstack 与puppet 都是基于 C/S 模式工作的,他们需要安装服务端与客户端,基于Python 编写,加入MQ消息同步,可以是执行命令和执行结果高效返回,但执行过程需要等客户端返回。所以如果客户端没有及时返回或响应,就可能导致部分机器没有执行结果。目前用的较少。
今天就主要分享ansible 自动化运维工具。我将详细的从概念、到基础搞高级,层层递进,让你轻松掌握ansible自动化运维
当然,每一篇文章都不是100%的全,我能做的就是将我会的,最大限度的分享给你,让你也可以掌握。
Ansible是一款自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
Ansible 是一种安装在控制节点上的无代理自动化工具。Ansible 从控制节点远程管理机器和其他设备(默认情况下,通过 SSH 协议)。Ansible 与Saltstack均是基于Python 语言开发,Ansible只需要在一台普通的服务器上运行即可,不需要在客户端服务器上安装客户端。因为 Ansible是基于SSH远程管理,而Linux 服务器大都离不开SSH,所以Ansible不需要为配置工作添加额外的支持。
Ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是Ansible所运行的模块,Ansible只是提供一种框架。主要包括:
架构图
ansible 官网
# 由上面的图可以看到 Ansible 的组成由 5 个部分组成:
#Ansible : ansible核心
#Modules : 包括 Ansible 自带的核心模块及自定义模块
#Plugins : 完成模块功能的补充,包括连接插件、邮件插件等
#Playbooks : 剧本;定义 Ansible 多任务配置文件,由Ansible 自动执行
#Inventory : 定义 Ansible 管理主机的清单 [ˈɪnvəntri] 清单
实验环境
名称 | 系统 | 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 |
实验拓扑
官网安装步骤
# 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)]
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
定义主机清单
[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]#
ssh 免密登录
# 第一个历程: 创建秘钥对(管理端服务器)
sh-keygen -t 秘钥的类型(dsa|rsa)
#第二个历程: 将公钥进行分发(被管理端服务器)
ssh-copy-id -i /root/.ssh/id_dsa.pub [email protected]
# 本地生成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 [email protected]
[root@web01_server~]# ssh-copy-id [email protected]
[root@web01_server~]# ssh-copy-id [email protected]
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最基础的模块为ping模块,主要用于判断远程客户端是否在线,用于ping本身服务器,返回值为changed、ping。
自己管理自己
# 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]
10.0.0.61 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=123456
[root@ansible_server~]#
# 同时还可以基于SSH 免密登录,2种方式选一种。
# 将自己的密钥拷贝到本地,然后ssh 连接一下即可。
[root@web01_server~]# ssh-copy-id [email protected]
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~]#
模块介绍
# Ansible shell模块主要用于远程客户端上执行各种Shell命令或者运行脚本,远程执行命令通过/bin/sh环境来执行,支持比command更多的指令,Shell模块使用详解:
# 常用参数
chdir 执行命令前,切换到目录;
creates 当该文件存在时,则不执行该步骤;
executable 换用shell环境执行命令;
free_form 需要执行的脚本;
removes 当该文件不存在时,则不执行该步骤;
warn 如果在ansible.cfg中存在告警,如果设定了False,不会警告此行。
创建/查看目录
# 在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~]#
远程查看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~]#
远程查看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~]#
批量修改用户密码
# 通通过shell 远程批量修改密码
[root@ansible_server~]# ansible www -m shell -a "echo 123456|passwd --stdin root"
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.
command 模块介绍
# Ansible command模块为ansible默认模块,主要用于执行Linux基础命令,可以执行远程服务器命令执行、任务执行等操作。Command模块使用详解:
Chdir 执行命令前,切换到目录;
Creates 当该文件存在时,则不执行该步骤;
Executable 换用shell环境执行命令;
Free_form 需要执行的脚本;
Removes 当该文件不存在时,则不执行该步骤;
Warn 如果在ansible.cfg中存在告警,如果设定了False,不会警告此行。
查看磁盘空间
# 使用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 区别不大,知识支持的命令更多
使用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~]#
远程下载
# 先远程查看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"
模块介绍
# Ansible copy模块主要用于文件或者目录拷贝,支持文件、目录、权限、用户组功能,copy模块使用详解:
# 常用参数
src Ansible端源文件或者目录,空文件夹不拷贝;
content 用来替代src,用于将指定文件的内容,拷贝到远程文件内;
dest 客户端目标目录或者文件,需要绝对路径;
backup # 拷贝之前,先备份远程节点上的原始文件;backup=yes
directory_mode 用于拷贝文件夹,新建的文件会被拷贝,而老旧的不会被拷贝;
follow 支持link文件拷贝;
force 覆盖远程主机不一致的内容;
group 设定远程主机文件夹的组名;
mode 指定远程主机文件及文件及的权限;
owner 设定远程主机文件夹的用户名,拥有者。
远程拷贝
#将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~]#
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。
远程安装/卸载
# 远程在 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"
停止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~]#
file 模块介绍
# Ansible file模块主要用于对文件的创建、删除、修改、权限、属性的维护和管理,File模块使用详解:
# 常用参数介绍
src Ansible端源文件或者目录;
follow 支持link文件拷贝;
force 覆盖远程主机不一致的内容;
group 设定远程主机文件夹的组名;
mode 指定远程主机文件及文件及的权限;
owner 设定远程主机文件夹的用户名;
path 目标路径,也可以用dest,name代替;
state #状态包括:file、link、directory、hard、touch、absent;
attributes 文件或者目录特殊属性。
使用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表示创建目录
远程创建文件
#在/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 表示创建文件
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。
基本同步用法
# 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"
添加定时任务 名称注释
# 添加注释信息
[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
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表示删除
创建普通用户
# 在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~]#
创建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~]#
service 模块介绍
# Ansible service模块主要用于远程客户端各种服务管理,包括启动、停止、重启、重新加载等,service模块使用详解:
# 常用参数
enabled 是否开启启动服务;
name 服务名称;
runlevel 服务启动级别;
arguments 服务命令行参数传递;
state 服务操作状态,状态包括started, stopped, restarted, reloaded。
远程重启/关闭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"
平滑启动 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",
……
远程设置开机自启动
# 远程开机启动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"
模块介绍
# 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。
将源目录同步至目标目录(增量同步)
# 将本地/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=<>%i %n%L /tmp/ 10.0.0.7:/tmp/" ,
"msg": ".d..t...... ./\n\n cd+++++++++ ansible_synchronize_payload_Bxuy_S/\n\ncd+++++++++ vmware-root_6044-692160431/\n",
"rc": 0,
"stdout_lines": [
".d..t...... ./",
",
"cd+++++++++ ansible_synchronize_payload_Bxuy_S/",
",
"cd+++++++++ vmware-root_6044-692160431/"
]
}
[root@ansible_server~]#
将源目录同步至目标目录(增量同步)
# 完全同步,尾巴后添加 delete=yes
[root@ansible_server/tmp]# ansible docker -m synchronize -a 'src=/tmp/ dest=/tmp/ delete=yes'
剧本介绍
# 通过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
playbook 组件
Target 定义playbook的远程主机组;
常用参数:
hosts 定义远程主机组;
user 执行该任务的用户;
sudo 设置为yes的时候,执行任务的时候使用root权限;
sudo_user 指定sudo普通用户;
connection 默认基于SSH连接客户端;
gather_facks 获取远程主机facts基础信息。
Variable 定义playbook使用的变量;
Task 定义远程主机上执行的任务列表;
Handler 当服务的配置文件发生变化时需要进行的操作,比如:重启服务,重新加载配置
远程安装演示
# 通过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
安装 成功
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
批量创建系统用户
# 使用 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
实验环境介绍
名称 | 系统 | 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 |
分布式部署 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
修改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默认配置文件为/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
关闭ssh 检测密钥
# 在ansible 配置文件中加入以下代码:
host_key_checking = False
关闭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
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天左右,通过构思、实践,完整的走了一遍,如果当你读到这篇文章后,请认真看完,因为这是运维必备的技能。
日常运维中,还有很多细节需要注意,这里不做过多描述,当然这里介绍的并不是非常全,往后的学习中,还是要多去查看官网的说明文档,上面介绍的最详细,最权威。学习是一个漫长的过程,如果你想从事运维行业,能参加一个好点的培训机构最好,如果经济有限,不想花钱,也可以自学,买一本好点的书籍,看一套完整的视频,然后做实验,反复去练习。同时如果对我的云计算专栏感兴趣,也可以订阅我的专栏,进行学习。
以梦为马,不负韶华,流年笑掷,未来可期!
—黄昏