ansible的安装和操作,并编写一个docker部署的示例【测试成功】

艺帆风顺 发布于 2025-04-03 22 次阅读


一、安装ansible

没安python包的机器需要下载python3.7安装包并解压

  1. 安装wget yum -y install wget

  2. 下载python文件 wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz如果离线安装的话可以预先把压缩包准备好

  3. 解压文件 tar zxvf Python-3.7.0.tgz

  4. 切换到目录下 cd Python-3.7.0

编译并安装

  1. 编译 ./configure --prefix=/usr/local/bin/python3 (可能提示error: no acceptable C compiler found in $PATH,此时需安装gcc yum -y install gcc,然后再执行)

  2. make

  3. make install (可能提示zipimport.ZipImportError: can’t decompress data; zlib not available ,此时需安装yum -y install zlib*,再执行)(可能提示ModuleNotFoundError: No module named ‘_ctypes’ make: *** [install] Error 1,此时需安装yum install libffi-devel -y,再执行)

修改默认版本

  1. 查看python版本 python -V仍显示python 2.7

  2. 查看python3.7的版本 `/usr/local/bin/python3/bin/python3 -V 显示python 3.7.0

  3. 查看python命令的绝对路径which python 显示/usr/bin/python

  4. 删除当前软连接 rm -rf /usr/bin/python

  5. 新建python3软连接 ln -s /usr/local/bin/python3/bin/python3 /usr/bin/python

  6. 查看效果 python -V 显示python 3.7.0

恢复yum

  1. 修改完python的默认版本后,yum命令无法再执行。

  2. vim /usr/bin/yum将文件第一行改为/usr/bin/python2.7。(2.7.x也改为2.7)

  3. vim /usr/libexec/urlgrabber-ext-down 将文件第一行改为/usr/bin/python2.7

  4. 这样python3.7就安装在CentOS上,同时又能够使用yum来安装软件了。

安装pip

 curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py

//如果离线安装的话可以预先把压缩包准备好
sudo python3 get-pip.py

通过pip安装ansible

 python -m pip install ansible

使用`ansible --version测试安装是否成功

[root@host ~]# ansible --version
ansible 2.4.2.0
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 = /bin/ansible
python version = 2.7.5 (default, Apr 9 2019, 14:30:50) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]

二、Ansible 基础使用

ansible 是基于ssh隧道进行连接运行的,故只要系统得ssh可以使用则ansible就可以使用。

配置文件

ansible在使用配置文件时按照以下顺序优先配置:

export ANSIBLE_CONFIG

./ansible.cfg

~/.ansible.cfg

/etc/ansible/ansible.cfg

如果以上顺序没有找到配置文件ansible会自动使用默认配置

可以去github上把默认配置拿下来:

https://raw.githubusercontent.com/ansible/ansible/devel/examples/ansible.cfg

把它放到/etc/ansible/目录

配置文件主要配置:

 # 默认配置项
[defaults]
ask_pass:控制Ansible剧本playbook是否会自动默认弹出密码
ask_sudo_pass:用户系统开启了sudo的密码需要开启这个参数
gather_subset 设置收集的内容
#要自动化处理的客户端的信息
remote_port客户机ssh端口
remote_tmp客户机目录
remote_user客户机目录
sudo_exe sudo命令的路径
sudo_flags sudo命令的参数
sudo_user 可以使用sudo的用户
# 开发者中心的插件相关功能,开发者可以开发相应的插件完成自己的功能
action_plugins 激活事件
callback_plugins 回调
connection_plugins 连接插件
lookup_plugins 加载路径
vars_plugins 任何地方加载
filter_plugins 过滤器
forks 最大开辟的子进程数,过大会导致性能耗费高,过小的话并发性低,一般来说是CPU核数*2
module_name /usr/bin/ansible默认模块名
pattern playbook要通信的默认主机组
inventory 存放可通信主机的目录
library Ansible默认搜寻模块路径
#用户权限设置

[privilege_escalation]
#paramiko插件配置(不是所有情况都启用插件)
[paramiko_connection]
#ssh连接设置
[ssh_connection]

添加一台机器

1.编辑/etc/ansible/hosts

194.168.0.46 将46的控制权限添加到列表中

2.添加控制机的public SSH key到被控制机器的authorized_keys中

cat .ssh/id_rsa.pub查看公钥(没有的话:ssh-keygen -t rsa )

 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC39Ob41GSi4Yxuy1BaKnBON1LPUyP9SN4wv4IWi+xJ99aOa5iuafoH3KLIA8RIVw0BY50zFhlghCktqcBtaH6UT7KG27+G7GWOzI7gwKKg1ajGtYRQ+7x+WN123oUk+p1aiaxvYrhukSqwYyomKJFDL74CYXU4H5EfOAg6jhYIDD/K63VYIw6KdEiiyBAR6RqdmRFd9ozxwH/5uLD5PDKlpo753QHyubk4XyKil2WVREWREosZTZ5L5QqQf2kAJTyV09LxBhg6vNXr6pHbPi5mizgd7rmyVpIiJjh+R5Xw54igBMskICePFPiS9+wLITyoO5qptnJdeiJ2LTOvlhvt root@ebb7023

