前言
Ansible是一个开源的自动化运维工具,它可以帮助管理员自动化部署、配置和管理服务器。在这篇文章中,我们将介绍如何配置Ansible的配置文件。此外,我们还将介绍Ansible的一些常用模块,如copy、raw、yum等,以及如何使用Ansible Playbook编写自动化脚本。
安装Ansible
$ yum install epel-release ansible -y
Ansible配置文件配置
Ansible的配置文件名为 ansible.cfg
Ansible 配置文件可存放在 4 个位置,若多个位置下均存在 ansible.cfg 配置文件,其生效优先级为:
- ①ANSIBLE_CONFIG环境变量所指定的 ansible.cfg路径;
- ②./ansible.cfg即运行 ansible命令时所在的当前工作目录;
- ③~/.ansible.cfg即当前用户所在家目录下的一个隐藏文件.ansible.cfg;
- ④/etc/ansible/ansible.cfg即 ansible的默认配置文件所在路径;
配置文件示例
$ cat /etc/ansible/ansible.cfg
[defaults]
inventory = /etc/ansible/hosts #主机清单
library = /usr/share/my_modules/ # 使用的模块
forks = 5 #处理并发的进程数,建议设置控制机的数量
sudo_user = root #默认执行远程命令的用户
remote_port = 22 #SSH连接被控制机的端口
gathering = smart #'smart'收集facts的信息,如已收集,则采用缓存。可选参数'implicit'、'explicit',分别表示每次都收集和默认不收集facts信息
fact_caching_timeout = 86400 #'gathering为smart'可用,设置收集超时时间
fact_caching = jsonfile #'gathering为smart'可用,设置以什么存储facts信息。还可在本地安装redis、memcache来作为facts的存储。
fact_caching_connection = /etc/ansible/ansible_facts_cache #'gathering为smart'可用,设置缓存路径。
roles_path = /etc/ansible/roles #设置ansible其他roles的路径
host_key_checking = false #忽略检查主机密钥
log_path = /var/log/ansible.log #ansible日志路径
module_name = command #ansible默认的模块
deprecation_warnings = False #禁用ansible“不建议使用”的警告
remote_user = root #定义默认远程连接用户
[ssh_connection]
ssh_args = -C -o ControlMaster=auto -o ControlPersist=1d #开启ssh长连接,保存时间为1天
control_path_dir = /etc/ansible/ssh-socket #ssh长连接存放的路径
control_path = %(directory)s/%%h-%%p-%%r #ssh长连接的格式名称
pipelining = True #减少执行远程模块SSH操作次数,开启这个设置,将显著提高性能,但被控制机需要将/etc/sudoers下"Defaults requiretty"注释掉
[accelerate]
accelerate_port = 5099 #使用python程序在被控制机上运行一个守护进程,ansible通过这个守护进程监听的端口进行通信。所有机器都要安装python-keyczar包
accelerate_timeout = 30 #设置用来控制从客户机获取数据的超时时间,如果在这段时间内没有数据传输,套接字连接会被关闭。
accelerate_connect_timeout = 5.0 #设置空着套接字调用的超时时间.这个应该设置相对比较短.这个和`accelerate_port`连接在回滚到ssh或者paramiko连接方式之前会尝试三次开始远程加速daemon守护进程.默认设置为1.0秒:
[privilege_escalation] # 特权升级相关配置项
become=True # 【允许远程主机上的普通用户提权】
become_method=sudo # 【提权方式为 sudo】
become_user=root # 【提权至 root用户身份】
become_ask_pass=False #【提权时无需验证交互密码】
hosts 文件(机器清单,进行分组管理)
[tomcat]
192.168.16.192
192.168.16.193
node01
[nginx]
app1 ansible_ssh_host=192.168.16.190 ansible_ssh_pass="password"
app2 ansible_ssh_host=192.168.16.191 sudo_user=”ald” ansible_ssh_pass="password"
sudo_user和ansible_ssh_pass为帐号密码方式验证,建议用密钥。
如果已经进行过互信,直接填写ip或者主机名即可;主机名需要确认在/etc/hosts中有对应ip
Ansible指令参数
Ad-Hoc 是 ansible 下临时执行的一条命令,Ad-Hoc 的执行主要依赖于模块;
Ansible命令的格式如下所示:
ansible 主机清单 -m 模块名 -a ‘模块选项’ ansible 选项
ansible 常用命令参数
- -i, –inventory-file: 指定 inventory 文件的路径,包含了 Ansible 需要管理的主机信息。
- -u, –user: 指定连接到远程主机时使用的用户名。
- –private-key: 指定连接到远程主机时使用的私钥文件路径。
- -b, –become: 以超级用户身份运行 Ansible 命令,相当于
sudo
。 - –become-user: 指定在远程主机上以超级用户身份运行时使用的用户名。
- –tags: 仅运行包含指定标签的任务。
- –skip-tags: 跳过包含指定标签的任务。
- -e, –extra-vars: 提供额外的变量,用于在 playbook 中使用。
- –limit: 限制 playbook 只运行在指定的主机或主机组上。
- –check: 以检查模式运行 playbook,不会实际执行修改。
- -m: 指定模块
- -a: 指定模块的命令。默认是command模块,可以省略
ansible-doc 常用命令参数
- -l –list:显示已存在的所有模块
ansible-galaxy
下载第三方模块指令,类似yum、pip、easy_install这样的命令
ansible-galaxy install <module_name>
常用模块
1、 copy模块
用于将本地或远程机器上的文件拷贝到远程主机上,其选项有:
- src:主控端本地源文件/目录所在路径;目录后带/表示拷贝该目录下所有内容;
- dest:拷贝至远程主机的目标路径;
- remote_src:默认为 no,表示将主控端的文件/目录拷贝至被控端,当该选项为 yes时,表示直接将被控端的文件/目录拷贝至被控端
- force:目标文件存在的情况下,该选项为 yes 表示强制覆盖,默认为 yes 选项;
- backup:覆盖目标文件之前备份原文件,有 yes/no两个选项;
- content:向文件中写入具体内容,可替代 src选项;
- others:file 模块中文件属性相关的如 owner、group、mode 等选项在此也适用;
$ ansible all –m copy -a “src=/xxx/xxx dest=/yyy/yyy owner=root group=root mode=644 force=yes/no backup=yes/no”
解释:将src文件/目录复制到远程dest上,所有者/组为root 权限为644,force为是否强制替换,backup为替换前是否需要备份远程远文件
2、 raw模块 (和command、shell类似)
用于在目标主机上执行原始的 shell 命令,而无需使用 Ansible 的模块系统。
主要作用
- 执行原始命令:
raw
模块允许直接在目标主机上执行原始的 shell 命令,而不需要通过 Ansible 模块的方式。 - 绕过模块系统: 对于一些不适合或无法使用 Ansible 模块解决的任务,可以使用
raw
模块绕过模块系统。
常用选项
executable
: 指定要用于执行命令的可执行文件,例如/bin/bash
。
$ ansible all –m raw -a "ifconfig"
$ ansible all -m raw -a "executable=/bin/bash ls -l"
解释:在所有主机上执行ifocnfig命令。
3、fetch模块
fetch模块用于将远程主机的文件拷贝至主控端,其选项有:
- src:远程主机上源文件的路径(只能是文件不能是目录)
- dest:主控端存放文件的路径
- flat:默认为 no,表示文件在主控端仍保留远程主机的原文件存放的目录结构;yes表示不会保留远程主机的原有目录结构,此时目录后必须带/。
$ ansible node2 -m fetch -a 'src=/tmp/ice/1.txt dest=/opt'
$ ansible node2 -m fetch -a 'src=/tmp/ice/1.txt dest=/opt/ falt=yes'
解释:
1、将node2节点上的/tmp/ice/1.txt拷贝至主控端的/opt目录(flat=no),拷贝后的目录结构为:/opt/node2/tmp/ice/1.txt
2、将node2节点上的/tmp/ice/1.txt拷贝至主控端的/opt目录(flat=yes),拷贝后的目录结构为:/opt/1.txt
4、 yum模块
yum模块用来对软件包进行管理,其选项有:
- name:要进行操作的软件包名,也可是 rpm包路径或 url地址
- state:
- present 安装
- absent 卸载
- latest 更新至最新版本
$ ansible all –m yum –a “name=httpd state=present”
解释:
安装httpd程序
5、yum_repository 模块
yum_repository模块用来配置 yum仓库,其选项有:
- file:配置文件的命令,不包括.repo后缀
- name:yum仓库的名字
- description:仓库的描述信息
- baseurl:yum源地址
- enabled:是否开启该仓库,yes/no
- gpgcheck:是否检查软件包的完整性,yes/no
- gpgcheck:公钥地址
$ ansible node1 -m yum_repository -a 'file=AppStream name=AppStream description=RHEL8.4_AppStream baseurl=file:///mnt/iso/AppStream enabled=yes gpgcheck=no'
解释:
为 RHEL8.4配置 AppStream镜像仓库
6、 file模块
file模块主要用于远程主机上的文件操作,其选项有:
- path:指定文件/目录的路径
- state:操作类型,详情介绍如下
- file:默认选项,查看文件状态
- touch:创建文件、更新文件时间戳
- directory:创建目录
- absent:删除文件、目录、链接文件
- hard:创建硬链接
- link:创建软链接
- owner:指定文件/目录的属主
- group:指定文件/目录的属组
- mode: 指定文件/目录的权限
- src: 链接的源文件的路径,只应用于 state=hard/link的情况
- dest: 链接的目标文件的路径,只应用于 state=hard/link的情况
- force:默认为 no,两种情况下使该选项等于 yes 可强制创建软连接,一种是源文件不存在但之后会创建的情况,另一种是目标软连接已存储,需要先取消之前的软链接,再创建新的软连接。
$ ansible all –m file –a “src=/xxx/xxx/1 dest=/yyy/1 state=link owner=alad group=alad mode=777”
$ ansible develop -m file -a "path=/xxx/dir recurse=yes owner=root group=alad mode=644"
解释:
1、将src的文件软连接到dest目录下,并修改所有者/组和权限
2、将path路径的目录递归形式设置所有者和权限*、state还可以是directory:如果目录不存在,创建目录
7、 cron模块
cron模块用于管理计划任务,其选项有:
- name:该计划任务的描述
- state:
- presen:创建
- absen:删除
- user:以哪个用户身份执行该计划任务
- minute:分钟
- hour:小时
- day:日
- mouth:月
- weekday:周
- job:要执行的任务,前提是 state=present
- cron_file:指定配置文件,如/etc/crontab,/etc/cron.d/*
$ ansible develop -m cron -a "name='show time' minute=*/1 hour=* day=* month=* weekday=* job='/bin/date'"
$ ansible develop -m cron -a "name='show time' state=absent"
解释:
1、创建一个每分钟显示时间的计划任务
2、删除名为show time这个计划任务
8、 group模块
group模块用于对用户组进行管理,其选项有:
- name:组名
- gid:指定组 id
- state:
- present:创建
- absent:删除
$ ansible all-m group -a "name=develop"
$ ansible all -m group -a 'name=haha state=present gid=1888'
解释:
1、在所有主机上创建一个develop的组 ,state默认选项为present
2、创建一个名为 haha,gid为 1888的组
9、 user模块
user模块用于对用户进行管理,其选项有:
- name:用户名
- state:
- present:创建
- absent:删除
- password:密码(不会自动加密,需先 openssl passwd -6 bingren 手动加密)
- uid:用户的 uid
- group:指定用户的主组
- groups:指定用户的附加组
- comment:定义用户的描述信息
- create_home:是否创建家目录 yes|no
- home:指定用户的家目录,需于 create_home结合使用
- shell:指定用户的 shell类型
- remove:删除家目录与邮箱 yes|no,需 state=absent
$ ansible develop -m user -a "name=harlan groups=root password=-1vFO89dP6qyK"
$ ansible develop -m user -a "name=harlan state=absent remove=yes"
解释:
1、在所有主机上创建harlan用户,并将其添加到root组,密码是经过hash加密后的,明文密码会被哈希,所以先填入hash后的密码即可
可用此命令hash密码 openssl passwd -salt -1 "123456"
2、删除harlan用户。Remove表示是否删除用户的同时删除家目录
注意:group 主组无需指定,会自动创建;-a 后的模块选项需使用单引号包裹,此时若使用双引号,password字段中的$符合会被特殊翻译。
10、 service模块
service模块用来管理服务,其选项有:
- name:服务名称
- state:
- started 启动
- stopped 停止
- restarted 重启
- reloaded 重新加载
- enabled:是否开机自启,yes/no
$ ansible develop -m service -a "name=nginx state=running"
$ ansible develop -m service -a "name=nginx state=restarted enabled=yes"
解释:
1、无论服务处在什么状态,最后都是将服务状态设置为启动,当服务正在运行的时候,显示为changed为false,state显示为状态,表示为正在运行;当服务停止的时候,显示为changed为true,表示这个时候将服务进行了启动,状态为启动
2、表示重启nginx并且将nginx设置为开机自启动
11、 script模块
用于在目标主机上执行本地脚本,其选项有:
- chdir 在运行脚本之前,切换到远程节点上的此目录。 默认:null
- cmd 本地脚本的路径,后跟可选参数。 默认:null 类型:str
- creates 远程节点上的一个文件名,如果已经存在,则不会运行此步骤。 默认:null
- decrypt 此选项控制使用vault对源文件进行自动解密。 默认:true 类型:bool
- executable 要调用的可执行文件的名称或路径。 默认:null
- free_form 本地脚本文件的路径,后跟可选参数。 默认:null
- removes 远程节点上的一个文件名,如果不存在,则不会运行此步骤。 默认:null
$ ansible develop -m script -a "/root/a.sh"
解释:
在develop主机上运行当前服务器上的a.sh脚本
12、get_url模块
get_url模块用于从 http、https、ftp服务器上下载文件,其选项有:
- url:文件的 url地址
- dest:指定下载后存放文件的目标目录
- owner:指定文件的拥有人
- group:指定文件的拥有组
- mode:指定文件的权限
- url_username:用于 HTTP验证的用户名
- url_password:用于 HTTP验证的密码
$ ansible develop -m get_url -a "url=http://file.alavening.com/alading_file/head_img/1526900421976.jpg dest=/home/ owner=alad group=alad mode=644"
解释:
将url上的图片下载到dest目的目录上,并且设置相应的所有者/组和权限。
13、synchronize模块
synchronize模块用于同步文件,其选项有:
- src:需同步的文件/目录,目录已/结尾表示拷贝只拷贝目录内的所有内容,不以/结尾表示拷贝目录本身及目录内的所有内容;
- dest:目标路径
- mode:
- push:默认为 push,从本机向远程主机上同步文件/目录
- pull:从远程主机向本机同步文件/目录
- compress:是否开启压缩
- delete:删除不存在的文件,默认为 no
- dest_port:目标主机上的端口,默认为 ssh协议 22号端口
- archive:归档,相当于同时开启 recursive(递归)、links、perms、times、owner、group、-D选项都为 yes
- rsync_opts:rsync的选项,选项之间用逗号隔开,如-a,-v,-z 等
$ ansible develop -m synchronize -a "src=/home/test/ dest=/home/test compress=yes delete=yes"
$ ansible develop -m synchronize -a "src=/home/test/ dest=/home/test compress=yes mode=pull"
解释:
1、将src下的文件同步到dest上,delete=yes表示以src目录为准镜像同步。
2、拉取远程src上的目录文件到本地dest上
14、template模块
主要用于根据 Jinja2 模板生成配置文件,其选项有:
src
:指定 Jinja2 模板文件的本地路径或远程 URL。这是唯一必需的参数,用于指定模板文件的位置。dest
:指定生成的配置文件在目标主机上的路径。如果未指定,默认情况下,文件将放置在目标主机的/tmp
目录中。force
:默认为no
。如果设置为yes
,即使目标文件已经存在,也会强制重新渲染模板。backup
:指定是否在渲染之前创建目标文件的备份。可以设置为yes
或指定备份文件的后缀,例如.bak
。owner
、group
、mode
:用于设置生成的配置文件的所有者、所属组和权限。validate
:用于指定生成的配置文件是否需要进行验证的脚本。如果验证脚本返回非零退出代码,则任务将失败。remote_src
:默认为yes
。如果设置为no
,则src
参数将在本地主机上查找文件,而不是在远程主机上。newline_sequence
:指定换行符序列。默认为unix
,可以设置为windows
或mac
。
$ ansible develop –m template –a ‘src=/mytemplates/foo.j2 dest=/etc/file.conf mode="u=rw,g=r,o=r"’
解释:
将src上foo.j2的变量模版复制到dest上。Template适合用playbook编写 ,通过变量然后拷贝到远程主机。
15、unarchive模块
unarchive模块用于解压文件,其选项有:
- src:需解压文件的源路径
- dest:文件解压后的存放路径
- remote_src:默认为 no,用于将主控端的文件解压至被控端当该选项为 yes时,用于将被控端的文件解压至被控端
- owner:解压后文件/目录的属主
- group:解压后文件/目录的属组
- mode:解压后文件的权限
- creates:指定一个文件名路径,当该文件不存在时,解压命令执行
- list_files:默认为 no,当为 yes时会列出压缩包里的文件
$ ansible develop -m unarchive -a "src=/root/apache-tomcat-7.0.85.tar.gz dest=/home/test owner=alad group=alad mode=755"
$ ansible develop -m unarchive -a "src=/home/alad/ansible/elk/logstash-6.2.4.tar.gz dest=/home/test remote_src=yes"
$ ansible develop -m unarchive -a "src=http://mirrors.linuxeye.com/oneinstack-full.tar.gz dest=/home/test remote_src=yes"
解释:
将本地的tomcat压缩包解压到远程主机dest目录下,并修改其权限和所有者/组,remote_src=yes 表示解压远程主机已有的压缩包,src为url表示下载此包到远程主机dest目录进行解压缩后,并删除压缩包源文件
16、command和shell模块
command
模块
- 作用:用于在目标主机上执行单个命令。
- 区别:
command
模块直接在目标主机上执行命令,不会启动一个可交互的 shell。这意味着,如果需要使用通配符、重定向等 shell 特性,需要手动包装命令。 - 常用选项:
cmd
:指定要执行的命令。creates
:如果指定的文件存在,则不执行命令。removes
:如果指定的文件不存在,则执行命令。
shell
模块
- 作用:用于在目标主机上执行通过 shell 解释的命令。
- 区别:
shell
模块在目标主机上通过 shell 执行命令,这使得可以使用 shell 特性,如通配符、重定向等。 - 常用选项:
cmd
:指定要执行的命令。creates
:如果指定的文件存在,则不执行命令。removes
:如果指定的文件不存在,则执行命令。chdir
:在执行命令之前更改当前工作目录。
区别总结
- 如果命令简单而且不需要 shell 特性,建议使用
command
模块,因为它效率更高。 - 如果命令包含了 shell 特性,如通配符、重定向等,或者需要使用管道、变量替换等高级 shell 特性,建议使用
shell
模块。
$ ansible node2 -m command -a "ls -l"
$ ansible node2 -m shell -a "ls -l"
17、setup模块
用于获取有关目标主机的事实(facts)信息,包括硬件、操作系统、网络等方面的信息,其选项有:
- filter:通过指定 filter 参数,可以仅获取特定的信息,而不是所有 facts。例如,
ansible -m setup --tree /tmp/facts -a 'filter=ansible_distribution*'
会只获取与发行版相关的 facts。 - gather_subset:允许指定要收集哪些子集的 facts。例如,
ansible -m setup --tree /tmp/facts -a 'gather_subset=network'
会只收集与网络相关的 facts。 - fact_path:指定存储 facts 的目录路径。通过默认情况下,
setup
将 facts 存储在默认的 Ansible 临时目录中。
$ ansible develop -m setup
$ ansible develop -m setup -a 'filter=ansible_*_mb'
解释:
1、显示系统所有信息
2、通常配合filter进行过滤来获取主机信息,(例子是显示内存信息)
18、assemble模块
主要用于将多个文件或代码片段合并成一个较大的文件,其选项有:
- src:指定包含文件碎片的目录路径。这些文件碎片通常是通过
disassemble
模块拆分的。 - dest:指定组装后的文件的目标路径。
- delimiter:指定文件碎片的分隔符。
assemble
模块使用这个分隔符来识别文件碎片并将它们组装在一起。 - mode:指定组装后的文件的权限模式。
$ ansible test -m assemble -a "src=/root/test dest=/root/ansible/fileone mode=777 remote_src=False delimiter='========'"
解释:
将src test目录下所有文件(不含test子目录内容)的内容发送到dest fileone文件中,remote_src默认为Ture表示src为远程主机上的路径,False为ansible控制端的路径,delimiter为文件之间内容分隔符。
Playbook语法和结构
Playbook 是一些列 ansible 命令的集合,基于 yaml 语言编写;playbook 依据自上而下的顺序执行。同时,在 playbook 中可以自定义变量,也可以将ansible在远程主机上收集的信息定义为变量。
Playbook 由一个或多个 play 组成;play 的主要功能是对定义一组实现某些功能的 task任务,而 task任务核心就是对 ansible的模块进行调用。
Playbook主要由下面四部分组成:
- ①Target section:定义主机清单、连接协议
- ②Variable section:定义变量
- ③Task section:定义任务列表
- ④Handler section:定义 task执行完成后所需调用的命令
示例:编写 playbook剧本创建一个名为 redhat的用户,附加组为 test
- name: create user # 剧本中第一幕的名称
hosts: all # 主机清单,all表示所有主机
vars: # 定义变量
username: redhat # 变量名:变量值
tasks: # 定义需要执行的任务
- name: create group # 任务名称
group: # 模块名称
name: test # 模块中的选项name
state: present # 模块中的选项state
- name: create user
user:
name: "{{ username }}"
groups: test
state: present
如何查询模块用法
$ ansible-doc yum
# 搜索EXAMPLES关键词
EXAMPLES:
- name: Install the latest version of Apache
ansible.builtin.yum:
name: httpd
state: latest
- name: Install Apache >= 2.4
ansible.builtin.yum:
name: httpd>=2.4
state: present
- name: Install a list of packages (suitable replacement for 2.11 loop deprecation warning)
ansible.builtin.yum:
name:
- nginx
- postgresql
- postgresql-server
state: present
- name: Install a list of packages with a list variable
ansible.builtin.yum:
name: "{{ packages }}"
vars:
packages:
- httpd
- httpd-tools
ansible-playbook 命令
playbook剧本通过 ansible-playbook命令执行,其常用选项有:
- -u 指定用户
- -k 指定 ssh远程连接密码
- -K 指定 sudo提权密码。
- -C 测试运行 playbook,先运行后撤销
- -v 打印任务运行结果
- -vv 打印任务运行结果即任务的配置信息
- -vvv 打印更详细的运行信息
- –syntax-check 检查 playbook语法信息
template模块jinja2语法
- template: 使用了Jinjia2格式作为文件模版,进行文档内变量的替换的模块。相当于copy,将jinja2的文件模板理解并执行,转化为各个主机间的对应值。
如:template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
http.conf.j2必须是完整的文件内容,因为这是覆盖操作,而非只选择性远程主机替换变量,dest要指定文件名,如果是目录就相当于copy了http.conf.j2到远程目录下,不是我们要的结果。
- when语句:在tasks中使用,Jinja2的语法格式
- name: start nginx service
shell: systemctl start nginx.service
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
当系统为 centos 7的时候执行sysctemctl命令,否则不执行
ansible_distribution
和ansible_distribution_major_version
都是ansible内置变量,通过setup模块可以查看
- 循环:迭代,需要重复执行的任务
变量名为item,而with_item为要迭代的元素。如果某个任务出错,后面不执行
- name: install pac
- kages
yum:
name={{ item }}
state=latest
with_items:
- httpd
- php
这是基于字符串列表给出元素示例
- name: create users
user:
name={{ item.name }}
group={{ item.group }}
state=present
with_items:
- {name: 'userx1', group: 'groupx1'}
- {name: 'userx2', group: 'groupx2'}
这是基于字典列表给元素示例:item.name . 后边的表示键。
在这篇文章中,我们学习了如何安装和使用Ansible,以及如何配置Ansible的配置文件和主机清单。我们还学习了Ansible的一些常用模块,如copy、raw、yum等,以及如何使用Ansible Playbook编写自动化脚本。通过使用Ansible,我们可以更高效地管理服务器,减少人工操作的错误率,提高运维工作的效率。
本文提供的模块示例仅包含常用选项,而非所有选项。你可以通过在命令行中输入ansible-doc 模块名称
来查看所有选项。