一、ansible install
1、install ansible
yum install -y epel-release
yum install -y ansible
rpm -qc ansible(查看配置文件)
ansible-doc -l (查看所有模块)
ansible-doc -s yum (看yum模块,了解其功能)
2、ansible命令的常用选项:
-m MODULE_NAME:指定要执行的模块的名称,如果不指定-m选项,默认是COMMAND模块。
-a MODULE_ARGS,:指定执行模块对应的参数选项。
-k:提示输入SSH登录的密码而不是基于密钥的验证
-K:用于输入执行su或sudo操作时需要的认证密码。
-b:表示提升权限操作。
--become-method:指定提升权限的方法,常用的有 sudo和su,默认是sudo。
--become-user:指定执行 sudo或su命令时要切换到哪个用户下,默认是root用户。
-B :指定一个时间,命令运行时间超过时就结束此命令
-C:测试一下会改变什么内容,不会真正去执行,主要用来测试一些可能发生的变化
-f FORKS,:设置ansible并行的任务数。默认值是5
-i INVENTORY: 指定主机清单文件的路径,默认为/etc/ansible/hosts。
3、常见的警告
[WARNING]: Platform linux on host ansible1 is using the discovered Python interpreter at /usr/bin/python, but future
installation of another Python interpreter could change this
配置文件添加:
interpreter_python = auto_legacy_silent
二、Inventory
1、vim /etc/ansible/hosts
[webserver]
host1
host2
host3
host4
inventory也可直接在配置文件中指明(默认路径/etc/ansible/ansible.cfg)
inventory = ~/workspace/zjz/test.ini
2、子分组
[apache]
host[1:2]
[nginx]
host[3:4]
[webserver:children]
apache
nginx
[webserver:vars]
ansible_ssh_user='root'
ansible_ssh_pass='666666'
3、自定义主机列表
#vim hostlist
[dockers]
host1
host2
[dockers:vars]
ansible_ssh_user='root'
ansible_ssh_pass='666666'
#ansible -i hostlist dockers -m ping -o (测试)
三、常用模块
1、shell模块(-m指定模块,-a为追加操作 -o为压缩输出)
ansible all -m shell -a "echo 'mage'|passwd --stdin cui" (改密要交给shell模块,command模块很像它,但是不能改密,因为识别不了“|”管道)
ansible all -m command -a "echo 'mage'|passwd --stdin cui" (command模块只能识别最左边的一个shell命令)
ansible host2 -m shell -a 'yum -y install httpd' -o 部署apache
ansible host3 -m shell -a 'uptime' -o 查询系统负载
ansible webserver -m shell -a 'hostname' -o -f 2 -f 2 指定线程数
ansible webserver -m shell -a 'hostname' -o 获取主机名
ansible-doc shell (帮助)
2、复制模块copy,可用于远程复制脚本。
# ansible webserver -m copy -a 'src=/etc/hosts dest=/tmp/2.txt owner=root group=bin mode=777 backup=yes' (复制带备份带指定相关属性)
# ansible all -m copy -a "content='hello\nworld' dest=/tmp/zjz.ansible mode=640" (content='hello\nworld' 表示直接生成源文件,\n表回车)
3、脚本模块 script
script 模块在远程主机上执行 ansible 管理主机上的脚本,脚本一直存在于 ansible 管理主机本地,不需要手动拷贝到远程主机后再执行
free_form参数 :必须参数,指定需要执行的脚本,脚本位于 ansible 管理主机本地,并没有具体的一个参数名叫 free_form
chdir参数 : 此参数的作用就是指定一个远程主机中的目录,在执行对应的脚本之前,会先进入到 chdir 参数指定的目录中。
creates参数 :使用此参数指定一个远程主机中的文件,当指定的文件存在时,就不执行对应脚本。
removes参数 :使用此参数指定一个远程主机中的文件,当指定的文件不存在时,就不执行对应脚本,即存在就执行脚本。
示例
3.1、/testdir/testscript.sh
脚本将在web 主机清单中执行,执行此脚本之前,会先进入到 web 主机中的 /opt
目录
# ansible web -m script -a "chdir=/opt /testdir/testscript.sh"
3.2、creates参数
web 主机中的 /testdir/testfile1
文件已经存在,ansible 主机中的 /testdir/testscript.sh
脚本将不会在 web 主机中执行。
# ansible web -m script -a "creates=/testdir/testfile1 /testdir/testscript.sh"
3.3、removes参数
web 主机中的 /testdir/testfile1
文件存在,ansible 主机中的 /testdir/testscript.sh
脚本则会在 web 主机中执行。
# ansible web -m script -a "removes=/testdir/testfile1 /testdir/testscript.sh"
4、user用户模块(ansible不支持明文传输,密码需要加密处理)
安装python-pip,并安装加密函数库-passlib
yum -y install python-pip
pip install --upgrade pip
pip install passlib
python -c "from passlib.hash import sha512_crypt; import getpass; print(sha512_crypt.using(rounds=5000).hash(getpass.getpass()))"
Password: 输入密码
创建用户
ansible webserver -m user -a 'name=qianfeng state=present'
创建系统用户( system=yes)
ansible web -m user -a "name=tom state=present comment='this is user tom' system=yes password=“\$6\$ay”
删除用户
ansible webserver -m user -a 'name=qianfeng state=absent'
修改密码
1.生成加密密码
echo '777777' | openssl passwd -1 -stdin ($1$XVzsJMDr$5wI4oUaQ.emxap6s.N272.)
2.修改密码
ansible webserver -m user -a 'name=qianfeng password="$1$XVzsJMDr$5wI4oUaQ.emxap6s.N272."'
3.修改shell
shell ansible webserver -m user -a 'name=qianfeng shell=/sbin/nologin append=yes' 追加
5、软件包管理
#ansible host2 -m yum -a 'name="httpd" state=latest' 安装apache。latest最新的
# ansible-doc yum
- state
install (`present' or `installed', `latest')
remove (`absent' or`removed') a package
6、服务模块
ansible host2 -m service -a 'name=httpd state=started'
ansible host2 -m service -a 'name=httpd state=started enabled=yes'
ansible host2 -m service -a 'name=httpd state=stopped'
ansible host2 -m service -a 'name=httpd state=restarted'
ansible host2 -m service -a 'name=httpd state=started enabled=no'
7、文件模块(设置文件属性)
ansible host1 -m file -a 'path=/tmp/88.txt mode=777 state=touch'
ansible host1 -m file -a 'path=/tmp/99 mode=777 state=directory'
ansible all -m file -a 'path=/tmp/fstab.ansible state=absent'
ansible all -m file -a 'path=/tmp/zjz.ansible.link src=/tmp/zjz.ansible state=link' 设置链接文件
8、setup收集模块(playbook默认运行)
运行playbook时,默认都会运行一个名为”[Gathering Facts]”的任务,ansible通过”[Gathering Facts]”这个默认任务收集远程主机的相关信息(例如远程主机的IP地址,主机名,系统版本,硬件配置等信息),这些被收集到的远程主机信息会保存在对应的变量中,当需要使用这些信息时,可以获取对应的变量,从而使用这些信息。
返回信息很多,比如:
“ansible_all_ipv4_addresses”表示远程主机中的所有ipv4地址
“ansible_distribution”表示远程主机的系统发行版
“ansible_distribution_version”表示远程主机的系统版本号
“ansible_ens35″表示远程主机ens35网卡的相关信息
“ansible_memory_mb”表示远程主机的内存配置信息
ansible host3 -m setup
ansible host3 -m setup -a 'filter=ansible_all_ipv4_addresses'(filter过滤)
只查看某一类信息,比如过滤出主机内存配置
ansible test7 -m setup -a 'filter=ansible_memory_mb'
##使用关键字
ansible test7 -m setup -a "filter=*mb*"
ansible剧本时卡顿或卡死的优化方法
1、关闭setup默认搜集:
修改配置文件/etc/ansible/ansible.cfg
vim /etc/ansible/ansible.cfg
gathering = explicit
#smart 表示默认收集 facts,但 facts 已有的情况下不会收集,即使用缓存 facts
#implicit 表示默认收集 facts,要禁止收集,必须使用 gather_facts: False
#explicit 则表示默认不收集,要显式收集,必须使用 gather_facts: Ture
2、调大并行线程数
fork 为 5, 并行进程数为5个,可根据服务器资源扩大
fact配置redis缓存方法
vim /etc/ansible/ansible.cfg
[defaults]
gathering = smart
fact_caching_timeout = 86400
fact_caching = redis
#redis的ip和端口,也可使用域名
fact_caching_connection = 192.168.1.5:6379
如果redis设置了密码为admin
fact_caching_connection = 192.168.1.5:6379:0:admin
9、cron模块
ansible all -m cron -a "minute='*/5' job='/usr/sbin/ntpdate 192.168.40.132 &>/dev/null' name='sync time'" (sync time为任务名)
ansible all -m cron -a " name='sync time' state=absent" (取消计划任务)
10、hostname
ansible all -m hostname -a name=zjz
11、fetch 拉取模块
# ansible all -m file -a "content=zjz.tx dest=/root" (先创建一个共同的文件)
# ansible all -m fetch -a "src=/root/zjz.tx dest=/tmp/ flat=yes"
注:fetch不能拉取文件夹。另外加上flat=yes参数,主要是判断dest是否以 / 结尾,从而来区分这是个目录还是路径。
# ansible web -m fetch -a "src=~/test-{{inventory_hostname}}.log dest=~/zjz/ flat=yes"
带/ 的结果如下:
#ls zjz/
test-ansible1.log test-ansible2.log test-ansible3.lo
否则生成一个叫zjz的普通文件
#ll zjz
-rw-r--r-- 1 root root 29 Nov 22 21:36 zjz
#cat zjz
Sun Nov 22 21:21:50 CST 2020
12、command 命令模块
它是ansible的默认模块,可以允许远程主机范围内的所有shell命令。
注意: 在command的命令中含有像`$ HOME'这样的变量和像``<“',`”>“, `“”“”,“”;“”和“”&“'将无法正常工作(如果需要这些功能,请使用[shell]模块)
13、debug模块
调试模块,用于在调试中输出信息 常用参数:
msg:调试输出的消息
var:将某个任务执行的输出作为变量传递给debug模块,debug会直接将其打印输出 verbosity:debug的级别(默认是0级,全部显示)
参数 | 默认值 | 解释 |
msg(string) | 默认输出:“Hello world” | 输出自定义信息,如果不指定或不写msg的话,默认也会输出“Hello world” |
var(string) | var与msg相互冲突,var涉及到变量的使用 | |
verbosity(integer) | 默认:0 | debug的调试级别,默认0是全部显示,级别调整到3是忽略内容不显示,如果verbosity参数设置为3还想像是debug内容的话,需要在命令后面加入 -vvv 参数 |
debug参数
- name: Print debug infomation eg1
hosts: test2
gather_facts: F
vars:
user: jingyong
tasks:
- name: Command run line
shell: date
register: result
- name: Show debug info
debug: var=result verbosity=0
$ ansible localhost -m debug -a 'msg="hello world"'
localhost \ sUCCESS =>{
"msg": "hello world"
}
利用debug调试playbook中变量,了解变量的值是否符合要求。
---
- hosts: test70
remote_user: root
vars:
testvar: value of test variable
tasks:
- name: debug demo
debug:
var: testvar
运行playbook即可看到var变量的值输出是否符合预期。
在屏幕中显示剧本的执行结果:
---
- hosts: web
tasks:
- name: show hostname
command: hostname
register: name
- name: print hostname
debug: msg={{name.stdout}}
debug模块,msg表示打印自定义消息,内容就是我们获取到结果的变量。
14、replace模块 和 Lineinfile模块
ansible在使用sed进行替换时,经常会遇到需要转义的问题,而且ansible在遇到特殊符号进行替换时,存在问题,无法正常进行替换 。其实在ansible自身提供了两个模块:lineinfile模块和replace模块,可以方便的进行替换
ansible all -m lineinfile -a "path=/etc/selinux/config regexp='^SELINUX=' line='SELINUX=enforcing'"
ansible all -m lineinfile -a 'dest=/etc/fstab state=absent regexp="^#"'
类似于sed命令,主要也是基于正则进行匹配和替换
ansible all -m replace -a "path=/etc/fstab regexp='^(UUID.*)' replace='#\1'"
ansible all -m replace -a "path=/etc/fstab regexp='^#(.*)' replace='\1'"
15、set_fact 模块(用于在play中定义task的变量)
可以通过set_fact模块在tasks中定义变量,也可以通过set_fact将一个变量的值赋予另一个变量:
先定义了一个变量testvar1,又使用register将shell模块的返回值注册到了变量shellreturn中,
之后,使用set_fact模块将testvar1变量的值赋予了变量testsf1,将shellreturn变量中的stdout信息赋值给了testsf2变量,(可以将注释去掉查看变量shellreturn的值。最后,使用debug模块输出了testsf1与testsf2的值。
cat bltest9.yml
---
- hosts: testB
remote_user: root
vars:
testvar1: test1_string
tasks:
- shell: "echo test2_string"
register: shellreturn
- set_fact:
testsf1: "{{testvar1}}"
testsf2: "{{shellreturn.stdout}}"
- debug:
msg: "{{testsf1}} {{testsf2}}"
#var: shellreturn
另外,通过set_fact模块创建的变量还有一个特殊性,通过set_fact创建的变量就像主机上的facts信息一样,可以在之后的play中被引用。
cat bltest10.yml
---
- hosts: testB
remote_user: root
vars:
testvar1: tv1
tasks:
- set_fact:
testvar2: tv2
- debug:
msg: "{{testvar1}} ----- {{testvar2}}"
- hosts: testB
remote_user: root
tasks:
- name: other play get testvar2
debug:
msg: "{{testvar2}}"
- name: other play get testvar1
debug:
msg: "{{testvar1}}"
例中一共有两个play,第一个play中,我们通过两种方式创建了两个变量,第一个变量testvar1使用vas关键字创建,第二个变量使用set_fact创建。
可以发现,这两个变量在第一个play中都可以正常的输出。但是在第二个play中,testvar2可以被正常输出了,testvar1却不能被正常输出,会出现未定义testvar1的
错误,因为在第一个play中针对testB主机进行操作时,testvar1是通过vars关键字创建的,而testvar2是通过set_fact创建的,所以testvar2就好像testB的facts信息
一样,可以在第二个play中引用到,而创建testvar1变量的方式则不能达到这种效果,虽然testvar2就像facts信息一样能被之后的play引用,但是在facts信息中并不能找到testvar2,只是”效果上”与facts信息相同罢了。
16、注册变量实现跨play调用变量
前文已经总结了注册变量的用法,其实注册变量也可以在之后的play操作同一主机时被调用到,
cat bltest11.yml
---
- hosts: testB
remote_user: root
vars:
testvar3: tv3
tasks:
- shell: "echo tv4"
register: testvar4
- debug:
msg: "{{testvar3}} -- {{testvar4.stdout}}"
- hosts: testB
remote_user: root
tasks:
- name: other play get testvar4
debug:
msg: "{{testvar4.stdout}}"
- name: other play get testvar3
debug:
msg: "{{testvar3}}"
http://www.yunweipai.com/34638.html ansible不错的教程
https://mp.weixin.qq.com/s/IDVKDBNVmpft9nZvhhtblg 有待整理
https://www.cnblogs.com/fanlong0212/p/12185290.html ansible 离线包制作和离线部署