将194.168.0.23的公钥添加到194.168.0.64的authorized_keys中

3.添加本机的私钥到Ansible(可省略)

4.运行ansible all -m ping测试是否添加成功

[root@host ~]# ansible all -m ping
10.1.114.53 | SUCCESS => {
"changed": false,
"ping": "pong"
}

success表示了操作的成功与否。

这里changed为false时,表示ansible没有进行任何操作,因为当前的被操作主机已经是我们想要达到的目标状态了。

changed为true时,表示ansible执行了操作,"当前状态"已经被ansible改变成了"目标状态"

简单操作

ansible all -m ping命令的解读:

ansible是命令主体--ansible/ansible-playbook

被操作的目标及其的正则表达式--all

指定要使用的模块-- -m ping

-a指定传入的参数

-v显示检索到的配置文件

-C -D两个一起使用,检查hosts规则文件的修改

-l 限制匹配规则的主机数

--list-hosts显示所有匹配规则的主机数

-m -M 指定所使用的模块和模块的路径。

--syntax-check检查语法

举例:

ansible all -a 'ls'

相当于在所有的被控制机上执行命令‘ls’即将ls这个参数传给要使用的模块,让它在被控制机器上执行。

对主机分组

Ansible可同时操作属于一个组的多台主机,组合主机之间的关系通过inventory文件配置,默认的文件路径为/etc/ansible/hosts

[webservers]
194.168.0.23
194.168.0.46

也就是说,194.168.0.23和194.168.0.46同属于webservers组中,当对该组操作时,会同时操作194.168.0.23和194.168.0.46.

分组操作:

ansible webservers -a 'ls'

如果出现了主机之间端口不一致可以在host文件注明端口号

194.168.0.23:8080

IP域名起别名(jumper): jumper ansible_ssh_port=5555,ansible_ssh_host=194.168.0.23(这配置是放在hosts文件中)

不想以root登录:jumper ansible_ssh_port =555 ansible_ssh_host=194.168.0.13 ansible_ssh_user=papa ansible_ssh_pass=papa@!123

ansible_ssh_user(用户名)

ansible_ssh_pass(密码)

机器如果有连着的,可以使用以下方式(也支持字母表):

[vim]

194.168.0.[1:50]

分文件管理

/etc/ansible/group_vars/vim

/etc/ansible/group_vars/webservers

/etc/ansible/group_vars/test

vim文件大致内容:

ntp_server:194.168.0.23

database_server:194.168.0.24

这时的文件名就是组名

ansible payerns

所有机器:all或者*

通过域名或者ip指定某个机器

指定连续的机器194.168.0.开头的: 194.168.0.*

指定不相关的机器: 194.168.0.24:10.2.70.28

通过组名指定:

在组vim和组test的机器 vim:test

在组vim但是不在组test的 vim:!test

在组vim也在组test的 vim:&test

与和非的匹配是从左到右依次匹配

ad-Hoc

如果我们可以使用一些命令去比较快的完成一些事情,而不需要将这些执行命令特别的保存下来,这样的命令就是ad-hoc,即临时命令。

ansible test -a “/sbin/reboot”-f 10对test组中的所有机器执行“/sbin/reboot”命令,执行时fork出10个子进程(bash)并行执行。

ansible test -a “/usr/bin/foo”-u username通过指定用户username执行命令

ansible test -a “/usr/bin/foo”-u username --sudo[-ask-sudo-pass]通过指定用户username执行sudo的命令

ansible中的变量

变量是应用于多个主机的便捷方式; 实际在主机执行之前,变量会对每个主机添加,然后在执行中引用

  • 命令行传递

-e VAR=VALUE

  • 配置文件中针对某个主机或者某个组的变量

 [webservers]
192.168.1.100 ansible_ssh_user=root hostname=web1
192.168.1.100 ansible_ssh_user=root hostname=web2

[webservers:vars]
ansible_ssh_user=root hostname=web1
  • 文件存储的变量

Ansible中的首选做法是不将变量存储在配置文件(hosts)中。

除了将变量直接存储在配置文件(hosts)之外,主机和组变量还可以存储在相对于配置文件(hosts)的单个文件中。

组变量:

group_vars 存放的是组变量

group_vars/all.yml 表示所有主机有效,等同于[all:vars]

grous_vars/etcd.yml 表示etcd组主机有效,等同于[etcd:vars]

 # vi /etc/ansible/group_vars/all.yml
work_dir: /data
# vi /etc/ansible/host_vars/webservers.yml
nginx_port: 80

