上次简单了解了一下Ansible的诞生背景、应用场景、框架以及相关组件的功能,对Ansible有了一个一致的理解,这篇文章继续深入Ansible,对一些相关的操作命令和功能进行学习,并用自己的多台云服务器进行一个ping服务的实战,加深印象。
配置文件默认位于/etc/ansible/ansible.cfg
,不填写时,大部分参数有缺省值,常用的配置项如下(持续根据需要和使用情况添加):
[default]
#主机列表配置文件
#inventory = /etc/ansible/hosts
#库文件存放目录
#library = /usr/share/my_modules/
#临时py文件存放在远程主机目录
#remote_tmp = ~/.ansible/tmp
#本机的临时执行目录
#local_tmp = ~/.ansible/tmp
#默认并发数
#forks = 5
#默认sudo用户
#sudo_user = root
#每次执行是否询问sudo的ssh密码
#ask_sudo_pass = True
#每次执行是否询问ssh密码
#ask_pass = True
#远程主机端口
#remote_port = 22
#设置是否检查SSH主机的密钥,关闭后第一次连接不会提示配置实例
host_key_checking = False
#ansible日志目录
log_path = /var/log/ansible.log
#指定通信机制
transport = smart
# 角色配置路径
roles_path = /etc/ansible/roles
# ssh连接超时
timeout = 10
# 指定ansible命令执行的用户,默认使用当前用户
remote_user = root
# ansible命令默认执行模块
module_name = command
#普通用户提权操作
[privilege_escalation]
#become=True
#become_method=sudo
#become_user=root
#become_ask_pass=False
实践时,我的配置文件如下:
[defaults]
remote_user=root
log_path=/var/log/ansible.log
sudo_user=root
host_key_checking=False
inventory=/etc/ansible/host
主要简化了后续命令执行的参数,不需要 -i 指定host文件路径以及 -u 指定远程服务器执行的用户。
在位于/etc/ansible/hosts
文件中,配置Ansible需要管理的主机及群组清单,主要使用方法如下:
# 使用主机名需要配置DNS域名解析
# 方式一: ip+端口+用户+密码(不使用默认配置)
[webs]
10.0.0.7 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass='1'
10.0.0.8 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass='1'
# 方式二:主机名+密码
[webs]
web0[1:2] ansible_ssh_pass='123456'
# 方式三:主机名 + 变量配置
[webs]
web0[1:2]
[webs:vars]
ansible_ssh_pass='123456'
给本地配置一下host文件:
[tencent]
42.194.184.177
159.75.83.204
为了不在配置文件中写入账号密码信息,并且能够每次ssh都直接访问成功,可以对要管理的服务器配置ssh免密登陆,方法如下:
# 管理端执行生成密钥
ssh-keygen -t rsa
# 被管理端添加公钥
ssh-copy-id [email protected]
ssh-copy-id [email protected]
这样就配置成功ssh免密登陆了,之后可以不需要密码直接访问两台服务器了。
Ansible常用的几个命令有: ansible / ansible-doc / ansible-galaxy / ansible-playbook / ansible-pull / ansible-vault,下面分别介绍一下这几个命令
ansible是最常用的命令,也是Ansible主框架最核心的命令,
可以通过ansible --help
查看命令的相关帮助,常用的一些参数如下:
# anisble命令语法: ansible[-i 主机文件][-f 批次][组名][-m 模块名称][-a 模块参数]
ansible详细参数:
-v,-verbose #详细模式,如果命令执行成功,输出详细的结果 (-vv –vvv -vvvv)
-i PATH, -inventory=PATH #指定host文件的路径,默认是在 /etc/ansible/hosts
-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 #测试此命令执行会改变什么内容,不会真正的去执行
测试连通性
上面已经通过配置host清单并且配置ssh登陆,并且配置ansible.cfg文件,完成基本的配置项,现在我们通过ansible命令的ping模块测试一下是否能连通两台服务器:
$ ansible -m ping tencent
42.194.184.177 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
159.75.83.204 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
这样证明两台服务器已经是连通状态,可以从本地对其进行批量管理了,Nice。
ansible-doc 命令常用于获取模块信息及其使用帮助,一般用法如下:
# 获取全部模块的信息
ansible-doc -l
# 获取指定模块的使用帮助
ansible-doc -s [模块名称]
比如我们想看一下与mysql相关的模块,可以看到mysql相关的模块和简单的介绍:
$ ansible-doc -l | grep mysql
azure.azcollection.azure_rm_mysqlconfiguration Manage Configur...
azure.azcollection.azure_rm_mysqlconfiguration_info Get Azure MySQL Confi...
azure.azcollection.azure_rm_mysqldatabase Manage MySQL Dat...
azure.azcollection.azure_rm_mysqldatabase_info Get Azure MySQL ...
azure.azcollection.azure_rm_mysqlfirewallrule Manage MySQL firewall...
azure.azcollection.azure_rm_mysqlfirewallrule_info Get Azure MySQL Firew...
azure.azcollection.azure_rm_mysqlserver Manage MySQL S...
azure.azcollection.azure_rm_mysqlserver_info Get Azure MySQ...
community.azure.azure_rm_mysqlconfiguration_facts Get Azure MySQL Confi...
community.azure.azure_rm_mysqlconfiguration_info Get Azure MySQL Confi...
community.azure.azure_rm_mysqldatabase_facts Get Azure MySQL ...
community.azure.azure_rm_mysqldatabase_info Get Azure MySQL ...
community.azure.azure_rm_mysqlfirewallrule_facts Get Azure MySQL Firew...
community.azure.azure_rm_mysqlfirewallrule_info Get Azure MySQL Firew...
community.azure.azure_rm_mysqlserver_facts Get Azure MySQ...
community.azure.azure_rm_mysqlserver_info Get Azure MySQ...
community.mysql.mysql_db Add or remove MySQL databases from...
community.mysql.mysql_info Gather information about...
community.mysql.mysql_query Run...
community.mysql.mysql_replication Manage MyS...
community.mysql.mysql_role Adds, removes, or update...
community.mysql.mysql_user Adds or removes a user from a ...
community.mysql.mysql_variables Manage MySQL gl...
community.proxysql.proxysql_backend_servers Adds or removes mysql hosts from proxysql a...
community.proxysql.proxysql_mysql_users Adds or removes mysql users from proxysql a...
f5networks.f5_modules.bigip_monitor_mysql Manages BIG-IP ...
ansble的galaxy工具,类似程序员使用的 github,docker 镜像仓库,yum仓库和deb仓库等。可以将自己编写的 Role 通过 Galaxy 这个平台进行分享。同样,我们也可以通过 Galaxy 这个平台去获取一些我们想要的 Role。
Galaxy官网: https://galaxy.ansible.com
可以通过帮助命令查看相关用法:
$ ansible-galaxy -h
本文暂时不详细介绍ansible-galaxy,感兴趣可以上官网查阅相关示例。
Ansible-playbook是日常应用中使用频率最高的命令,类似于Linux中的sh或source命令,用来执行系列任务。其工作机制:通过读取预先编写好的playbook文件实现集中处理任务。Ansible-playbook命令后跟yml格式的playbook文件,playbook文件存放了要执行的任务代码,命令使用方式如下:
Ansible-playbook playbook.yml
github上提供了大量的实例供大家参考: https://github.com/ansible/ansible-examples
to do:之后专门写一篇文章实践playbook的使用
该指令用于Ansible的另一种工作模式:pull模式(Ansible默认使用push模式)。
Ansible默认push模式工作,即不要在远程主机做任何操作只需要在控制机编排playbook,push到远程主机即可完成任务。pull模式刚好相反,其适用于以下场景:
但是这种模式不太友好,可以结合crontab定时任务配合使用
Ansible 基于pull 模式的工作流程:
将Ansible设置为从节点pull而不是push,是有一些缺点,例如要求在节点上安装软件,但是也存在一些优点:
ansible-vault用于配置文件中含有敏感信息不希望他能被人看到时,加密/解密这个配置文件。
主要对于playbooks里比如涉及到配置密码或其他变量时,可以通过该指令加密,这样我们通过cat看到的会是一个密码串类的文件,编辑的时候需要输入事先设定的密码才能打开。这种playbook文件在执行时,需要加上 --ask-vault-pass参数,同样需要输入密码后才能正常执行。
to do:之后专门写一篇文章实践playbook的使用,通过加密方式执行执行。
下面主要介绍一下比较常用的几个Ansible的模块。
command模块在远程主机执行命令,不支持管道、重定向等shell的特性(需使用shell模块实现这些功能),使用方法如下:
# Ansible command模块为ansible默认模块,主要用于执行Linux基础命令,可以执行远程服务器命令执行、任务执行等操作。Command模块使用详解:
chdir 执行命令前,切换到目录;
creates 当该文件或目录存在时,则不执行该步骤;
executable 换用shell环境执行命令;
free_form 需要执行的脚本;
removes 当该文件或目录不存在时,则不执行该步骤;
warn 如果在ansible.cfg中存在告警,如果设定了False,不会警告此行。
进行一个简单的测试:
# 先切换到/usr/目录下,再执行ls操作
$ ansible tencent -m command -a 'chdir=/usr/ ls'
159.75.83.204 | CHANGED | rc=0 >>
bin
etc
games
include
lib
lib64
libexec
local
mpi
sbin
share
src
tmp
42.194.184.177 | CHANGED | rc=0 >>
bin
etc
games
include
lib
lib64
libexec
local
mpi
sbin
share
src
tmp
# 当存在/usr/tmp/目录时,不执行ls的操作
$ ansible -a 'creates=/usr/tmp/ ls' tencent
42.194.184.177 | SUCCESS | rc=0 >>
skipped, since /usr/tmp/ existsDid not run command since '/usr/tmp/' exists
159.75.83.204 | SUCCESS | rc=0 >>
skipped, since /usr/tmp/ existsDid not run command since '/usr/tmp/' exists
# 当存在/usr/tmp/目录时,执行ls操作
$ ansible -a 'removes=/usr/tmp/ ls' tencent
42.194.184.177 | CHANGED | rc=0 >>
mysqld
159.75.83.204 | CHANGED | rc=0 >>
shell模块可以在远程主机上调用shell解释器运行命令,支持shell的各种功能,例如管道,重定向等,只要是shell命令,都可以通过这个模块执行。
$ ansible -m shell -a "ls /usr/ | grep s" tencent
42.194.184.177 | CHANGED | rc=0 >>
games
sbin
share
src
159.75.83.204 | CHANGED | rc=0 >>
games
sbin
share
src
这个模块用于将文件复制到远程主机,同时支持给定内容生成文件和修改权限等。常见的参数如下:
# Ansible copy模块主要用于文件或者目录拷贝,支持文件、目录、权限、用户组功能,copy模块使用详解:
# 常用参数
src Ansible端源文件或者目录,空文件夹不拷贝;
content 用来替代src,用于将指定文件的内容,拷贝到远程文件内;
dest 客户端目标目录或者文件,需要绝对路径;
backup # 拷贝之前,先备份远程节点上的原始文件;backup=yes
directory_mode 用于拷贝文件夹,新建的文件会被拷贝,而老旧的不会被拷贝;
follow 支持link文件拷贝;
force 覆盖远程主机不一致的内容;
group 设定远程主机文件夹的组名;
mode 指定远程主机文件及文件及的权限;
owner 设定远程主机文件夹的用户名,拥有者。
示例如下:
# 讲当前目录下的.config_yml文件复制到远程主机的/tmp目录下,权限是777,主是root,组是root
$ ansible -m copy -a "src=./_config.yml dest=/tmp mode=777 owner=root group=root" te
ncent
159.75.83.204 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "fc0903a6b52cee0d960bd855af19a200c014ece5",
"dest": "/tmp/_config.yml",
"gid": 0,
"group": "root",
"md5sum": "0b28c4882e62bef641608bfc4977efea",
"mode": "0777",
"owner": "root",
"size": 4032,
"src": "/root/.ansible/tmp/ansible-tmp-1649525840.5117528-83443-222917402901983/source",
"state": "file",
"uid": 0
}
42.194.184.177 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "fc0903a6b52cee0d960bd855af19a200c014ece5",
"dest": "/tmp/_config.yml",
"gid": 0,
"group": "root",
"md5sum": "0b28c4882e62bef641608bfc4977efea",
"mode": "0777",
"owner": "root",
"size": 4032,
"src": "/root/.ansible/tmp/ansible-tmp-1649525840.561137-83441-22380661739325/source",
"state": "file",
"uid": 0
}
该模块主要用于软件的安装,常见的参数如下:
#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。
示例如下:
# 远程安装httpd服务
ansible -m yum -a "name=httpd state=installed" tencent
# 远程启动httpd服务
ansible -m shell -a "systemctl start httpd" tencent
# 查看httpd服务进程信息
ansible -m shell -a "ps -ef | grep httpd" tencent
# 停止httpd服务
ansible -m shell -a "systemctl stop httpd" tencent
# 卸载httpd服务
ansible -m yum -a "name=httpd state=removed" tencent
该模块主要用于设置文件的属性,比如创建文件、创建链接文件、删除文件等,常用的参数如下:
# Ansible file模块主要用于对文件的创建、删除、修改、权限、属性的维护和管理,File模块使用详解:
# 常用参数介绍
src Ansible端源文件或者目录;
follow 支持link文件拷贝;
force 覆盖远程主机不一致的内容;
group 设定远程主机文件夹的组名;
mode 指定远程主机文件及文件及的权限;
owner 设定远程主机文件夹的用户名;
path 目标路径,也可以用dest,name代替;
state(主要有以下状态)
directory:如果目录不存在,就创建目录
file:即使文件不存在,也不会被创建
link:创建软链接
hard:创建硬链接
touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
absent:删除目录、文件或者取消链接文件
attributes 文件或者目录特殊属性。
示例如下:
# 在tencent主机组的服务器/tmp目录下面创建一个aaa的目录,属主为root
ansible -m file -a "path=/tmp/aaa state=directory mode=644 owner=root" tencent
# 在tencent主机组的服务器/tmp目录下面删除aaa目录,属主为root
ansible -m file -a "path=/tmp/aaa state=absent mode=644 owner=root" tencent
service模块为用来管理远程主机上的服务的模块。常见的参数如下:
# Ansible service模块主要用于远程客户端各种服务管理,包括启动、停止、重启、重新加载等:
# 常用参数
enabled 是否开启启动服务;
name 服务名称;
runlevel 服务启动级别;
arguments 服务命令行参数传递;
state 服务操作状态,状态包括started--->启动服务, stopped--->停止服务, restarted--->重启服务, reloaded--->重载配置
示例如下:
# 开启nginx服务并设置nginx服务开机自启
ansible -m service -a 'name=nginx state=started enabled=true' tencent
# 关闭nginx服务
ansible -m service -a 'name=nginx state=stoped' tencent
该模块用于将本机的脚本在被管理端的机器上运行,只需要指定本地一个脚本文件的路径即可,示例如下:
# 让tencent主机组执行当前目录下的install_docker.sh脚本,该脚本作用是安装docker及docker-compose及相关依赖
ansible -m script -a "./install_docker.sh" tencent
Ansible还有其他非常多的模块,像是user/group/cron等,详细的用法不一一介绍了,可以在官网查看用法及示例。