Day 44 Ansible自动化运维
Ansible自动化运维
几种常用运维工具比较
Puppet
—基于 Ruby 开发,采用 C/S 架构,扩展性强,基于 SSL,远程命令执行相对较弱ruby
SaltStack
—基于 Python 开发,采用 C/S 架构,相对 puppet 更轻量级,配置语法使用 YAML,使得配置脚本更简单
Ansible
—基于 Python paramiko 开发,分布式,无需客户端,轻量级,配置语法使用YAML 及 Jinja2模板语言,更强的远程命令执行操作
Ansible简介
Ansible 基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。
connection plugins:连接插件,负责和被监控端实现通信,有SSH,ZEROMQ等,默认使用SSH连接
host inventory:主机清单,是一个配置文件里面定义监控的主机
modules : 模块,核心模块、command模块、自定义模块等
plugins : modules功能的补充,包括连接插件,邮件插件等
playbook:编排,定义 Ansible 多任务配置文件,非必需
Ansible特性
1)、no agents:不需要在被管控主机上安装任何客户端,更新时,只需在操作机上进行一次更新即可
2)、no server:无服务器端,使用时直接运行命令即可
3)、modules in any languages:基于模块工作,可使用任意语言开发模块
4)、yaml,not code:使用yaml语言定制剧本playbook
5)、ssh by default:基于SSH工作
6)、strong multi-tier solution:可实现多级指挥
Ansible安装
环境:
系统:Centos7u3 / Centos stream9
主机:4台 一个控制节点 3个被控制节点
解析:本地互相解析
192.168.245.133 web1
192.168.245.4 web2
192.168.245.10 web3
192.168.245.3 ansible
配置ssh公钥认证:
控制节点需要发送ssh公钥给所有被控制节点
安装:控制节点
1、配置EPEL网络yum源
2、安装ansible
# yum install ansible -y
# ansible --version
ansible 2.3.2.0
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides
python version = 2.7.5 (default, Aug 4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]
Ansible基本使用
1、配置主机清单文件
主机清单文件
定义所管理的主机组及主机,可以在主配置文件中指定清单文件位置和名称
默认位置/etc/ansible/hosts
主配置文件:
/etc/ansible/ansible.cfg
主要设置一些ansible初始化的信息,比如日志存放路径、模块、插件等配置信息
# vim /etc/ansible/hosts 添加被控节点
web1
web2
web3
2、基本测试
语法:
# ansible <pattern> -m <module_name> -a <arguments>
pattern--主机清单里定义的主机组名,主机名,IP,别名等,all表示所有的主机,支持通配符,正则: --多个组,组名之间用冒号隔开*web* --组名或主机名中含web的webservers[0] -- webservers组中的第一台主机以~开头,匹配正则
-m module_name: 模块名称,默认为command
-a arguments: 传递给模块的参数最常用的模块:command shell
使用ping模块检查ansible节点的连通性:
-o:- - one - line,将信息整合到一行输出。
[root@ansible ~]# ansible web1 -m ping
web1 | SUCCESS => {"changed": false, "ping": "pong"
}
[root@ansible ~]# ansible web1 -m ping -o
web1 | SUCCESS => {"changed": false, "ping": "pong"}
同时指定多台机器
[root@ansible ~]# ansible web1,web2,web3 -m ping -o
web3 | SUCCESS => {"changed": false, "ping": "pong"}
web2 | SUCCESS => {"changed": false, "ping": "pong"}
web1 | SUCCESS => {"changed": false, "ping": "pong"}[root@ansible ~]# ansible web* -m ping -o
web3 | SUCCESS => {"changed": false, "ping": "pong"}
web2 | SUCCESS => {"changed": false, "ping": "pong"}
web1 | SUCCESS => {"changed": false, "ping": "pong"}[root@ansible ~]# ansible all -m ping -o
web1 | SUCCESS => {"changed": false, "ping": "pong"}
web3 | SUCCESS => {"changed": false, "ping": "pong"}
web2 | SUCCESS => {"changed": false, "ping": "pong"}
执行shell命令
[root@ansible ~]# ansible web1 -m shell -a 'uptime'
web1 | SUCCESS | rc=0 >>
10:59:56 up 2 days, 15:04, 2 users, load average: 0.00, 0.01, 0.05[root@ansible ~]# ansible web1 -m command -a 'uptime'
web1 | SUCCESS | rc=0 >>
11:00:03 up 2 days, 15:04, 2 users, load average: 0.00, 0.01, 0.05因为默认模块就是command,所以上面命令可以不加-m:
[root@ansible ~]# ansible web1 -a 'uptime'
web1 | SUCCESS | rc=0 >>
11:01:39 up 2 days, 15:06, 2 users, load average: 0.00, 0.01, 0.05
使用ssh账户和密码
-u 用户 //指定ssh账户
-k //指定使用ssh密码(注意:如果设置了公钥认证,这里写什么密码都可以)
注意:没有传公钥的其他账户就有用了,比如上面的root换成wing账户(前提:wing账户在被控制机器中已存在)
[root@ansible ~]# ansible web1 -a 'uptime' -u root -k
SSH password:
web1 | SUCCESS | rc=0 >>
11:02:56 up 2 days, 15:07, 2 users, load average: 0.00, 0.01, 0.05
给节点增加用户
[root@vm20 ~]# ansible 192.168.245.143 -a "useradd tom"
192.168.245.143 | SUCCESS | rc=0 >>[root@vm20 ~]# ansible 192.168.245.143 -a "grep tom /etc/passwd"
192.168.245.143 | SUCCESS | rc=0 >>
tom:x:1001:1001::/home/tom:/bin/bash
重定向输出到本地文件中
[root@vm20 ~]# ansible 192.168.245.143 -a "df -h" > /tmp/a.txt
[root@vm20 ~]# cat /tmp/a.txt
192.168.245.143 | SUCCESS | rc=0 >>
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-root 17G 5.5G 12G 33% /
devtmpfs 963M 0 963M 0% /dev
tmpfs 979M 0 979M 0% /dev/shm
tmpfs 979M 9.1M 970M 1% /run
tmpfs 979M 0 979M 0% /sys/fs/cgroup
/dev/sda1 1014M 161M 854M 16% /boot
tmpfs 196M 28K 196M 1% /run/user/0
Ansible组件 - inventory
http://docs.ansible.com/ansible/intro_inventory.html#
inventory文件通常用于定义要管理主机及其认证信息,例如ssh登录用户名、密码以及key相关信息。
主机清单文件配置格式
# vim /etc/ansible/hosts
web1 #单独指定主机,可以使用主机名称或IP地址
web2
web3[webservers] #使用[]标签指定主机组
192.168.10.128
bar.example.com
up.example.com:5309 #指定 SSH 端口 5309
web5 ansible_ssh_host=web2 #设置主机web2的别名为 web5
web1 ansible_ssh_pass='123' #设置ssh密码,使用-k参数之后提示的密码可以不写,直接回车
www[01:50].example.com #支持通配符匹配www01,www02,...,www50
db-[a:f].example.com #通配符匹配db-a,db-b,...,db-f#为每个主机单独指定变量,这些变量随后可以在 playbooks 中使用
[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909#为一个组指定变量,组内每个主机都可以使用该变量
[atlanta]
host1
host2[atlanta:vars]
ansible_ssh_pass='123'
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com#组可以包含其他组
[atlanta]
host1
host2[raleigh]
host3
host4[southeast:children] #southeast包括两个子组
atlanta
raleigh[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
查看组内主机列表
[root@ansible ~]# ansible webservers --list-hosts
hosts (3):
web1
192.168.245.135
web3
手动指定其他任意位置的主机清单
[root@ansible ~]# cat web2.host
web2[root@ansible ~]# ansible web2 -a 'uptime' -i web2.host
web2 | SUCCESS | rc=0 >>
13:37:24 up 1 day, 19:03, 6 users, load average: 0.00, 0.01, 0.05
Ansible Inventory 内置参数列表
Ansible组件 - Ad-Hoc
ad hoc 临时的,在ansible中是指需要快速执行,并且不需要保存的命令。其实就是执行简单的命令,对于复杂的命令则需要playbook。
ansible-doc命令获取模块列表及模块使用格式
[root@ansible ~]# ansible-doc -l
[root@ansible ~]# ansible-doc yum
[root@ansible ~]# ansible-doc -s yum
-l 获取列表
-s module_name 获取指定模块的使用信息
执行命令
-m shell
-f 2 指定定要使用的并行进程数,默认为5个。
[root@ansible ~]# grep forks /etc/ansible/ansible.cfg
#forks = 5
[root@ansible ~]# ansible all -m shell -a ‘hostname’ -o -f 3
192.168.245.135 | SUCCESS | rc=0 | (stdout) galera4
web1 | SUCCESS | rc=0 | (stdout) web1
web2 | SUCCESS | rc=0 | (stdout) web2
web3 | SUCCESS | rc=0 | (stdout) web3
复制文件
-m copy
backup=yes被控制节点上如果有文件,则会先备份再拷贝:前提是文件内容有区别[root@web1 ~]# cat /etc/hosts.25856.2018-02-04@14\:15\:43~ 注意:src指定的是ansible本地机器上的文件
把ansible机器上的文件拷贝到远程被控之器上src=/etc/hosts # ansible all -m copy -a 'src=/etc/hosts dest=/etc/hosts owner=root group=root mode=644 backup=yes' -o注意:如果想拷贝远程机器上的文件则需要使用remote_src=yes选项
把被控机器上的文件拷贝到同一台被控机器上
# ansible c1 -m copy -a "src=/tmp/cc.txt dest=/tmp/dd.txt remote_src=yes"
用户管理
-m user
添加用户[root@ansible ~]# echo '123' | openssl passwd -1 -stdin$1$hXe3alXf$4VGhWAbRGA6tm4NMJznSf1[root@ansible ~]# ansible web1 -m user -a 'name=liudehua password="$1$hXe3alXf$4VGhWAbRGA6tm4NMJznSf1"' -o使用变量需要用双引:[root@ansible ~]# pass=`echo '1' | openssl passwd -1 -stdin`[root@ansible ~]# ansible web1 -m user -a "name=liudehua password=$pass" -o使用命令替换需要用双引:[root@ansible ~]# ansible web1 -m user -a "name=liudehua password=`echo '1234' | openssl passwd -1 -stdin" -o删除用户[root@ansible ~]# ansible web1 -m user -a "name=liudehua state=absent" -o
软件包管理
-m yum
删除软件:[root@ansible ~]# ansible web1 -m yum -a 'name=httpd state=removed'
安装软件:[root@ansible ~]# ansible web1 -m yum -a 'name=httpd state=latest'
服务管理
-m service
[root@ansible ~]# ansible webservers -m service -a 'name=httpd state=started enabled=yes' -f 3 -o
Ansible组件 - facts
facts组件是Ansible用于采集被管理主机信息的一个功能,可以使用setup模块查看主机的有的facts信息。
[root@ansible ~]# ansible web1 -m setup [root@ansible ~]# ansible web1 -m setup -a 'filter=ansible_all_ipv4_addresses'
web1 | SUCCESS => {"ansible_facts": {"ansible_all_ipv4_addresses": ["192.168.245.133"]}, "changed": false
}
将所有主机的信息输入到/tmp/facts目录下:
每台主机的信息输入到主机名文件中(/etc/ansible/hosts里的主机名)
[root@ansible ansible]# ansible all -m setup --tree /tmp/facts
查看主机内存信息
[root@ansible ansible]# ansible web1 -m setup -a 'filter=ansible_*_mb'
查看地接口为eth0-2的网卡信息
[root@ansible ansible]# ansible 10.212.52.252 -m setup -a 'filter=ansible_eth[0-2]'
Ansible组件 - PlayBook
playbook介绍
playbook是由一个或多个"play"组成的列表。play的主要功能在于将事先归为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来将,所谓的task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让他们联通起来按事先编排的机制同唱一台大戏。
playbook-->play-->task-->module
Playbook是Ansible的配置,部署,编排语言。他们可以被描述为一个需要希望远程主机执行命令的方案,或者一组IT程序运行的命令集合。
当执行一些简单的改动时ansible命令是非常有用的,然而它真的作用在于它的脚本能力。当对一台机器做环境初始化的时候往往需要不止做一件事情,这时使用playbook会更加适合。通过playbook你可以一次在多台机器执行多个指令。通过这种预先设计的配置保持了机器的配置统一,并很简单的执行日常任务。
Playbook还开创了很多特性,它可以允许你传输某个命令的状态到后面的指令,如你可以从一台机器的文件中抓取内容并附为变量,然后在另一台机器中使用,这使得你可以实现一些复杂的部署机制,这是ansible命令无法实现的。
在如右的连接中: https://github.com/ansible/ansible-examples,有一些整套的playbooks,它们阐明了上述的这些技巧。
YAML介绍
Ansible使用标准的YAML解析器,使用YAML文件语法即可书写playbook。
YAML是一个可读性高的用来表达资料序列的格式,YAML参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822等。Clark Evans在2001首次发表了这种语言。
YAML Ain’t Makup Language,即YAML不是XML。不过,在开发这种语言时,YAML的意思是:Yet Another Makrup Language(仍是一种标记语言),其特性:YAML的可读性好、YAML和脚本的交互性好、YAML有一个一致的信息模型、YAML易于实现、 YAML可以基于流来处理、YAML表达能力强,扩展性好。更多的内容及规范参见www.yaml.org。
Playbooks核心元素
- Variables # 变量元素,可传递给Tasks/Templates使用;
- Tasks # 任务元素,由模块定义的操作的列表,即调用模块完成任务;
- Templates # 模板元素,使用了模板语法的文本文件,可根据变量动态生成配置文件;
- Handlers # 处理器元素,通常指在某事件满足时触发的操作;
- Roles # 角色元素
playbook的基础组件
name
定义playbook或者task的名称
hosts
playbook中的每一个paly的目的都是为了让某个或某些以某个指定用户的身份执行任务。hosts用于指定要执行指定任务的主机,其可以是一个或多个由冒号分割主机组。与命令模式下的ansible匹配规则一样
remote_user
remote_user则用于指定远程主机上的执行任务的用户,也可以使用user
在play级别中remote_user和user都可以使用,tasks中只能使用remote_user
tasks被包含在play中,play中的参数属于全局参数,tasks中的参数属于局部参数,同等功能局部会覆盖全局,所以当play中和tasks中同时有remote_user时,tasks中remote_user会覆盖play中的remote_user(简单点就是两个都能在play中用,user只能用于play中)
tasks
任务列表
play的主体部分是task list. task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。
vars
定义变量
vars_files
定义变量文件
notify
任务执行结果如果是发生更改了的则触发定义在handler的任务执行
handlers
用于当前关注的资源发生变化时采取一定指定的操作
include
能包含的包括task,handler和playbook
可以在include的时候传递变量
示例1:简单playbook
文档以---开头,没有也可以
[root@master ~]# cd /etc/ansible/
[root@master ansible]# vim test.yml # 固定后缀为yml或者yaml
---- hosts: all # 一个完整的play,特别注意-后面的空格 指定执行本play的主机组user: root # 指定运行本play的远程主机用户tasks: - name: playbook_test # 任务描述shell: touch /tmp/playbook.txt # shell是ansible模块(module)tags: suibian # 这是一个任务标记,可用来单独执行此任务参数解释:hosts参数指定了对哪些主机进行操作;user参数指定了使用什么用户登录远程主机操作;tasks指定了一个任务,其下面的name参数同样是对任务的描述,在执行过程中会打印出来。tags:给指定的任务定义一个调用标识,形式如下- name: NAMEmodule: argumentstags: TAG_ID**语法检测**:[root@ansible ansible]# ansible-playbook --syntax-check test.yml playbook: test.yml
测试运行
[root@master ansible]# ansible-playbook -C /path/to/playbook.yaml
可以使用如下参数:
-C:--check,检查模式,模拟运行playbook中的任务,但不会实际更改目标主机的状态--list-hosts:列出playbook执行后影响的主机,但是不会执行任何操作--list-tasks:列出playbook中定义的所有任务--list-tags: 列出playbook中定义的所有可用的标签
运行Playbook:
[root@master ansible]# ansible-playbook test.yml 只运行指定标记的任务:-t tags
[root@ansible ansible]# ansible-playbook -t 标记名称 test.yml 跳过某一个被标记的任务:--skip-tags=SKIP_TAGS
[root@ansible ansible]# ansible-playbook --skip-tags=标记名称 test.yml 从某一个任务开始往下运行:--start-at-task 任务名称
[root@ansible ansible]# ansible-playbook --start-at-task "start httpd service" test.yml
示例2.每个playbook可以有多个play
[root@ansible ansible]# cat test.yml
- hosts: all # play1remote_user: roottasks:- name: install a groupgroup: name=mygrp system=true- name: install a useruser: name=user1 group=mygrp system=true- hosts: webservers # play2remote_user: roottasks:- name: install httpd packageyum: name=httpd- name: start httpd serviceservice: name=httpd state=started
示例3:使用变量
[root@ansible ansible]# cat create_user.yml
- name: create_user # 剧本描述信息hosts: web1user: rootgather_facts: falsevars:- user: "msiyuetian"tasks:- name: create useruser: name="{{ user }}"参数解释:
name参数对该playbook实现的功能做一个概述,后面执行过程中,会打印 name变量的值 ,可以省略;gather_facts参数指定了在以下任务部分执行前,是否先执行setup模块获取主机相关信息,这在后面的task会使用到setup获取的信息时用到;默认值为true,改成false之后在执行过程中就看不到以下信息:TASK [Gathering Facts] *********************************************************ok: [web1]ok: [web3]ok: [web2]ok: [192.168.245.135]vars参数指定了变量,这里指字一个user变量,其值为test ,需要注意的是,变量值一定要用引号引住;user指定了调用user模块,name是user模块里的一个参数,而增加的用户名字调用了上面user变量的值。运行playbook:
[root@master ansible]# ansible-playbook create_user.yml
示例4:条件执行
[root@master ansible]# vim when.yml
- hosts: web1user: rootgather_facts: Truetasks:- name: use whenshell: touch /tmp/when.txtwhen: ansible_hostname == "web1"[root@ansible ansible]# cat when.yml
- hosts: web1user: rootgather_facts: Truetasks:- name: use whenshell: touch /tmp/when.txtwhen: ansible_all_ipv4_addresses[0] == "192.168.245.133"只有当参数ansible_all_ipv4_addresses[0]为 192.168.245.133 时才在该机器上新建指定文件;意思就是只对 testhost 组中特定的主机进行操作,忽略组内其他的主机。可以通过setup模块查看各个参数的值setup模块变量获取:
上面的变量:ansible_hostname和ansible_all_ipv4_addresses[0] 是从setup模块中获取注意看是:"ansible_hostname": "web1"还是:"ansible_all_ipv4_addresses": ["192.168.245.133"]如果变量值是用[]括起来的需要用[0]方式切片获取[root@master ansible]# ansible-playbook when.yml
示例5:handlers:由特定条件触发的Tasks
通过 notify 调用触发 handlers
# 调用及定义方式
tasks:
- name: TASK_NAMEmodule: argumentsnotify: HANDLER_NAMEhandlers:
- name: HANDLER_NAMEmodule: arguments
handlers示例1
[root@ansible ansible]# cat handlers.yml
- name: handlers testhosts: web1user: roottasks:- name: test copycopy: src=/etc/passwd dest=/tmp/handlers.txtnotify: test handlershandlers:- name: test handlersshell: echo "www.qianfeng.com" >> /tmp/handlers.txt说明:只有 copy 模块真正执行后,才会去调用下面的 handlers 相关的操作,追加内容。所以这种比较适合配置文件发生更改后,需要重启服务的操作。
[root@master ansible]# ansible-playbook handlers.yml
handlers示例2
- hosts: websrvsremote_user: roottasks:- name: install httpd packageyum: name=httpd state=latest- name: install conf filecopy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.confnotify: restart httpd service- name: start httpd serviceservice: name=httpd state=startedhandlers:- name: restart httpd serviceservice: name=httpd state=restarted
示例6:include参数
- name: create_userhosts: web1user: rootgather_facts: falsevars:- user: "msiyuetian"tasks:- name: create useruser: name="{{ user }}"
- include: handlers.yml # 已经用下面的import_playbook代替
- import_playbook: handlers.yml
# tail test.yaml playbook1.yml playbook2.yml
==> test.yaml <==
- import_playbook: playbook1.yml
- import_playbook: playbook2.yml==> playbook1.yml <==
- hosts: redis02remote_user: rootgather_facts: truevars:- var1: "test.yaml"tasks:- name: copy filecopy: src=./{{ var1 }} dest=/tmp/==> playbook2.yml <==
- hosts: redis03remote_user: rootgather_facts: truevars:- var1: "test.yaml"tasks:- name: copy filecopy: src=./{{ var1 }} dest=/tmp/
示例7:pause暂停
在playbook执行的过程中暂停一定时间或者提示用户进行某些操作
常用参数:
minutes:暂停多少分钟
seconds:暂停多少秒
prompt:打印一串信息提示用户操作
[root@ansible ansible]# cat wait.yml
---
- name: waithosts: web1tasks:- name: wait on user inputpause: prompt="Warning! Detected slight issue. ENTER to continue CTRL-C a to quit" - name: timed waitpause: seconds=30
Ansible变量Variables(扩展)
类型:
内建变量
自定义变量
变量调用:
{{ var_name }}
内建变量
由facts组件提供,可以使用setup模块查询
[root@ansible ansible]# ansible web1 -m setup
自定义变量
1.用命令行传递参数
为了使Playbook更灵活、通用性更强,允许用户在执行的时候传入变量的值,这个时候就需要用到"额外变量"。
定义命令行变量
在release.yml文件里,hosts和user都定义为变量,需要从命令行传递变量值。
—
- hosts: ‘{{ hosts }}’
remote_user: ‘{{ user }}’
tasks:
- …
使用命令行变量
在命令行里面传值的方法:
# ansible-playbook release.yml --extra-vars "hosts=web user=root"
还可以用json格式传递参数:
# ansible-playbook release.yml --extra-vars "{'hosts':'vm-rhel7-1', 'user':'root'}"
还可以将参数放在文件里面:
# ansible-playbook release.yml --extra-vars "@vars.json"
2.在hosts Inventory中为每个主机定义专用变量值
向不同的主机传递不同的变量:
IP/HOSTNAME variable_name=value
向组内的所有主机传递相同的变量:
[groupname:vars]
variable_name=value
3.在playbook中定义
vars:
- var_name: value
- var_name: value
通过vars_files关键字引入变量文件:
- hosts: all
remote_user: root
vars:
favcolor: blue
vars_files:
- /vars/external_vars.yml
- /vars/nginx_vars.yml
示例文件:
# vim /vars/nginx_vars.yml
http_port: 80
server_name: localhost
cert_file: /etc/nginx/ssl/nginx.crt
key_file: /etc/nginx/ssh/nginx.key
conf_file: /etc/nginx/conf/default.conf
注意:变量文件不一定以.yml结尾,变量冒号后面必须有空格
4.Inventory使用参数:
用于定义ansible远程连接目标主机时使用的属性,而非传递给playbook的变量;
ansible_ssh_host
ansible_ssh_port
ansible_ssh_user
ansible_ssh_pass
ansible_sudo_pass
…
5.在角色调用时传递
roles:
- { role: ROLE_NAME, var: value, …}
6.set_fact自定义facts变量:
set_fact模块可以自定义facts,这些自定义的facts可以通过template或者变量的方式在playbook中使用。如果你想要获取一个进程使用的内存的百分比,则必须通过set_fact来进行计算之后得出其值,并将其值在playbook中引用。
下面是一个配置mysql innodb buffer size的示例:
- name: Configure MySQLhosts: mysqlserverstasks: - name: install MySqlyum: name=mysql-server state=installed- name: Calculate InnoDB buffer pool sizeset_fact: innodb_buffer_pool_size_mb="{{ ansible_memtotal_mb / 2 }}"- name: Configure MySQL template: src=templates/my.cnf dest=/etc/my.cnf owner=root group=root mode=0644 notify: restart mysql - name: Start MySQL service: name=mysqld state=started enabled=yes handlers: - name: restart mysql service: name=mysqld state=restarted
my.cnf的配置示例:
# {{ ansible_managed }}
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted
security risks
symbolic-links=0# Configure the buffer pool
innodb_buffer_pool_size = {{ innodb_buffer_pool_size_mb|int }}M
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
所有变量都可以在playbook或者jinja2模板中通过{{ varname }}中使用。另外,当变量和jinja2的管道配合起来的时候能提供各种灵活的条件判断和变量处理。具体看下边两个例子。
如果第一个任务执行失败了才会执行第二个任务,可以这么写:
[root@ansible ansible]# cat wait.yml
---
- name: testhosts: web1tasks:- shell: /usr/bin/lsregister: resultignore_errors: True- debug: msg="it failed"when: result|failed
变量的优先级
• -e 命令行指定的最高
• inventory文件定义的变量次之,其实inventory文件也分全局,group级别的和hosts级别的变量定义
• fact变量次之
• 角色的default变量优先级最低
Ansible role
在ansible中,roles是playbooks的一部分。
playbooks模块化之后,成为roles的组织结构,易读,代码可重用,层次清晰。
以特定的层级目录结构进行组织的tasks、variables、handlers、templates、files等;
role_name/
files/:存储由copy或script等模块调用的文件;
tasks/:
此目录中至少应该有一个名为main.yml的文件,用于定义各task;其它的文件需要由main.yml进行“包含”调用;
handlers/:
此目录中至少应该有一个名为main.yml的文件,用于定义各handler;其它的文件需要由main.yml进行“包含”调用;
vars/:
此目录中至少应该有一个名为main.yml的文件,用于定义各variable;其它的文件需要由main.yml进行“包含”调用;
templates/:
存储由template模块调用的模板文本;
meta/:
此目录中至少应该有一个名为main.yml的文件,定义当前角色的特殊设定及其依赖关系;其它的文件需要由main.yml进行“包含”调用;
default/:
此目录中至少应该有一个名为main.yml的文件,用于设定默认变量;
在playbook中调用角色的方法:
- hosts: HOSTSremote_user: USERNAMEroles:- ROLE1- ROLE2- { role: ROLE3, VARIABLE: VALUE, ...}- { role: ROLE4, when: CONDITION }
role目录结构:
tasks:
handlers:
vars:
jinja template:
ansible-playbook
Ansible Templates:模板
Jinja2 is a template engine written in pure Python. It provides a Django inspired non-XML syntax but supports inline expressions and an optional sandboxed environment.
最简示例:
[root@ansible ansible]# cat wait.yml
- name: userhosts: web1user: rootvars:- user: "wing"- say: "wingfile"tasks:- name: task {{ user }}template: src=/root/testfile dest=/root/{{ say }}[root@ansible ansible]# cat /root/testfile
hello
i love {{ user }}[root@ansible ansible]# ansible-playbook wait.yml
模板文件语法:
字面量:
字符串:使用单引号或双引号;
数字:整数、浮点数;
列表:[item1, item2, …]
元组:(item1, item2, …)
字典:{key1:value1, key2:value2, …}
布尔型:true/false
算术运算:
+, -, , /, //, %, *
比较操作:
==, !=, >, <, >=, <=
逻辑运算:
and, or, not
执行模板文件中的脚本,并生成结果数据流,需要使用template模块;
在实际应用中,我们的配置文件有些地方可能会根据远程主机的配置的不同而有稍许的不同,template可以使用变量来接收远程主机上setup收集到的facts信息,针对不同配置的主机,定制配置文件。用法大致与copy模块相同。
常用参数:
backup:如果原目标文件存在,则先备份目标文件
dest:目标文件路径
force:是否强制覆盖,默认为yes
group:目标文件属组
mode:目标文件的权限
owner:目标文件属主
src:源模板文件路径
validate:在复制之前通过命令验证目标文件,如果验证通过则复制
注意:此模板不能在命令行使用,而只能用于playbook;
示例:
- hosts: ngxsrvsremote_user: roottasks:- name: install nginx packageyum: name=nginx state=latest- name: install conf filetemplate: src=/root/nginx.conf.j2 dest=/etc/nginx/nginx.conftags: ngxconfnotify: reload nginx service- name: start nginx serviceservice: name=nginx state=started enabled=true
handlers:- name: reload nginx serviceshell: /usr/sbin/nginx -s reload
条件测试:
when语句:在tasks中使用,Jinja2的语法格式;
- hosts: allremote_user: roottasks:- name: install nginx packageyum: name=nginx state=latest- name: start nginx service on CentOS6shell: service nginx startwhen: ansible_distribution == "CentOS" and ansible_distribution_major_version == "6"- name: start nginx serviceshell: systemctl start nginx.servicewhen: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
循环:
当有需要重复性执行的任务时,可以使用迭代机制。
其使用格式为:
将需要迭代的内容定义为item变量引用,并通过with_items语句来指明迭代的元素列表即可。
注意:变量名"item"是固定的
元素列表有两种:字符串和字典
基于字符串列表给出元素示例:
- hosts: websrvsremote_user: roottasks:- name: install packagesyum: name={{ item }} state=latestwith_items:- httpd- php- php-mysql- php-mbstring- php-gd
基于字典列表给出元素示例:
- hosts: allremote_user: roottasks:- name: create groupsgroup: name={{ item }} state=presentwith_items:- groupx1- groupx2- groupx3- name: create usersuser: name={{ item.name }} group={{ item.group }} state=presentwith_items:- {name: 'userx1', group: 'groupx1'}- {name: 'userx2', group: 'groupx2'}- {name: 'userx3', group: 'groupx3'}
文件通配符循环
用with_fileglob可以获取本地文件列表。示例如下:
[root@ansible ansible]# cat filelist.yml
---
- name: testhosts: web1tasks:- copy: src={{ item }} dest=/tmp/ owner=root mode=600with_fileglob:- /etc/yum.repos.d/*
官方简单示例:
- template: src=/mytemplates/foo.j2 dest=/etc/file.conf owner=bin group=wheel mode=0644
- template: src=/mytemplates/foo.j2 dest=/etc/file.conf owner=bin group=wheel mode=“u=rw,g=r,o=r”
- template: src=/mine/sudoers dest=/etc/sudoers validate='visudo -cf %s’named.conf
配置文件的jinja2模板示例:
options {
listen-on port 53 {
127.0.0.1;
{% for ip in ansible_all_ipv4_addresses %}
{{ ip }};
{% endfor %}
};
listen-on-v6 port 53 { ::1; };
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
memstatistics-file "/var/named/data/named_mem_stats.txt";
};
zone "." IN {
type hint;
file "named.ca";
};
include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
{# Variables for zone config #}
{% if 'authorativenames' in group_names %}
{% set zone_type = 'master' %}
{% set zone_dir = 'data' %}
{% else %}
{% set zone_type = 'slave' %}
{% set zone_dir = 'slaves' %}
{% endif %}
zone "internal.example.com" IN {
type {{ zone_type }};
file "{{ zone_dir }}/internal.example.com";
{% if 'authorativenames' not in group_names %}
masters { 192.168.2.2; };
{% endif %}
};
注:
group_names 是魔法变量,表示当前host所在的group的组名列表,包括其父组
要使这个模板文件生效,需要建立一个authorative nameserver,在设备清单文件中创建一个叫authorative nameserver的组,并添加一些主机(远程受管主机)
playbook的引用该模板配置文件的方法示例:
- name: Setup BINDhost: allnamestasks:- name: configure BINDtemplate: src=templates/named.conf.j2 dest=/etc/named.conf owner=root group=named mode=0640
nginx.conf.j2
[root@ansible ansible]# cat roles/nginx/templates/nginx.conf.j2
#user nobody;
worker_processes {{ ansible_processor_cores }};#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;#pid logs/nginx.pid;events {worker_connections {{ worker_connections }};
}http {include mime.types;default_type application/octet-stream;#log_format main '$remote_addr - $remote_user [$time_local] "$request" '# '$status $body_bytes_sent "$http_referer" '# '"$http_user_agent" "$http_x_forwarded_for"';#access_log logs/access.log main;sendfile on;#tcp_nopush on;#keepalive_timeout 0;keepalive_timeout 65;#gzip on;server {listen 80;server_name localhost;#charset koi8-r;#access_log logs/host.access.log main;location / {root html;index index.html index.htm;}#error_page 404 /404.html;# redirect server error pages to the static page /50x.html#error_page 500 502 503 504 /50x.html;location = /50x.html {root html;}# proxy the PHP scripts to Apache listening on 127.0.0.1:80##location ~ \.php$ {# proxy_pass http://127.0.0.1;#}# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000##location ~ \.php$ {# root html;# fastcgi_pass 127.0.0.1:9000;# fastcgi_index index.php;# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;# include fastcgi_params;#}# deny access to .htaccess files, if Apache's document root# concurs with nginx's one##location ~ /\.ht {# deny all;#}}# another virtual host using mix of IP-, name-, and port-based configuration##server {# listen 8000;# listen somename:8080;# server_name somename alias another.alias;# location / {# root html;# index index.html index.htm;# }#}# HTTPS server##server {# listen 443 ssl;# server_name localhost;# ssl_certificate cert.pem;# ssl_certificate_key cert.key;# ssl_session_cache shared:SSL:1m;# ssl_session_timeout 5m;# ssl_ciphers HIGH:!aNULL:!MD5;# ssl_prefer_server_ciphers on;# location / {# root html;# index index.html index.htm;# }#}
}
常用模块
-
setup: 查看远程主机的基本信息
-
ping: 测试远程主机的运行状态
-
file: 设置文件属性
相关选项如下:
force:需要在两种情况下强制创建软链接,一种是源文件不存在,但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no
group:定义文件/目录的属组
mode:定义文件/目录的权限
owner:定义文件/目录的属主
path:必选项,定义文件/目录的路径
recurse:递归设置文件的属性,只对目录有效,有两个选项:yes|no
src:被链接的源文件路径,只应用于state=link的情况
dest:被链接到的路径,只应用于state=link的情况
state:
directory:如果目录不存在,就创建目录
file:即使文件不存在,也不会被创建
link:创建软链接
hard:创建硬链接
touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
absent:删除目录、文件或者取消链接文件
使用示例:# ansible test -m file -a "src=/etc/fstab dest=/tmp/fstab state=link" # ansible test -m file -a "path=/tmp/fstab state=absent" # ansible test -m file -a "path=/tmp/test state=touch"
-
copy: 把主控端的文件复制到远程主机
把ansible机器上的文件拷贝到远程被控之器上
把被控机器上的文件拷贝到同一台被控机器上
相关选项如下:
backup:在覆盖之前,将源文件备份,备份文件包含时间信息。有两个选项:yes|no
content:用于替代“src”,可以直接设定指定文件的值
dest:必选项。要将源文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录
directory_mode:递归设定目录的权限,默认为系统默认权限
force:如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes
others:所有的file模块里的选项都可以在这里使用
src:被复制到远程主机的本地文件,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用“/”来结尾,则只复制目录里的内容,如果没有使用“/”来结尾,则包含目录在内的整个内容全部复制,类似于rsync
示例如下:
ansible test -m copy -a “src=/srv/myfiles/foo.conf dest=/etc/foo.conf owner=foo group=foo mode=0644”
ansible test -m copy -a “src=/mine/ntp.conf dest=/etc/ntp.conf owner=root group=root mode=644 backup=yes”
5.service模块:用于管理服务
该模块包含如下选项:
arguments:给命令行提供一些选项
enabled:是否开机启动 yes|no
name:必选项,服务名称
pattern:定义一个模式,如果通过status指令来查看服务的状态时,没有响应,就会通过ps指令在进程中根据该模式进行查找,如果匹配到,则认为该服务依然在运行
runlevel:运行级别
sleep:如果执行了restarted,在则stop和start之间沉睡几秒钟
state:对当前服务执行启动,停止、重启、重新加载等操作(started,stopped,restarted,reloaded)
使用示例:
ansible test -m service -a “name=httpd state=started enabled=yes”
asnible test -m service -a “name=foo pattern=/usr/bin/foo state=started”
ansible test -m service -a “name=network state=restarted args=eth0”
6.cron模块:用于管理计划任务
包含如下选项:
backup:对远程主机上的原任务计划内容修改之前做备份
cron_file:如果指定该选项,则用该文件替换远程主机上的cron.d目录下的用户的任务计划
day:日(1-31,,/2,……)
hour:小时(0-23,,/2,……)
minute:分钟(0-59,,/2,……)
month:月(1-12,,/2,……)
weekday:周(0-7,*,……)
job:要执行的任务,依赖于state=present
name:该任务的描述
special_time:指定什么时候执行,参数:reboot,yearly,annually,monthly,weekly,daily,hourly
state:确认该任务计划是创建还是删除
user:以哪个用户的身份执行
示例:
ansible test -m cron -a ‘name=“a job for reboot” special_time=reboot job=“/some/job.sh”’
ansible test -m cron -a 'name=“yum autoupdate” weekday=“2” minute=0 hour=12 user="root
ansible test -m cron -a ‘backup=“True” name=“test” minute=“0” hour=“5,2” job=“ls -alh > /dev/null”’
ansilbe test -m cron -a ‘cron_file=ansible_yum-autoupdate state=absent’
7.yum模块:使用yum包管理器来管理软件包
其选项有:
config_file:yum的配置文件
disable_gpg_check:关闭gpg_check
disablerepo:不启用某个源
enablerepo:启用某个源
name:要进行操作的软件包的名字,也可以传递一个url或者一个本地的rpm包的路径
state:状态(present,absent,latest)
示例如下:
ansible test -m yum -a ‘name=httpd state=latest’
ansible test -m yum -a ‘name=“@Development tools” state=present’
ansible test -m yum -a ‘name=http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present’
8.user模块与group模块
user模块是请求的是useradd, userdel, usermod三个指令,goup模块请求的是groupadd, groupdel, groupmod 三个指令。
1、user模块
home:指定用户的家目录,需要与createhome配合使用
groups:指定用户的属组
uid:指定用的uid
password:指定用户的密码
name:指定用户名
createhome:是否创建家目录 yes|no
system:是否为系统用户
remove:当state=absent时,remove=yes则表示连同家目录一起删除,等价于userdel -r
state:是创建还是删除
shell:指定用户的shell环境
使用示例:
user: name=johnd comment=“John Doe” uid=1040 group=admin
user: name=james shell=/bin/bash groups=admins,developers append=yes user: name=johnd state=absent remove=yes
user: name=james18 shell=/bin/zsh groups=developers expires=1422403387
user: name=test generate_ssh_key=yes ssh_key_bits=2048 ssh_key_file=.ssh/id_rsa #生成密钥时,只会生成公钥文件和私钥文件,和直接使用ssh-keygen指令效果相同,不会生成authorized_keys文件。注:指定password参数时,不能使用明文密码,因为后面这一串密码会被直接传送到被管理主机的/etc/shadow文件中,所以需要先将密码字符串进行加密处理。然后将得到的字符串放到password中即可。
echo “123456” | openssl passwd -1 -salt $(< /dev/urandom tr -dc ‘[:alnum:]’ | head -c 32) -stdin
$1 4 P 4 P l F u E 4P4PlFuE 4P4PlFuEur9ObJiT5iHNrb9QnjaIB0
#使用上面的密码创建用户
ansible all -m user -a 'name=foo password=“$1 4 P 4 P l F u E 4P4PlFuE 4P4PlFuEur9ObJiT5iHNrb9QnjaIB0”'不同的发行版默认使用的加密方式可能会有区别,具体可以查看/etc/login.defs文件确认,centos 6.5版本使用的是SHA512加密算法。
2、group示例
ansible all -m group -a ‘name=somegroup state=present’
- shell: shell命令
ansible默认使用的模块是command,支持多数shell命令,但不支持shell变量及管道,如果要使用,用shell模块
主配置文件(扩展)
注意:实际上平时没有特殊情况主配置文件不需要修改,ansible默认配置已经很好了
主配置文件位置:
配置文件存在不同的位置,但只有一个可用
在下列列表中,ansible从上往下依次检查,检查到哪个可用就用哪个
• ANSIBLE_CFG 环境变量,可以定义配置文件的位置
• ansible.cfg 存在于当前工作目录
• ansible.cfg 存在与当前用户家目录
• /etc/ansible/ansible.cfg
默认位置: /etc/ansible/ansible.cfg
[root@vm20 share]# ansible --version
ansible 2.3.2.0
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides
python version = 2.7.5 (default, Aug 4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]
wing测试:配置文件不存在也可以,会使用默认配置
ansible.cfg 配置项说明
[defaults]
配置 | 说明 |
---|---|
#inventory = /etc/ansible/hosts | 指定主机清单文件 |
#library = /usr/share/my_modules/ | 指定模块地址 |
#remote_tmp = $HOME/.ansible/tmp | 指定远程执行的路径 |
#local_tmp = $HOME/.ansible/tmp | ansible 管理节点得执行路径 |
#forks = 5 | 置默认情况下Ansible最多能有多少个进程同时工作,默认设置最多5个进程并行处理 |
#poll_interval = 15 | 轮询间隔 |
#sudo_user = root | sudo默认用户 |
#ask_sudo_pass = True | 是否需要用户输入sudo密码 |
#ask_pass = True | 是否需要用户输入连接密码 |
#transport = smart | |
#remote_port = 22 | 远程链接的端口 |
#module_lang = C | 这是默认模块和系统之间通信的计算机语言,默认为’C’语言. |
#module_set_locale = True | |
#gathering = implicit | |
#gather_subset = all | 定义获取fact的子集,默认全部 |
#roles_path = /etc/ansible/roles | 角色存储路径 |
#host_key_checking = False | 跳过ssh 首次连接提示验证部分,False表示跳过。 |
#stdout_callback = skippy | |
#callback_whitelist = timer, mail | |
#task_includes_static = True | |
#handler_includes_static = True | |
#sudo_exe = sudo | sudo的执行文件名 |
#sudo_flags = -H -S -n | sudo的参数 |
#timeout = 10 | 连接超时时间 |
#remote_user = root | 指定默认的远程连接用户 |
#log_path = /var/log/ansible.log | 指定日志文件 |
#module_name = command | 指定ansible默认的执行模块 |
#executable = /bin/sh | 用于执行脚本得解释器 |
#hash_behaviour = replace | 如果变量重叠,优先级更高的一个是替换优先级低得还是合并在一起,默认为替换 |
#private_role_vars = yes | 默认情况下,角色中的变量将在全局变量范围中可见。 为了防止这种情况,可以启用以下选项,只有tasks的任务和handlers得任务可以看到角色变量。 |
#jinja2_extensions = jinja2.ext.do,jinja2.ext.i18n | jinja2的扩展应用 |
#private_key_file = /path/to/file | 指定私钥文件路径 |
#vault_password_file = /path/to/vault_password_file | 指定vault密码文件路径 |
#ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host} | 定义一个Jinja2变量,可以插入到Ansible配置模版系统生成的文件中 |
#display_skipped_hosts = True | 如果设置为False,ansible 将不会显示任何跳过任务的状态.默认选项是显示跳过任务的状态 |
#display_args_to_stdout = False | |
#error_on_undefined_vars = False | 如果所引用的变量名称错误的话, 是否让ansible在执行步骤上失败 |
#system_warnings = True | |
#deprecation_warnings = True | |
#command_warnings = False | |
#action_plugins = /usr/share/ansible/plugins/action | action模块的存放路径 |
#callback_plugins = /usr/share/ansible/plugins/callback | callback模块的存放路径 |
#connection_plugins = /usr/share/ansible/plugins/connection | connection模块的存放路径 |
#lookup_plugins = /usr/share/ansible/plugins/lookup | lookup模块的存放路径 |
#vars_plugins = /usr/share/ansible/plugins/vars | vars模块的存放路径 |
#test_plugins = /usr/share/ansible/plugins/test | test模块的存放路径 |
#strategy_plugins = /usr/share/ansible/plugins/strategy | strategy模块的存放路径 |
#bin_ansible_callbacks = False | |
#nocows = 1 | |
#cow_selection = default | |
#cow_selection = random | |
#cow_whitelist=bud-frogs,bunny,cheese,daemon,default,dragon,elephant-in-snake,elephant,eyes,\ | |
#nocolor = 1 | 默认ansible会为输出结果加上颜色,用来更好的区分状态信息和失败信息.如果你想关闭这一功能,可以把’nocolor’设置为‘1’: |
#fact_caching = memory | fact值默认存储在内存中,可以设置存储在redis中,用于持久化存储 |
#retry_files_enabled = False | 当playbook失败得情况下,一个重试文件将会创建,默认为开启此功能 |
#retry_files_save_path = ~/.ansible-retry | 重试文件的路径,默认为当前目录下.ansible-retry |
#squash_actions = apk,apt,dnf,package,pacman,pkgng,yum,zypper | Ansible可以优化在循环时使用列表参数调用模块的操作。 而不是每个with_项调用模块一次,该模块会一次调用所有项目一次。该参数记录哪些action是这样操作得。 |
#no_log = False | 任务数据的日志记录,默认情况下关闭 |
#no_target_syslog = False | 防止任务的日志记录,但只在目标上,数据仍然记录在主/控制器上 |
#allow_world_readable_tmpfiles = False | |
#var_compression_level = 9 | 控制发送到工作进程的变量的压缩级别。 默认值为0,不使用压缩。 此值必须是从0到9的整数。 |
#module_compression = ‘ZIP_DEFLATED’ | 指定压缩方法,默认使用zlib压缩,可以通过ansible_module_compression来为每个主机设置 |
#max_diff_size = 1048576 | 控制–diff文件上的截止点(以字节为单位),设置0则为无限制(可能对内存有影响) |
[privilege_escalation]
#become=True
#become_method=sudo
#become_user=root
#become_ask_pass=False
[paramiko_connection]
#record_host_keys=False
#pty=False
[ssh_connection]
配置 | 说明 |
---|---|
#ssh_args = -o ControlMaster=auto -o ControlPersist=60s | ssh连接时得参数 |
#control_path = %(directory)s/ansible-ssh-%%h-%%p-%%r | 保存ControlPath套接字的位置 |
#pipelining = False | SSH pipelining 是一个加速 Ansible 执行速度的简单方法。ssh pipelining 默认是关闭,之所以默认关闭是为了兼容不同的 sudo 配置,主要是 requiretty 选项。如果不使用 sudo,建议开启。打开此选项可以减少 ansible 执行没有传输时 ssh 在被控机器上执行任务的连接数。不过,如果使用 sudo,必须关闭 requiretty 选项。 |
#scp_if_ssh = True | 该项为True时,如果连接类型是ssh,使ansible使用scp,为False是,ansible使用sftp。默认为sftp |
#sftp_batch_mode = False | 该项为False时,sftp不会使用批处理模式传输文件。 这可能导致一些类型的文件传输失败而不可捕获,但应该只有在您的sftp版本在批处理模式上有问题时才应禁用 |
[accelerate]
加速配置
#accelerate_port = 5099
#accelerate_timeout = 30
#accelerate_connect_timeout = 5.0
#accelerate_daemon_timeout = 30
#accelerate_multi_key = yes
[selinux]
配置 | 说明 |
---|---|
#special_context_filesystems=nfs,vboxsf,fuse,ramfs | 文件系统在处理安全上下文时需要特殊处理,定义复制现有上下文的文件系统 |
#libvirt_lxc_noseclabel = yes | 将此设置为yes,以允许libvirt_lxc连接在没有SELinux的情况下工作。 |
[colors]
定义输出颜色
#highlight = white
#verbose = blue
#warn = bright purple
#error = red
#debug = dark gray
#deprecate = purple
#skip = cyan
#unreachable = red
#ok = green
#changed = yellow
#diff_add = green
#diff_remove = red
#diff_lines = cyan
问题
问题1:
如果ssh的known_hosts文件被删除,远程登陆的时候会出现提示yes/no,ansible不能自动处理则报错如下:
[root@ansible ~]# ansible web2 -a ‘uptime’
web2 | FAILED | rc=-1 >>
Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host’s fingerprint to your known_hosts file to manage this host.
解决:扫描远程主机信息添加到known_hosts文件
| 该项为True时,如果连接类型是ssh,使ansible使用scp,为False是,ansible使用sftp。默认为sftp |
| #sftp_batch_mode = False | 该项为False时,sftp不会使用批处理模式传输文件。 这可能导致一些类型的文件传输失败而不可捕获,但应该只有在您的sftp版本在批处理模式上有问题时才应禁用 |
[accelerate]
加速配置
#accelerate_port = 5099
#accelerate_timeout = 30
#accelerate_connect_timeout = 5.0
#accelerate_daemon_timeout = 30
#accelerate_multi_key = yes
[selinux]
配置 | 说明 |
---|---|
#special_context_filesystems=nfs,vboxsf,fuse,ramfs | 文件系统在处理安全上下文时需要特殊处理,定义复制现有上下文的文件系统 |
#libvirt_lxc_noseclabel = yes | 将此设置为yes,以允许libvirt_lxc连接在没有SELinux的情况下工作。 |
[colors]
定义输出颜色
#highlight = white
#verbose = blue
#warn = bright purple
#error = red
#debug = dark gray
#deprecate = purple
#skip = cyan
#unreachable = red
#ok = green
#changed = yellow
#diff_add = green
#diff_remove = red
#diff_lines = cyan
问题
问题1:
如果ssh的known_hosts文件被删除,远程登陆的时候会出现提示yes/no,ansible不能自动处理则报错如下:
[root@ansible ~]# ansible web2 -a ‘uptime’
web2 | FAILED | rc=-1 >>
Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host’s fingerprint to your known_hosts file to manage this host.
解决:扫描远程主机信息添加到known_hosts文件
[root@ansible ~]# ssh-keyscan web2 >> /root/.ssh/known_hosts
相关文章:
Day 44 Ansible自动化运维
Ansible自动化运维 几种常用运维工具比较 Puppet —基于 Ruby 开发,采用 C/S 架构,扩展性强,基于 SSL,远程命令执行相对较弱ruby SaltStack —基于 Python 开发,采用 C/S 架构,相对 puppet 更轻量级,配置语法使用 YAML,使得配置脚本更简单 Ansible —基于 …...
Excel/WPS《超级处理器》功能介绍与安装下载
超级处理器是基于Excel或WPS开发的一款插件,拥有近300个功能,非常简单高效的处理表格数据,安装即可使用。 点击此处:超i处理器安装下载 Excel菜单,显示如下图所示: WPS菜单显示,如下图所示&am…...
U-Net for Image Segmentation
1.Unet for Image Segmentation 笔记来源:使用Pytorch搭建U-Net网络并基于DRIVE数据集训练(语义分割) 1.1 DoubleConv (Conv2dBatchNorm2dReLU) import torch import torch.nn as nn import torch.nn.functional as F# nn.Sequential 按照类定义的顺序去执行模型&…...
POI导入带有合并单元格的excel,demo实例,直接可以运行
直接可以运行 import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.s…...
【C语言】解决C语言报错:Use-After-Free
文章目录 简介什么是Use-After-FreeUse-After-Free的常见原因如何检测和调试Use-After-Free解决Use-After-Free的最佳实践详细实例解析示例1:释放内存后未将指针置为NULL示例2:多次释放同一指针示例3:全局或静态指针被释放后继续使用示例4&am…...
C语言经典例题-19
1.字符串左旋结果 题目内容:写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。 例:给定s1 AABCD和s2 BCDAA,返回1 给定s1 abcd和s2 ACBD,返回0 AABCD左旋一个字符得到ABCDA AABCD左旋两个字符得到BCDAA AABCD右旋一…...
AlmaLinux 更换CN镜像地址
官方镜像列表 官方列表:https://mirrors.almalinux.org/CN 开头的站点,不同区域查询即可 一键更改镜像地址脚本 以下是更改从默认更改到阿里云地址 cat <<EOF>>/AlmaLinux_Update_repo.sh #!/bin/bash # -*- coding: utf-8 -*- # Author:…...
【笔记】【矩阵的二分】668. 乘法表中第k小的数
力扣链接:题目 参考地址:参考 思路:二分查找 把矩阵想象成一维的已排好序的数组,用二分法找第k小的数字。 假设m行n列,则对应一维下标范围是从1到mn,初始: l1; rmn; mid(lr)/2 设mid在第i行&a…...
红米手机RedNot11无法使用谷歌框架,打开游戏闪退的问题,红米手机如何开启谷歌框架
红米手机RedNot11无法使用谷歌框架,打开游戏闪退的问题, 1.问题描述2.问题原因3.解决方案3.1配置谷歌框架:3.1软件优化 4.附图 1.问题描述 红米手机打开安卓APP没有广告,直接闪退,无法使用谷歌框架 异常关键词中包含&…...
emqx5.6.1 数据、配置备份与迁移
EMQX 支持导入和导出的数据包括: EMQX 配置重写的内容: 认证与授权配置规则、连接器与 Sink/Source监听器、网关配置其他 EMQX 配置内置数据库 (Mnesia) 的数据 Dashboard 用户和 REST API 密钥客户端认证凭证(内置数据库密码认证、增强认证…...
VUE3脚手架工具cli配置搭建及创建VUE工程
1、VUE的脚手架工具(CLI) 开发大型vue的时候,不能通过html编写一个大型的项目,这个时候需要用到vue的脚手架工具 通过vue的脚手架,可以快速的生成vue工程 1.1、安装nodejs和npm 【下载nodejs】 https://nodejs.org/en 【安装…...
前端开发之DNS协议
上一篇👉: 前端开发之计算机网络模型认识 文章目录 DNS协议详介绍1. DNS 协议概述2. DNS协议与TCP/UDP3. DNS查询过程4. 迭代与递归查询5. DNS记录与报文结构资源记录类型对比 6. 总结 DNS协议详介绍 1. DNS 协议概述 DNS(Domain Name System…...
如何在 Tailwind CSS 中实现居中对齐
如何在 Tailwind CSS 中实现居中对齐: 1. 使用 text-center 类(针对行内元素或行内块元素) 这个类用于将文本或行内块元素水平居中对齐。 <div class"text-center"><span>这是一个行内元素</span> </div&g…...
【iOS】编译二进制文件说明
编译二进制文件说明 如何生成文件路径文件说明第一部分:.o文件第二部分:link第三部分:Segment第四部分:Symbol 如何生成 使用Xcode进行编译 ,会生成二进制相关文件,可以更详细看产物的布局 项目Target -&…...
红队内网攻防渗透:内网渗透之内网对抗:隧道技术篇防火墙组策略FRPNPSChiselSocks代理端口映射C2上线
红队内网攻防渗透 1. 内网隧道技术1.1 Frp内网穿透C2上线1.1.1 双网内网穿透C2上线1.1.1.1 服务端配置1.1.1.2 客户端配置1.1.2 内网穿透信息收集1.1.2.1、建立Socks节点(入站没限制采用)1.1.2.2 主动转发数据(出站没限制采用)1.2 Nps内网穿透工具1.2.1 NPS内网穿透C2上线1…...
qt+halcon实战
注意建QT工程项目用的是MSVC,如果选成MinGW,则会报错 INCLUDEPATH $$PWD/include INCLUDEPATH $$PWD/include/halconcppLIBS $$PWD/lib/x64-win64/halconcpp.lib LIBS $$PWD/lib/x64-win64/halcon.lib#include "halconcpp/HalconCpp.h" #include &quo…...
Java_POJO
概念 POJO即简单的Java对象,区别于JavaBean JavaBean:特殊的Java类,容易被重用或插入到其他应用程序中去,通过封装属性和方法成为具有某种功能或者处理某个业务的对象 这个类必须有public的无参构造器所有属性都是private的所有属…...
24年安克创新社招入职自适应能力cata测评真题分享北森测评高频题库
第一部分:安克创新自适应能力cata测评 感谢您关注安克创新社会招聘,期待与您一起弘扬中国智造之美。 为对您做出全面的评估,现诚邀您参加我们的在线测评。 测评名称:社招-安克创新自适应能力cata测评 第二部分:安克…...
OpenCV中的圆形标靶检测——findCirclesGrid()(三)
前面说到cv::findCirclesGrid2()内部先使用SimpleBlobDetector进行圆斑检测,然后使用CirclesGridClusterFinder算法类执行基于层次聚类的标靶检测。如下图所示,由于噪声的影响,SimpleBlobDetector检出的标靶可能包含噪声。 而CirclesGridClusterFinder算法类会执行基…...
C++拷贝构造函数、运算符重载函数、赋值运算符重载函数、前置++和后置++重载等的介绍
文章目录 前言一、拷贝构造函数1. 概念2. 特征3. 编译器生成默认拷贝构造函数4. 拷贝构造函数典型使用场景 二、运算符重载函数三、赋值运算符重载函数1. 赋值运算符重载格式2. 赋值运算符只能重载成类的成员函数不能重载成全局函数3.编译器生成一个默认赋值运算符重载4. 运算符…...
视频智能分析平台智能边缘分析一体机视频监控业务平台区域人数不足检测算法
智能边缘分析一体机区域人数不足检测算法是一种集成了先进图像处理、目标检测、跟踪和计数等功能的算法,专门用于实时监测和统计指定区域内的人数,并在人数不足时发出警报。以下是对该算法的详细介绍: 一、算法概述 智能边缘分析一体机区域…...
揭秘MMAdapt:如何利用AI跨领域战胜新兴健康谣言?
MMAdapt: A Knowledge-Guided Multi-Source Multi-Class Domain Adaptive Framework for Early Health Misinformation Detection 论文地址: MMAdapt: A Knowledge-guided Multi-source Multi-class Domain Adaptive Framework for Early Health Misinformation Detection …...
【云手机】数据安全如何保障?
安全办公,信息安全,这是企业使用云手机的初衷和目的,云手机在数据保密,远程办公等功能上有巨大的优势,也为企业提供了支持 首先就是云手机能够实现数据的集中管理和加密存储。所有办公相关的数据都存储在云端的安全服务…...
【算法专题--链表】删除排序链表中的重复元素 -- 高频面试题(图文详解,小白一看就懂!!)
目录 一、前言 二、题目描述 三、解题方法 ⭐双指针 四、总结与提炼 五、共勉 一、前言 删除排序链表中的重复元素这道题,可以说是--链表专题--,最经典的一道题,也是在面试中频率最高的一道题目,通常在面试中࿰…...
【ajax基础01】ajax简介
目录 一:ajax简介 1 什么是ajax 二:ajax使用 1 如何使用ajax 2 axios使用(重点) 三:案例 四:如何赚钱 一:ajax简介 1 什么是ajax AJAX(Asynchronous JavaScript And XML &am…...
[数据集][目标检测]棉花叶子害虫检测数据集VOC+YOLO格式595张1类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):595 标注数量(xml文件个数):595 标注数量(txt文件个数):595 标注类别…...
Nominatim免费的地址解析,逆地址解析,OpenStreetMap开源地图数据【全网最全】
视频学习地址 国内的一些地址解析供应商的API都开始付费了,就想找个免费的地址解析和逆地址解析的应用,最终选择了Nominatim OpenStreetMap 文章目录 一、选型1-1、数据源1-2、地理编码引擎2-1、初尝Nominatim2-1-1、地址解析2-1-2、逆地址解析 2-2、OS…...
js 移除字符串中所有的a标签;js 移除字符串中所有的a标签,但是保留a标签包裹的部分
js 移除字符串中所有的a标签 要移除字符串中所有的 <a> 标签,可以使用正则表达式和 String.replace() 方法。以下是实现这一功能的示例代码: function removeATags(str) {return str.replace(/<a\b[^<]*(?:(?!<\/a>)<[^<]*)…...
深信服科技:2023网络安全深度洞察及2024年趋势研判报告
2023 年,生成式人工智能和各种大模型迅速应用在网络攻击与对抗中,带来了新型攻防场景和安全威胁。漏洞利用链组合攻击实现攻击效果加成,在国家级对抗中频繁使用。勒索团伙广泛利用多个信创系统漏洞,对企业数据安全与财产安全造成了…...
windows下mysql修改 my.ini的datadir后 `Access denied`
1. 背景 window安装mysql数据库时,不能指定数据文件存放位置(默认安装路径 "C:/ProgramData")。 只能通过修改mysql.ini来更改数据文件存放目录。 2. 问题: 修改mysql.ini后,mysql 出现 "Access denied for user ‘root‘@‘localhost‘ (using passwor…...
Java比较运算符
关系运算符和比较运算符适用于条件判断类型。 相当于布尔值,只有True和False两个 符号 说明ab,判断a的值是否等于b的值,条件成立为true,不成立为false ! a!b,判断a和b的值是否不相等,条件成立为true,不成立为false > …...
「网络原理」IP 协议
🎇个人主页:Ice_Sugar_7 🎇所属专栏:计网 🎇欢迎点赞收藏加关注哦! IP 协议 🍉报头结构🍉地址管理🍌动态分配 IP 地址🍌NAT 机制(网络地址映射&am…...
电商平台生活用品销售数据分析与应用
摘 要 在当前互联网飞速发展的时代,计算机应用给我们的工作生活带来了极大的便利。如今我们的生活离不开电商平台,其随之而来的是各种各样的销售数据与消费者信息,这些数据和信息的分析应用成为了当前互联网领域研究的重要部分。 本论文以基…...
FastAdmin数据库设计规范
FastAdmin数据库设计规范,官方文档上也有,仅仅是为了我自己做一次笔记增加记忆强度 表名和字段名全小写,只允许出现a-z和_这几种字符,且不能有拼音,只能为英文单词存储引擎统一使用innodb引擎字符集统一使用utf8mb4,排序规则使用…...
基于MATLAB仿真LFM线性调频信号
基于MATLAB仿真LFM线性调频信号 目录 前言 一、LFM信号简介 二、LFM信号基本原理 三、LFM信号仿真 四、代码 总结 前言 仿真中的接收信号,有时为了简单会直接用一个正弦波代替,但实际中接收到的信号极少是点频信号,一般都是PSK信号、OF…...
互联网的盈利模式
1. 广告收入 展示广告:通过在网站或应用上展示横幅广告、视频广告等,按点击次数(CPC)或展示次数(CPM)收费。搜索广告:通过搜索引擎上的关键词竞价广告,按点击次数收费。社交媒体广告…...
什么是距离选通型水下三维激光扫描仪?(下)
距离选通激光水下成像的发展 距离选通激光成像技术始于上世纪60年代,受制于高性能脉冲激光器和选通成像器件发展的制约,激光距离选通成像技术在随后的二十年发展缓慢,直到20世纪90年代,随着硬件技术的不断成熟,该技术…...
计算机网络(谢希仁第六版)| 课后习题与答案 | 物理层 | 题目知识点详细分析
计算机网络(谢希仁第六版)课后习题与答案 物理层 博客只对老师给的重点进行整理,完整的课后习题答案见Gitee下载:《计算机网络教程(第6版)(微课版)》习题答案 2-5 请画出数据流1 0 1…...
安卓安装linux + .net环境
安装Termux 到下面地址获取apk安装包 https://github.com/termux/termux-app 安装ssh ~ $ pkg install openssl ~ $ pkg install openssh查看用户名 ~ $ whoami ssh u0_a390修改当前用户密码 passwd 启动ssh sshd 安装 proot-distro pkg install proot-distro 列出能装的lin…...
ES6 新增Set 和 Map 两种数据结构
ES6 新增了 Set 和 Map 这两种数据结构,它们为 JavaScript 提供了更强大和灵活的数据处理能力。下面详细介绍一下 Set 和 Map 的特性和用法: Set Set 是一种类似于数组的数据结构,但是成员的值都是唯一的,没有重复的值。 特性&…...
【学一点儿前端】单页面点击前进或后退按钮导致的内存泄露问题(history.listen监听器清除)
今天测试分配了一个比较奇怪的问题,在单页面应用中,反复点击“上一步”和“下一步”按钮时,界面表现出逐渐变得卡顿。为分析这一问题,我用Chrome的性能监控工具进行了浏览器性能录制。结果显示,每次点击“上一步”按钮…...
vue跳转页面 如果登录了直接跳转 没有登录登录完以后直接跳转,使用vuex管理登录状态
在Vue.js中,如果你需要在用户登录后重定向到他们原本想要访问的页面,你可以使用Vue Router的beforeEach守卫来实现这个功能。以下是实现这一需求的步骤: 存储目标路由:在用户被重定向到登录页面之前,存储他们想要访问的…...
渗透测试-若依框架的杀猪交易所系统管理后台
前言 这次是带着摸鱼的情况下简单的写一篇文章,由于我喜欢探究黑灰产业,所以偶尔机遇下找到了一个加密H币的交易所S猪盘,我记得印象是上年的时候就打过这一个同样的站,然后我是通过指纹查找其它的一些站,那个站已经关…...
【免费】中国电子学会2024年03月份青少年软件编程Python等级考试试卷一级真题(含答案)
2024-03 Python一级真题 分数:100 题数:37 测试时长:60min 一、单选题(共25题,共50分) 1. 下列哪个命令,可以将2024转换成2024 呢?( A)(2分) A.str(2024) B.int(2024) C.fl…...
深入了解RTMP推流技术:视频汇聚EasyCVR低延迟与高稳定性分析
RTMP(Real Time Messaging Protocol)视频推流技术,作为音视频传输领域的关键技术之一,已经在直播、视频会议、在线教育等多个场景中得到了广泛应用。RTMP以其独特的优势,为实时音视频传输提供了高效、稳定的解决方案。…...
containerd手动配置容器网络
containerd手动配置容器网络 机器详情nerdctl启动一个不带网络的容器获取容器ID、PID与network namespace路径准备bridge插件的执行配置文件通过下面的命令调用bridge插件准备tuning插件文件执行下面的命令调用tuning插件准备portmap插件文件执行下面的命令调用portmap插件删除…...
数据迁移到 Django 模型表:详尽指南
数据迁移是许多应用程序开发过程中必不可少的一部分。在这篇文章中,我们将详细分析和总结如何通过一个定制的 Django 管理命令,将数据从 MySQL 数据库迁移到 Django 模型表中。这种方法可以确保数据在多个数据库之间有效且安全地迁移,同时避免…...
代码随想三刷二叉树篇4
代码随想三刷二叉树篇4 617. 合并二叉树题目代码 700. 二叉搜索树中的搜索题目代码 98. 验证二叉搜索树题目代码 530. 二叉搜索树的最小绝对差题目代码 501. 二叉搜索树中的众数题目代码 236. 二叉树的最近公共祖先题目代码 617. 合并二叉树 题目 链接 代码 /*** Definitio…...
『大模型笔记』如何让小型语言模型发挥作用!
如何让小型语言模型发挥作用! 文章目录 一. 如何让小型语言模型发挥作用!不可能的可能性小模型的潜力创新方法与突破实践与验证过滤系统与数据质量小模型的逐步改进信息理论蒸馏方法(新工作InfoSum)总结与展望Infini-Gram与N-gram模型的新时代后缀数组与高速计算二. 参考文献…...
jnp.diag
jnp.diag 是 JAX 库中用于创建对角矩阵或提取对角线元素的函数。具体功能取决于输入的形状: 当输入是一维数组时,jnp.diag 创建一个以该数组为对角线元素的对角矩阵。当输入是二维数组时,jnp.diag 提取并返回对角线元素。 函数签名 jnp.di…...