三、ansible的部分模块介绍

ansible-doc –l 查看所有模块

ansible-doc –s copy 查看模块文档

模块文档:https://docs.ansible.com/ansible/latest/modules/modules_by_category.html

command模块

command模块可以帮助我们在远程主机上执行命令

注意:使用command模块在远程主机中执行命令时,不会经过远程主机的shell处理,在使用command模块时,如果需要执行的命令中含有重定向、管道符等操作时,这些符号也会失效,比如"", "|", ";" 和 "&" 这些符号,如果你需要这些功能,可以参考后面介绍的shell模块,还有一点需要注意,如果远程节点是windows操作系统,则需要使用win_command模块

free_form参数 :必须参数,指定需要远程执行的命令,需要说明一点,free_form参数与其他参数并不相同,在之前的模块示例中,如果想要使用一个参数,那么则需要为这个参数赋值,举个例子,之前的示例模块中,大多都有path参数,当我们需要指定要操作的文件时,通常需要对path参数赋值,比如,path=/testdir/test,表示我们想要操作/testdir/test文件,但是free_form参数则不同,"free_form"并不是一个"实际存在"的参数名,比如,当我们想要在远程主机上执行ls命令时,我们并不需要写成"free_form=ls" ,这样写反而是错误的,因为并没有任何参数的名字是free_form,当我们想要在远程主机中执行ls命令时,直接写成ls即可,这就是free_form参数的含义,因为command模块的作用是执行命令,所以,任何一个可以在远程主机上执行的命令都可以被称为free_form,如果你还是不明白,看下面的小示例就行了。

chdir参数 : 此参数的作用就是指定一个目录,在执行对应的命令之前,会先进入到chdir参数指定的目录中。

creates参数 :看到creates,你可能会从字面上理解这个参数,但是使用这个参数并不会帮助我们创建文件,它的作用是当指定的文件存在时,就不执行对应命令,比如,如果/testdir/test文件存在,就不执行我们指定的命令。

removes参数 :与creates参数的作用正好相反,它的作用是当指定的文件不存在时,就不执行对应命令,比如,如果/testdir/tests文件不存在,就不执行我们指定的命令,此参数并不会帮助我们删除文件

 ansible test -m command -a "ls"
#在test主机上执行ls命令,因为我使用的是root用户,所以默认情况下,ls出的结果是test70主机中root用户家目录中的文件列表。

ansible test -m command -a "chdir=/testdir ls"
#chdir参数表示执行命令之前,会先进入到指定的目录中,所以如下命令表示查看test主机上/testdir目录中的文件列表

shell模块

shell模块可以帮助我们在远程主机上执行命令,与command模块不同的是,shell模块在远程主机中执行命令时,会经过远程主机上的/bin/sh程序处理。

free_form参数 :必须参数,指定需要远程执行的命令,但是并没有具体的一个参数名叫free_form,具体解释参考command模块。

chdir参数 : 此参数的作用就是指定一个目录,在执行对应的命令之前,会先进入到chdir参数指定的目录中。

creates参数 :使用此参数指定一个文件,当指定的文件存在时,就不执行对应命令,可参考command模块中的解释。

removes参数 :使用此参数指定一个文件,当指定的文件不存在时,就不执行对应命令,可参考command模块中的解释。

executable参数:默认情况下,shell模块会调用远程主机中的/bin/sh去执行对应的命令,通常情况下,远程主机中的默认shell都是bash,如果你想要使用其他类型的shell执行命令,则可以使用此参数指定某种类型的shell去执行对应的命令,指定shell文件时,需要使用绝对路径。

 #使用shell模块可以在远程服务器上执行命令,它支持管道与重定向等符号。
ansible test -m shell -a "chdir=/testdir echo test > test"

script模块

script模块可以帮助我们在远程主机上执行ansible主机上的脚本,也就是说,脚本一直存在于ansible主机本地,不需要手动拷贝到远程主机后再执行。

free_form参数 :必须参数,指定需要执行的脚本,脚本位于ansible主机本地,并没有具体的一个参数名叫free_form,具体解释参考command模块。

chdir参数 : 此参数的作用就是指定一个远程主机中的目录,在执行对应的脚本之前,会先进入到chdir参数指定的目录中。

creates参数 :使用此参数指定一个远程主机中的文件,当指定的文件存在时,就不执行对应脚本,可参考command模块中的解释。

removes参数 :使用此参数指定一个远程主机中的文件,当指定的文件不存在时,就不执行对应脚本,可参考command模块中的解释。

如下命令表示ansible主机中的/testdir/atest.sh脚本将在test70主机中执行,执行此脚本之前,会先进入到test70主机中的/opt目录

 #如下命令表示ansible主机中的/testdir/atest.sh脚本将在test主机中执行,执行此脚本之前,会先进入到test主机中的/opt目录
ansible test -m script -a "chdir=/opt /testdir/atest.sh"

copy模块

copy 模块的作用就是拷贝文件,它与之前介绍过的 fetch 模块类似,不过,fetch 模块是从远程主机中拉取文件到 ansible 管理主机,而 copy 模块是将 ansible 管理主机上的文件拷贝到远程主机中。

src参数 :用于指定需要copy的文件或目录。

dest参数 :用于指定文件将被拷贝到远程主机的哪个目录中,dest为必须参数。

content参数 :当不使用src指定拷贝的文件时,可以使用content直接指定文件内容,src与content两个参数必有其一,否则会报错。

force参数 : 当远程主机的目标路径中已经存在同名文件,并且与ansible主机中的文件内容不同时,是否强制覆盖,可选值有yes和no,默认值为yes,表示覆盖,如果设置为no,则不会执行覆盖拷贝操作,远程主机中的文件保持不变。

backup参数 : 当远程主机的目标路径中已经存在同名文件,并且与ansible主机中的文件内容不同时,是否对远程主机的文件进行备份,可选值有yes和no,当设置为yes时,会先备份远程主机中的文件,然后再将ansible主机中的文件拷贝到远程主机。

owner参数 : 指定文件拷贝到远程主机后的属主,但是远程主机上必须有对应的用户,否则会报错。

group参数 : 指定文件拷贝到远程主机后的属组,但是远程主机上必须有对应的组,否则会报错。

mode参数 : 指定文件拷贝到远程主机后的权限,如果你想将权限设置为”rw-r--r--“,则可以使用mode=0644表示,如果你想要在user对应的权限位上添加执行权限,则可以使用mode=u+x表示。

 ansible test -m copy -a "src=/etc/ansible/hosts dest=/"
#文件分发:源文件及路径/etc/ansible/hosts ,目标路径/,目标主机:test分组的所有主机

file模块

file模块以完成创建文件或目录、删除文件或目录、修改文件权限等操作

path参数 :必须参数,用于指定要操作的文件或目录,在之前版本的ansible中,使用dest参数或者name参数指定要操作的文件或目录,为了兼容之前的版本,使用dest或name也可以。

state参数 :此参数非常灵活,此参数对应的值需要根据情况设定,比如,当我们需要在远程主机中创建一个目录的时候,我们需要使用path参数指定对应的目录路径,假设,我想要在远程主机上创建/testdir/a/b目录,那么我则需要设置path=/testdir/a/b,但是,我们无法从"/testdir/a/b"这个路径看出b是一个文件还是一个目录,ansible也同样无法单单从一个字符串就知道你要创建文件还是目录,所以,我们需要通过state参数进行说明,当我们想要创建的/testdir/a/b是一个目录时,需要将state的值设置为directory,"directory"为目录之意,当它与path结合,ansible就能知道我们要操作的目标是一个目录,同理,当我们想要操作的/testdir/a/b是一个文件时,则需要将state的值设置为touch,当我们想要创建软链接文件时,需将state设置为link,想要创建硬链接文件时,需要将state设置为hard,当我们想要删除一个文件时(删除时不用区分目标是文件、目录、还是链接),则需要将state的值设置为absent,"absent"为缺席之意,当我们想让操作的目标"缺席"时,就表示我们想要删除目标。

src参数 :当state设置为link或者hard时,表示我们想要创建一个软链或者硬链,所以,我们必须指明软链或硬链链接的哪个文件,通过src参数即可指定链接源。

force参数 : 当state=link的时候,可配合此参数强制创建链接文件,当force=yes时,表示强制创建链接文件,不过强制创建链接文件分为两种情况,情况一:当你要创建的链接文件指向的源文件并不存在时,使用此参数,可以先强制创建出链接文件。情况二:当你要创建链接文件的目录中已经存在与链接文件同名的文件时,将force设置为yes,回将同名文件覆盖为链接文件,相当于删除同名文件,创建链接文件。情况三:当你要创建链接文件的目录中已经存在与链接文件同名的文件,并且链接文件指向的源文件也不存在,这时会强制替换同名文件为链接文件。

owner参数 :用于指定被操作文件的属主,属主对应的用户必须在远程主机中存在,否则会报错。

group参数 :用于指定被操作文件的属组,属组对应的组必须在远程主机中存在,否则会报错。

mode参数:用于指定被操作文件的权限,比如,如果想要将文件权限设置为"rw-r-x---",则可以使用mode=650进行设置,或者使用mode=0650,效果也是相同的,如果你想要设置特殊权限,比如为二进制文件设置suid,则可以使用mode=4700。

recurse参数:当要操作的文件为目录,将recurse设置为yes,可以递归的修改目录中文件的属性。

 # 在创建文件或目录的时候指定属组或者修改远程主机上的文件或目录的属组。
ansible test -m file -a "path=/testdir/abb state=touch group=zsy"

blockinfile模块

这个模块可以在指定的文件中插入一段文本,而且这段文本会被标记,以后的操作可以找到这段文本修改或者删除

path参数 :必须参数,指定要操作的文件。

block参数 :此参数用于指定我们想要操作的那"一段文本",此参数有一个别名叫"content",使用content或block的作用是相同的。

marker参数 :假如我们想要在指定文件中插入一段文本,ansible会自动为这段文本添加两个标记,一个开始标记,一个结束标记,默认情况下,开始标记为# BEGIN ANSIBLE MANAGED BLOCK,结束标记为# END ANSIBLE MANAGED BLOCK,我们可以使用marker参数自定义"标记",比如,marker=#{mark}test ,这样设置以后,开始标记变成了# BEGIN test,结束标记变成了# END test,没错,{mark}会自动被替换成开始标记和结束标记中的BEGIN和END,我们也可以插入很多段文本,为不同的段落添加不同的标记,下次通过对应的标记即可找到对应的段落。

state参数 : state参数有两个可选值,present与absent,默认情况下,我们会将指定的一段文本"插入"到文件中,如果对应的文件中已经存在对应标记的文本,默认会更新对应段落,在执行插入操作或更新操作时,state的值为present,默认值就是present,如果对应的文件中已经存在对应标记的文本并且将state的值设置为absent,则表示从文件中删除对应标记的段落。

insertafter参数 :在插入一段文本时,默认会在文件的末尾插入文本,如果你想要将文本插入在某一行的后面,可以使用此参数指定对应的行,也可以使用正则表达式(python正则),表示将文本插入在符合正则表达式的行的后面,如果有多行文本都能够匹配对应的正则表达式,则以最后一个满足正则的行为准,此参数的值还可以设置为EOF,表示将文本插入到文档末尾。

insertbefore参数 :在插入一段文本时,默认会在文件的末尾插入文本,如果你想要将文本插入在某一行的前面,可以使用此参数指定对应的行,也可以使用正则表达式(python正则),表示将文本插入在符合正则表达式的行的前面,如果有多行文本都能够匹配对应的正则表达式,则以最后一个满足正则的行为准,此参数的值还可以设置为BOF,表示将文本插入到文档开头。

backup参数 :是否在修改文件之前对文件进行备份。

create参数 :当要操作的文件并不存在时,是否创建对应的文件。

 #假如,我们想要在test的主机中的/testdir/rc.local文件尾部插入如下两行
systemctl start mariadb
systemctl start httpd
#可以使用如下命令
ansible test -m blockinfile -a 'path=/testdir/rc.local block="systemctl start mariadbnsystemctl start httpd" '

lineinfile模块

lineinfile模块,用于对文件内容的修改。

path参数 :必须参数,指定要操作的文件。

line参数 : 使用此参数指定文本内容。

regexp参数 :使用正则表达式匹配对应的行,当替换文本时,如果有多行文本都能被匹配,则只有最后面被匹配到的那行文本才会被替换,当删除文本时,如果有多行文本都能被匹配,这么这些行都会被删除。

state参数:当想要删除对应的文本时,需要将state参数的值设置为absent,absent为缺席之意,表示删除,state的默认值为present

backrefs参数:默认情况下,当根据正则替换文本时,即使regexp参数中的正则存在分组,在line参数中也不能对正则中的分组进行引用,除非将backrefs参数的值设置为yes,backrefs=yes表示开启后向引用,这样,line参数中就能对regexp参数中的分组进行后向引用了,这样说不太容易明白,参考下面的示例命令比较直观一点,backrefs=yes除了能够开启后向引用功能,还有另一个作用,默认情况下,当使用正则表达式替换对应行时,如果正则没有匹配到任何的行,那么line对应的内容会被插入到文本的末尾,不过,如果使用了backrefs=yes,情况就不一样了,当使用正则表达式替换对应行时,同时设置了backrefs=yes,那么当正则没有匹配到任何的行时,则不会对文件进行任何操作,相当于保持原文件不变,如果没有理解,就按照下面的示例命令,动手操作一下吧,那样更加直观。

insertafter参数:借助insertafter参数可以将文本插入到“指定的行”之后,insertafter参数的值可以设置为EOF或者正则表达式,EOF为End Of File之意,表示插入到文档的末尾,默认情况下insertafter的值为EOF,如果将insertafter的值设置为正则表达式,表示将文本插入到匹配到正则的行之后,如果正则没有匹配到任何行,则插入到文件末尾,当使用backrefs参数时,此参数会被忽略。

insertbefore参数:借助insertbefore参数可以将文本插入到“指定的行”之前,insertbefore参数的值可以设置为BOF或者正则表达式,BOF为Begin Of File之意,表示插入到文档的开头,如果将insertbefore的值设置为正则表达式,表示将文本插入到匹配到正则的行之前,如果正则没有匹配到任何行,则插入到文件末尾,当使用backrefs参数时,此参数会被忽略。

backup参数:是否在修改文件之前对文件进行备份。

create参数 :当要操作的文件并不存在时,是否创建对应的文件。

举例:

# cat /testdir/test
This is a file
The file is very simple
hello world!
# 如果指定的文本本来就存在于文件中,则不做任何操作,如果不存在,默认在文件的末尾插入这行文本
ansible 194.168.0.46 -m lineinfile -a 'path=/testdir/test line="hello text"'

yum_repository模块

yum_repository模块用于管理远程主机上的yum仓库

name参数:必须参数,用于指定要操作的唯一的仓库ID,也就是".repo"配置文件中每个仓库对应的"中括号"内的仓库ID

baseurl参数:此参数用于设置yum仓库的baseurl

description参数:此参数用于设置仓库的注释信息,也就是".repo"配置文件中每个仓库对应的"name字段"对应的内容。

file参数:此参数用于设置仓库的配置文件名称,即设置".repo"配置文件的文件名前缀,在不使用此参数的情况下,默认以name参数的仓库ID作为".repo"配置文件的文件名前缀,同一个'.repo'配置文件中可以存在多个yum源

enabled参数:此参数用于设置是否激活对应的yum源,此参数默认值为yes,表示启用对应的yum源,设置为no表示不启用对应的yum源。

gpgcheck参数:此参数用于设置是否开启rpm包验证功能,默认值为no,表示不启用包验证,设置为yes表示开启包验证功能。

gpgcakey参数:当gpgcheck参数设置为yes时,需要使用此参数指定验证包所需的公钥

state参数:默认值为present,当值设置为absent时,表示删除对应的yum源

 #在test主机上设置ID为aliEpel 的yum源,仓库配置文件路径为/etc/yum.repos.d/aliEpel.repo
ansible test -m yum_repository -a 'name=aliEpel description="alibaba EPEL" baseurl=https://mirrors.aliyun.com/epel/$releaseverServer/$basearch/'

yum模块

yum 模块可以帮助我们在远程主机上通过 yum 源管理软件包。

name参数:必须参数,用于指定需要管理的软件包,比如 nginx。

state参数:用于指定软件包的状态 ,默认值为。present,表示确保软件包已经安装,除了。present,其他可用值有 installed、latest、absent、removed,其中 installed 与present 等效,latest 表示安装 yum 中最新的版本,absent 和 removed 等效,表示删除对应的软件包。

disable_gpg_check参数:用于禁用对 rpm 包的公钥 gpg 验证。默认值为 no,表示不禁用验证,设置为 yes 表示禁用验证,即不验证包,直接安装。在对应的 yum 源没有开启 gpg 验证的情况下,需要将此参数的值设置为 yes,否则会报错而无法进行安装。

enablerepo参数:用于指定安装软件包时临时启用的 yum 源。假如你想要从A源中安装软件,但是你不确定A源是否启用了,你可以在安装软件包时将此参数的值设置为 yes,即使A源的设置是未启用,也可以在安装软件包时临时启用A源。

disablerepo参数:用于指定安装软件包时临时禁用的 yum 源。某些场景下需要此参数,比如,当多个 yum 源中同时存在要安装的软件包时,你可以使用此参数临时禁用某个源,这样设置后,在安装软件包时则不会从对应的源中选择安装包。

enablerepo 参数和 disablerepo 参数可以同时使用

 ansible test -m yum -a"name=acme state = present"
#确认一个软件包已经安装,但是不升级它

ansible webservers -m yum -a "name=nginx state=latest"
#安装nginx,最新版本,安装过程中的信息会全部输出值屏幕端

unarchive模块

用于解压文件,模块包含如下选项:

copy:在解压文件之前,是否先将文件复制到远程主机,默认为yes。若为no,则要求目标主机上压缩包必须存在。

creates:指定一个文件名,当该文件存在时,则解压指令不执行

dest:远程主机上的一个路径,即文件解压的路径

grop:解压后的目录或文件的属组

list_files:如果为yes,则会列出压缩包里的文件,默认为no,2.0版本新增的选项

mode:解决后文件的权限

src:如果copy为yes,则需要指定压缩文件的源路径

owner:解压后文件或目录的属主

service模块

 ansible webservers -m service -a "name=nginx enabled=true state=started"
#开启nginx服务,并设置成开机自启

四、ansible playbook介绍

什么是ansible playbook,以及他的作用

当我们要安装某个软件并启动时,我们需要很多条命令,以nginx为例:

 #配置对应的yum源
ansible test -m yum_repository -a 'name=aliEpel description="alibaba EPEL" baseurl=https://mirrors.aliyun.com/epel/$releaseverServer/$basearch/'
#使用yum模块安装nginx
ansible test -m yum -a 'name=nginx disable_gpg_check=yes enablerepo=aliEpel'
#使用service模块启动nginx
ansible test -m service -a "name=nginx state=started"

但是在工作中如果有新机器加入进来,每次用命令显得有些繁琐,如果是一些安装起来较为复杂的软件,环境配置要求很多的情况下会非常麻烦,故ansible提供了剧本:playbook,将ad-hoc命令按照顺序编写在在一个可执行文件中,语法遵循yaml语法。

示例:

#原ad-hoc命令
#使用ping模块去ping主机test70
ansible 194.168.0.46 -m ping
#再用file模块在test70主机上创建目录
ansible 194.168.0.46 -m file -a "path=/testdir/test state=directory"
#test.yaml
---
- hosts: 194.168.0.46
remote_user: root
tasks:
- name: ping46
ping:
- name: mkdir test
file:
path: /testdir/test
state: directory

如上所示:

在YAML语法中:---表示文档开始。

下面-开头(有空格),表示一个块的节点,host表明要操作的主机,host关键字对应值为194.168.0.22,表示在该主机上操作。

下面的remote_user表示远程操作时使用的用户,这里我们使用194.168.0.22的root用户。这行要与host对齐,yaml中不识别tab

tasts表示要执行的任务列表,每个play包含一系列任务。这些任务按照顺序执行,在play中,所有主机都会执行相同的任务指令。play目的是将选择的主机映射到任务。任务列表的起名比较随意。

每个任务以- 开头,上面的语法中ping模块没有指定参数,而使用file模块时制定了path和state的值。

[root@ohost ~]# ansible-playbook test.yml 

PLAY [etcd] ********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [194.168.0.46]

TASK [ping64] ******************************************************************
ok: [194.168.0.46]

TASK [mkdir test] **************************************************************
changed: [194.168.0.46]

PLAY RECAP *********************************************************************
194.168.0.46 : ok=3 changed=1 unreachable=0 failed=0

 #检查yaml有没有语法错误
ansible-playbook --syntax-check test.yaml
#模拟运行(不会真的运行,只是帮助我们预估该yml文件能不能运行,但是如果yaml中的任务有前后依赖关系,那模拟执行会失败)
ansible-playbook --check test.yaml

看下面的例子:

 tasks: - name: make testfile file: path: /testdir/testfile state: touch mode: 0700 #设置权限为0700

也可以编写成如下格式:

 tasks: - name: make testfile file: path=/testdir/testfile state=touch mode=0700

常用模块的playbook语法

该处用到的参数均可在上面的模块介绍中找到,也可以在安装了ansible的机器上查看帮助文档。这里以几个常用的模块为例示范对应的playbook语法

shell

 - name: 将命令结果输出到指定文件
shell: somescript.sh >> somelog.txt
- name: 切换目录执行命令
shell:
cmd: ls -l | grep log
chdir: somedir/
- name: 编写脚本
shell: |
if [ 0 -eq 0 ]; then # 比较0和0 的值,一致则输出yes到result,否则输出no
echo yes > /tmp/result
else
echo no > /tmp/result
fi
args:
executable: /bin/bash #用什么执行脚本

copy

 - name: 拷贝文件
copy:
src: /srv/myfiles/myfile.conf
dest: /etc/myfile.conf
owner: wang
group: wang
mode: u=rw,g=r,o=r #相当于命令中的u+rw,g-wx,o-rwx 或者使用mode: '0644'
backup: yes

file

 - name: 创建目录
file:
path: /etc/some_directory
state: directory
mode: '0755'
- name: 删除文件
file:
path: /etc/foo.txt
state: absent
- name: 递归删除目录
file:
path: /etc/foo
state: absent

yum

 - name: 安装最新版apache
yum:
name: httpd
state: latest
- name: 安装列表中所有包
yum:
name:
- nginx
- postgresql
- postgresql-server
state: present
- name: 卸载apache包
yum:
name: httpd
state: absent
- name: 更新所有包
yum:
name: '*'
state: latest
- name: 安装nginx来自远程repo
yum:
name: http://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.14.0-1.el7_4.ngx.x86_64.rpm
# name: /usr/local/src/nginx-release-centos-6-0.el6.ngx.noarch.rpm
state: present
- name: 安装nginx最新版
yum: pkg=nginx state=latest

unarchive

 - name: 解压文件/tmp/test.tar.gz 
unarchive:
src: test.tar.gz
dest: /tmp/

service

 - name: 服务管理
service:
name: etcd
state: started
#state: stopped
#state: restarted
#state: reloaded
- name: 设置开机启动
service:
name: httpd
enabled: yes

debug

将上一步任务执行的结果打印出来,在这一步会将4台主机的执行结果都返回,不管成功或是失败都会显示出来。

 - hosts: all
remote_user: root
tasks:
- name: 查看root目录下的文件
shell:
cmd: ls -l
chdir: /root/
- name: 输出的结果
debug:
var: result

playbook中的变量

全局变量/组变量/主机变量

 ---
- hosts: webservers
vars: # 这种变量对于hosts组都有效
http_port: 80
server_name: www.ctnrs.com

响应变量 接收任务的响应

 tasks:
- name: 只在192.168.1.100运行任务
shell:
cmd: ls -l | grep log
chdir: somedir/
register: result

五、playbook中的常用流程控制

条件

 tasks:
- name: 只在192.168.1.100运行任务
shell:
cmd: ls -l | grep log
chdir: somedir/
register: result
- debug: var=result
when: ansible_default_ipv4.address == '192.168.1.100'

循环

 tasks:
- name: 批量创建用户
user: name={{ item }} state=present groups=wheel
with_items:
- testuser1
- testuser2
- name: 遍历/temp中所有txt文件的文件名
copy: src={{ item }} dest=/tmp
with_fileglob:
- "*.txt"

常用循环语句:

语句描述with_items标准循环with_fileglob遍历文件名称with_dict遍历字典with_file遍历文件内容

注意这里with_file和with_fileglob的区别,如果我们用debug输出结果会发现,with_file中debug打出来的是文件内容,而with_fileglob打出来的是文件名称

任务控制

当某个剧本中有很多任务时,可能我们只要执行其中的某个步骤,那么我们可以给它打标签:

 tasks:
- name: 安装nginx最新版
yum: pkg=nginx state=latest
tags: install
- name: 写入nginx配置文件
template: src=/srv/httpd.j2 dest=/etc/nginx/nginx.conf
tags: config
- name: 批量创建用户
user: name={{ item }} state=present groups=wheel
with_items:
- testuser1
- testuser2
tags: adduser

使用如下命令可以只执行打了某个标签的任务,或者跳过某个标签的任务

 ansible-playbook test.yml --tags "install"
ansible-playbook test.yml --tags "install,config"
ansible-playbook test.yml --skip-tags "install"

模板

Jinja2是基于python的模板引擎

 vars:
domain: "www.ctnrs.com"
tasks:
- name: 写入nginx配置文件
template: src=/srv/server.j2 dest=/etc/nginx/conf.d/server.conf
# server.j2
{% set domain_name = domain %}
server {
listen 80;
server_name {{ domain_name }};
location / {
root /usr/share/html;
}
}

在jinja里使用ansible变量直接 {{ }}引用。使用ansible变量赋值jinja变量不用{{ }}引用

生成的文件:

 server {
listen 80;
server_name www.ctnr.com;
location / {
root /usr/share/html;
}
}

如果使用程序流程语句:

定义变量:{% set local_ip = inventory_hostname %}

条件和循环:

 {% set list=['one', 'two', 'three'] %}
{% for i in list %}
{% if i == 'two' %}
-> two
{% elif loop.index == 3 %}
-> 3
{% else %}
{{i}}
{% endif %}
{% endfor %}

文件执行结果:

 [root@myhost ~]# vim server.conf 

one
-> two
-> 3

忽略执行出现的错误

ignore_errors: true是忽略出现的问题 ,不加默认为false,任务运行出bug时不会执行目标主机的后续任务

 - name: 安装nginx最新版
yum: pkg=nginx state=latest
tags: install
ignore_errors: true

六、一个小例子:docker安装

在files/文件目录放docker的二级制包,这是相对于yml文件的相对路径

 ---
#指定安装docker的主机组
- hosts: docker
#安装目录
vars:
tmp_dir: '/tmp/docker'
remote_user: root
gather_facts: false

tasks:

- name: 创建临时目录放配置文件和二进制包
file: dest={{ tmp_dir }} state=directory

- name: 分发并解压docker二进制包(去官网随便选个版本下就行了)
unarchive: src={{ item }} dest={{ tmp_dir }}
with_fileglob:
- "files/docker-*.tgz"

- name: 移动docker二进制文件
shell: cp -rf {{ tmp_dir }}/docker/* /usr/bin

- name: 分发service文件
copy: src=files/docker.service dest=/usr/lib/systemd/system/

- name: 创建目录
file: dest=/etc/docker state=directory

- name: 配置docker
copy: src=files/daemon.json dest=/etc/docker/daemon.json

- name: 启动docker
systemd: name=docker state=restarted enabled=yes daemon_reload=yes

- name: 查看状态
shell: docker info
register: docker
- debug: var=docker.stdout_lines
    版权声明:本文内容来自知乎:王三岁,遵循CC 4.0 BY-SA版权协议上原文接及本声明。本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行可。原文链接:https://zhuanlan.zhihu.com/p/149499486?utm_id=0如有涉及到侵权,请联系,将立即予以删除处理。在此特别鸣谢原作者的创作。此篇文章的所有版权归原作者所有,与本公众号无关,商业转载建议请联系原作者,非商业转载请注明出处。