ansible使用详解
ansible执行,用户主机配置
免密同一个同一个用户执行命令
1
能免密登录的
[root@mcw1 ~]$ ansible 10.0.0.132 -m shell -a "hostname"
10.0.0.132 | CHANGED | rc=0 >>
mcw2
[root@mcw1 ~]$ ssh 10.0.0.132 #132能免密登录
Last login: Mon Feb 7 18:57:12 2022 from 10.0.0.131
[root@mcw2 ~]#
不能免密登录的
[root@mcw1 ~]$ ssh 10.0.0.133
root@10.0.0.133's password:
[root@mcw1 ~]$ ansible 10.0.0.133 -m shell -a "hostname"
[WARNING]: Could not match supplied host pattern, ignoring: 10.0.0.133
[WARNING]: No hosts matched, nothing to do
使用host文件执行命令
[root@mcw1 ~]$ cat mcw.txt
[mcw]
10.0.0.132 #免密
10.0.0.133 #不免密
[root@mcw1 ~]$ ansible -i mcw.txt mcw -m shell -a "hostname"
10.0.0.133 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: root@10.0.0.133: Permission denied (publickey,password).",
"unreachable": true
}
10.0.0.132 | CHANGED | rc=0 >>
mcw2
2、指定用户密码执行命令
[root@mcw1 ~]$ cat mcw.txt
[mcw]
10.0.0.132
10.0.0.133 ansible_ssh_user='root' ansible_ssh_pass='123456'
[root@mcw1 ~]$ ansible -i mcw.txt mcw -m shell -a "hostname"
10.0.0.132 | CHANGED | rc=0 >>
mcw2
10.0.0.133 | CHANGED | rc=0 >>
mcw3
用户密码可以写在上面,这样分组里重复使用的时候不用写用户密码了
[root@mcw1 ~]$ cat mcw.txt
10.0.0.133 ansible_ssh_user='root' ansible_ssh_pass='123456'
[mcw]
10.0.0.132
10.0.0.133
[root@mcw1 ~]$ ansible -i mcw.txt mcw -m shell -a "hostname"
10.0.0.133 | CHANGED | rc=0 >>
mcw3
10.0.0.132 | CHANGED | rc=0 >>
mcw2
3、使用普通用户执行命令
[machangwei@mcw1 ~]$ cat mcw.txt
10.0.0.132 ansible_ssh_user='root' ansible_ssh_pass='123456'
10.0.0.133
[mcw]
10.0.0.132 #root免密,machangwei不
10.0.0.133 #都不
[machangwei@mcw1 ~]$ ansible -i mcw.txt mcw -m shell -a "whoami"
The authenticity of host '10.0.0.133 (10.0.0.133)' can't be established.
ED25519 key fingerprint is SHA256:q2pX2MgVhzo7ed3GE0bd50R7jcFkd5FR68yaVAbSVG4.
This host key is known by the following other names/addresses:
~/.ssh/known_hosts:1: 10.0.0.132
Are you sure you want to continue connecting (yes/no/[fingerprint])? 10.0.0.132 | CHANGED | rc=0 >>
root
普通用户连接root执行命令还是需要添加ansible_sudo_pass,不然会提示yes信息
[machangwei@mcw1 ~]$ cat mcw.txt
10.0.0.132 ansible_ssh_user='root' ansible_ssh_pass='123456' ansible_sudo_pass='123456'
10.0.0.133 ansible_ssh_user='machangwei' ansible_ssh_pass='123456'
[mcw]
10.0.0.132
10.0.0.133
[machangwei@mcw1 ~]$ ansible -i mcw.txt mcw -m shell -a "whoami"
10.0.0.133 | 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.
10.0.0.132 | CHANGED | rc=0 >>
root
免密普通用户连接另一个普通用户执行命令
普通用户连接另一个普通用户sudo到root执行命令
报错了:
[xiaoma@mcw1 ~]$ cat mcw.txt
10.0.0.132 ansible_ssh_user='machangwei' ansible_ssh_pass='123456' ansible_sudo_pass='123456'
10.0.0.133 ansible_ssh_user='machangwei' ansible_ssh_pass='123456' ansible_sudo_pass='123456'
[mcw]
10.0.0.132
10.0.0.133
[xiaoma@mcw1 ~]$ ansible -i mcw.txt mcw -m shell -a "whoami"
10.0.0.132 | 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. 10.0.0.133 | 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.
解决方法:打开这个参数
[root@mcw1 ~]$ vim /etc/ansible/ansible.cfg
[root@mcw1 ~]$ grep host_key_checking /etc/ansible/ansible.cfg
#host_key_checking = False
host_key_checking = False
然后再次执行,但是用户不是root,我们想通过普通用户sudo到root执行命令的
[xiaoma@mcw1 ~]$ cat mcw.txt
10.0.0.132 ansible_ssh_user='machangwei' ansible_ssh_pass='123456' ansible_sudo_pass='123456'
10.0.0.133 ansible_ssh_user='machangwei' ansible_ssh_pass='123456' ansible_sudo_pass='123456'
[mcw]
10.0.0.132
10.0.0.133
[xiaoma@mcw1 ~]$
[xiaoma@mcw1 ~]$ ansible -i mcw.txt mcw -m shell -a "whoami"
10.0.0.132 | CHANGED | rc=0 >>
machangwei
10.0.0.133 | CHANGED | rc=0 >>
machangwei
如下,需要开启这些参数,可参考:https://blog.csdn.net/weixin_46575696/article/details/109638397
[root@mcw1 ~]$ grep -A 8 privilege_escalation /etc/ansible/ansible.cfg
[privilege_escalation]
#become=True
#become_method=sudo
#become_user=root
#become_ask_pass=False
become=True
become_method=sudo
become_user=root
become_ask_pass=False
然后再次执行,就可以实现sudo到root执行命令
[xiaoma@mcw1 ~]$ cat mcw.txt
10.0.0.132 ansible_ssh_user='machangwei' ansible_ssh_pass='123456' ansible_sudo_pass='123456'
10.0.0.133 ansible_ssh_user='machangwei' ansible_ssh_pass='123456' ansible_sudo_pass='123456'
[mcw]
10.0.0.132
10.0.0.133
[xiaoma@mcw1 ~]$ ansible -i mcw.txt mcw -m shell -a "whoami"
10.0.0.132 | CHANGED | rc=0 >>
root
10.0.0.133 | CHANGED | rc=0 >>
root
ansible通过跳板机方式执行(主机A上用普通用户A连接主机B的另一个普通用户B,然后在主机B上用普通用户B连接主机C,在主机C上执行命令
)
1.1 首先生成ssh公钥秘钥对(如果没有,有就不用了):
ssh-keygen -t rsa
1
一路默认回车,系统会在~/.ssh下生成id_rsa、id_rsa.pub
1.2 然后将公钥发送到跳板机和目标机:
可以直接将公钥的内容拷贝到~/.ssh/authorized_keys中
chmod 600 ~/.ssh/authorized_keys
或者ssh-copy-id -p12345 user@IP(跳板机可以使用,目标机不能)
二、跳板机安装nc命令
执行nc -help确认命令是否成功安装(没有安装的可以百度安装,我这里是已经安装好了的)
三、测试ssh是否能通过跳板机连接到目标机
ssh -o "ProxyCommand ssh -p 12345 user@跳板机公网IP nc -w 1000 %h %p" -p22 user@目标主机ip
我这里环境如下,mcw1是ansible主机,mcw2是当做跳板机,mcw3是当做目标主机。现在mcw1上通过mcw2去连接mcw3测试成功
10.0.0.131 mcw1 10.0.0.132 mcw2 10.0.0.133 mcw3
[root@mcw1 ~]$ ssh -o "ProxyCommand ssh -p 22 root@10.0.0.132 nc %h %p" -p22 root@10.0.0.133
Last login: Mon Feb 7 22:10:29 2022 from 10.0.0.132
[root@mcw3 ~]#
加上-w参数这个值也是可以的
[root@mcw1 ~]$ ssh -o "ProxyCommand ssh -p 22 root@10.0.0.132 -w 14400 nc %h %p" -p22 root@10.0.0.133
channel 0: open failed: administratively prohibited: open failed
Tunnel forwarding failed
Last login: Mon Feb 7 22:15:12 2022 from 10.0.0.132
[root@mcw3 ~]#
四、测试添加到~/.ssh/config配置文件中
mcw1是ansible主机,mcw2是当做跳板机,mcw3是当做目标主机。现在mcw1上通过mcw2去连接mcw3测试成功
[root@mcw1 ~]$ cat .ssh/config
Host mcw2
HostName 10.0.0.132
Port 22
BatchMode yes
User root Host mcw3
HostName 10.0.0.133
ServerAliveInterval 60
TCPKeepAlive yes
IdentityFile ~/.ssh/id_rsa
ProxyCommand ssh mcw2 'nc %h %p'
User root
Port 22
[root@mcw1 ~]$ ssh mcw3
Last login: Tue Feb 8 00:44:54 2022 from 10.0.0.132
[root@mcw3 ~]#
由于实际情况生产的服务器太多不能一个一个的config配置文件,所以config可以配置如下:
我这里不太好模拟环境。因为这里本来就可以直接通过ip连接
[root@mcw1 ~]$ cat .ssh/config
Host mcw2
HostName 10.0.0.132
Port 22
BatchMode yes #这个选项对脚本文件和批处理任务十分有用
User machangwei Host 10.0.0.x
ServerAliveInterval 60 #本地 ssh 每隔 60s 向 server 端 sshd 发送 keep-alive 包,如果发送 50 次,server 无回应断开连接。
#ServerAliveCountMax 50 #前一个参数表示要保持TCP连接,后一个参数(ClientAliveCountMax)表示客户端的SSH连线闲置多长时间后自动终止连线的数值,单位为分钟。
TCPKeepAlive yes
#ClientAliveCountMax 360
#IdentityFile ~/.ssh/id_rsa
ProxyCommand ssh mcw2 'nc %h %p'
User machangwei
Port 22
[root@mcw1 ~]$ ssh 10.0.0.133
Last login: Tue Feb 8 01:03:44 2022 from 10.0.0.131
[root@mcw3 ~]#
安装
yum安装
[root@mcw01 ~]$ yum install -y ansible
下载tar包安装
包下载地址:https://releases.ansible.com/ansible/
yum install -y ansible
yum remove ansible
yum install gcc gcc-c++ make glibc-devel kernel-headers
yum install pycrypto
wget https://pypi.python.org/packages/source/a/ansible/ansible-1.9.6.tar.gz
tar xf ansible-1.9.6.tar.gz
cd ansible-1.9.6/
python setup.py install [root@mcw02 ~/ansible]$ ansible --version
ansible 1.9.6
configured module search path = None
[root@mcw02 ~/ansible]$
安装后不知道它的配置和hosts在哪里,直接创建一个目录/etc/ansible/,然后创建hosts文件,它就能找到
[root@mcw02 ~/ansible]$ ls /etc/ansible/
hosts
[root@mcw02 ~/ansible]$
此时,可以直接写程序调用apii也是没问题的。安装时将包都装到python2的目录下了
linux上使用tar包成功安装1,9,6版本的了,但是我pycharm中没有,这样不太好开发。pycharm命令行和setting里面都装失败了,那么就将linux上的包下载到本地
如下,当我setting里面按照ansible时,发现依赖包已经安装上了,但只是ansible包装不了。将包从linux上下载下来后,发现不能识别,就把里面两个文件弄到外面来就行,就能识别到了。如下,导入不报红线了。如此,可以方便开发了
我们最好实现安装ansible,能直接迁移就用的那种。不会破坏主机内环境,单独一个目录下,像编译安装的那种。ansible我这里编译安装的,发现在其他目录生成文件了,包括命令文件,有时间试试迁移走能不能使用,这样就能确定生成哪些文件,我们能安装又能恢复到安装之前的环境。
安装后简单使用
配置免密。将控制主机的共有下发到被管节点,重命名为authorized_keys。添加主机清单
添加主机到默认hosts文件中
echo '10.0.0.12' >>/etc/ansible/hosts
没有设置免密
[root@mcw01 ~]$ ansible 10.0.0.12 -m 'ping'
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: 10.0.0.12 将控制主机的共有下发到被管节点,重命名为authorized_keys
[root@mcw01 ~]$ ssh-copy-id -i /root/.ssh/id_rsa.pub root@10.0.0.12
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@10.0.0.12's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'root@10.0.0.12'"
and check to make sure that only the key(s) you wanted were added. [root@mcw01 ~]$ 再次执行报错
[root@mcw01 ~]$ ansible 10.0.0.12 -m ping
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: 10.0.0.12
原因:
没有添加主机清单 [root@mcw01 ~]$ echo '10.0.0.12' >>/etc/ansible/hosts #添加主机到hosts文件后就可以了
[root@mcw01 ~]$ ansible 10.0.0.12 -m ping
10.0.0.12 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@mcw01 ~]$
自定义hosts文件
[root@mcw01 ~/mcw]$ vim hosts
[root@mcw01 ~/mcw]$ cat hosts
10.0.0.12
[web]
10.0.0.12
[root@mcw01 ~/mcw]$ ansible -i hosts 10.0.0.12 -m ping
10.0.0.12 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@mcw01 ~/mcw]$ ansible -i hosts web -m ping
10.0.0.12 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@mcw01 ~/mcw]$
获取帮助信息
ansible-doc -h
[root@mcw01 ~/mcw]$ ansible-doc -h
usage: ansible-doc [-h] [--version] [-v] [-M MODULE_PATH]
[--playbook-dir BASEDIR]
[-t {become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,module,strategy,vars}]
[-j] [-F | -l | -s | --metadata-dump]
[plugin [plugin ...]] plugin documentation tool positional arguments:
plugin Plugin optional arguments:
--metadata-dump **For internal testing only** Dump json metadata for
all plugins.
--playbook-dir BASEDIR
Since this tool does not use playbooks, use this as a
substitute playbook directory.This sets the relative
path for many features including roles/ group_vars/
etc.
--version show program's version number, config file location,
configured module search path, module location,
executable location and exit
-F, --list_files Show plugin names and their source files without
summaries (implies --list)
-M MODULE_PATH, --module-path MODULE_PATH
prepend colon-separated path(s) to module library (def
ault=~/.ansible/plugins/modules:/usr/share/ansible/plu
gins/modules)
-h, --help show this help message and exit
-j, --json Change output into json format.
-l, --list List available plugins
-s, --snippet Show playbook snippet for specified plugin(s)
-t {become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,module,strategy,vars}, --type {become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,module,strategy,vars}
Choose which plugin type (defaults to "module").
Available plugin types are : ('become', 'cache',
'callback', 'cliconf', 'connection', 'httpapi',
'inventory', 'lookup', 'netconf', 'shell', 'module',
'strategy', 'vars')
-v, --verbose verbose mode (-vvv for more, -vvvv to enable
connection debugging) See man pages for Ansible CLI options or website for tutorials
https://docs.ansible.com
[root@mcw01 ~/mcw]$
列出ansible系统支持的模块 ansible-doc -l
[root@mcw01 ~/mcw]$ ansible-doc -l
fortios_router_community_list Configure community lists in Fortinet's FortiOS and FortiGate
azure_rm_devtestlab_info Get Azure DevTest Lab facts
ecs_taskdefinition register a task definition in ecs
avi_alertscriptconfig Module for setup of AlertScriptConfig Avi RESTful Object
tower_receive Receive assets from Ansible Tower
netapp_e_iscsi_target NetApp E-Series manage iSCSI target configuration
azure_rm_acs Manage an Azure Container Service(ACS) instance
fortios_log_syslogd2_filter Filters for remote system server in Fortinet's FortiOS and FortiGate
junos_rpc Runs an arbitrary RPC over NetConf on an Juniper JUNOS device
na_elementsw_vlan NetApp Element Software Manage VLAN
pn_ospf CLI command to add/remove ospf protocol to a vRouter
pn_snmp_vacm CLI command to create/modify/delete snmp-vacm
cp_mgmt_service_sctp Manages service-sctp objects on Check Point over Web Services API
..........
ansible-doc -s 模块,列出模块的动作
[root@mcw01 ~]$ ansible-doc -s yum
- name: Manages packages with the `yum' package manager
yum:
allow_downgrade: # Specify if the named package and version is allowed to downgrade a maybe already installed higher version of that
package. Note that setting allow_downgrade=True can make this module behave in a non-
idempotent way. The task could end up with a set of packages that does not match the
complete list of specified packages to install (because dependencies between the
downgraded package and others can cause changes to the packages which were in the
earlier transaction).
autoremove: # If `yes', removes all "leaf" packages from the system that were originally installed as dependencies of user-
installed packages but which are no longer required by any such package. Should be
used alone or when state is `absent' NOTE: This feature requires yum >= 3.4.3
(RHEL/CentOS 7+)
bugfix: # If set to `yes', and `state=latest' then only installs updates that have been marked bugfix related.
conf_file: # The remote yum configuration file to use for the transaction.
disable_excludes: # Disable the excludes defined in YUM config files. If set to `all', disables all excludes. If set to `main', disable
excludes defined in [main] in yum.conf. If set to `repoid', disable excludes defined
for given repo id.
disable_gpg_check: # Whether to disable the GPG checking of signatures of packages being installed. Has an effect only if state is
`present' or `latest'.
disable_plugin: # `Plugin' name to disable for the install/update operation. The disabled plugins will not persist beyond the
transaction.
disablerepo: # `Repoid' of repositories to disable for the install/update operation. These repos will not persist beyond the
transaction. When specifying multiple repos, separate them with a `","'. As of
Ansible 2.7, this can alternatively be a list instead of `","' separated string
download_dir: # Specifies an alternate directory to store packages. Has an effect only if `download_only' is specified.
download_only: # Only download the packages, do not install them.
enable_plugin: # `Plugin' name to enable for the install/update operation. The enabled plugin will not persist beyond the
transaction.
enablerepo: # `Repoid' of repositories to enable for the install/update operation. These repos will not persist beyond the
transaction. When specifying multiple repos, separate them with a `","'. As of
Ansible 2.7, this can alternatively be a list instead of `","' separated string
exclude: # Package name(s) to exclude when state=present, or latest
install_weak_deps: # Will also install all packages linked by a weak dependency relation. NOTE: This feature requires yum >= 4
(RHEL/CentOS 8+)
installroot: # Specifies an alternative installroot, relative to which all packages will be installed.
list: # Package name to run the equivalent of yum list --show-duplicates <package> against. In addition to listing packages,
use can also list the following: `installed', `updates', `available' and `repos'.
This parameter is mutually exclusive with `name'.
lock_timeout: # Amount of time to wait for the yum lockfile to be freed.
name: # A package name or package specifier with version, like `name-1.0'. If a previous version is specified, the task also
needs to turn `allow_downgrade' on. See the `allow_downgrade' documentation for
caveats with downgrading packages. When using state=latest, this can be `'*'' which
means run `yum -y update'. You can also pass a url or a local path to a rpm file
(using state=present). To operate on several packages this can accept a comma
separated string of packages or (as of 2.0) a list of packages.
releasever: # Specifies an alternative release from which all packages will be installed.
security: # If set to `yes', and `state=latest' then only installs updates that have been marked security related.
skip_broken: # Skip packages with broken dependencies(devsolve) and are causing problems.
state: # Whether to install (`present' or `installed', `latest'), or remove (`absent' or `removed') a package. `present' and
`installed' will simply ensure that a desired package is installed. `latest' will
update the specified package if it's not of the latest available version. `absent'
and `removed' will remove the specified package. Default is `None', however in effect
the default action is `present' unless the `autoremove' option is enabled for this
module, then `absent' is inferred.
update_cache: # Force yum to check if cache is out of date and redownload if needed. Has an effect only if state is `present' or
`latest'.
update_only: # When using latest, only update installed packages. Do not install packages. Has an effect only if state is `latest'
use_backend: # This module supports `yum' (as it always has), this is known as `yum3'/`YUM3'/`yum-deprecated' by upstream yum
developers. As of Ansible 2.7+, this module also supports `YUM4', which is the "new
yum" and it has an `dnf' backend. By default, this module will select the backend
based on the `ansible_pkg_mgr' fact.
validate_certs: # This only applies if using a https url as the source of the rpm. e.g. for localinstall. If set to `no', the SSL
certificates will not be validated. This should only set to `no' used on personally
controlled sites using self-signed certificates as it avoids verifying the source
site. Prior to 2.1 the code worked as if this was set to `yes'.
(END)
ansible命令后加-v -vvv得到详细输出结果
[root@mcw01 ~/mcw]$ ansible web -i hosts -m ping
10.0.0.12 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@mcw01 ~/mcw]$
[root@mcw01 ~/mcw]$ ansible web -i hosts -m ping -v
Using /etc/ansible/ansible.cfg as config file
10.0.0.12 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@mcw01 ~/mcw]$ ansible web -i hosts -m ping -vvv
ansible 2.9.27
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 = /usr/bin/ansible
python version = 2.7.5 (default, Aug 4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]
Using /etc/ansible/ansible.cfg as config file
host_list declined parsing /root/mcw/hosts as it did not pass its verify_file() method
script declined parsing /root/mcw/hosts as it did not pass its verify_file() method
auto declined parsing /root/mcw/hosts as it did not pass its verify_file() method
Parsed /root/mcw/hosts inventory source with ini plugin
Skipping callback 'actionable', as we already have a stdout callback.
Skipping callback 'counter_enabled', as we already have a stdout callback.
Skipping callback 'debug', as we already have a stdout callback.
Skipping callback 'dense', as we already have a stdout callback.
Skipping callback 'dense', as we already have a stdout callback.
Skipping callback 'full_skip', as we already have a stdout callback.
Skipping callback 'json', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'null', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.
Skipping callback 'selective', as we already have a stdout callback.
Skipping callback 'skippy', as we already have a stdout callback.
Skipping callback 'stderr', as we already have a stdout callback.
Skipping callback 'unixy', as we already have a stdout callback.
Skipping callback 'yaml', as we already have a stdout callback.
META: ran handlers
<10.0.0.12> ESTABLISH SSH CONNECTION FOR USER: None
<10.0.0.12> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/4121990a2e 10.0.0.12 '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
<10.0.0.12> (0, '/root\n', '')
<10.0.0.12> ESTABLISH SSH CONNECTION FOR USER: None
<10.0.0.12> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/4121990a2e 10.0.0.12 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605 `" && echo ansible-tmp-1665935443.85-27907-45480909600605="` echo /root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605 `" ) && sleep 0'"'"''
<10.0.0.12> (0, 'ansible-tmp-1665935443.85-27907-45480909600605=/root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605\n', '')
<10.0.0.12> Attempting python interpreter discovery
<10.0.0.12> ESTABLISH SSH CONNECTION FOR USER: None
<10.0.0.12> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/4121990a2e 10.0.0.12 '/bin/sh -c '"'"'echo PLATFORM; uname; echo FOUND; command -v '"'"'"'"'"'"'"'"'/usr/bin/python'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.7'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.6'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.5'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python2.7'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python2.6'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'/usr/libexec/platform-python'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'/usr/bin/python3'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python'"'"'"'"'"'"'"'"'; echo ENDFOUND && sleep 0'"'"''
<10.0.0.12> (0, 'PLATFORM\nLinux\nFOUND\n/usr/bin/python\n/usr/bin/python2.7\n/usr/bin/python\nENDFOUND\n', '')
<10.0.0.12> ESTABLISH SSH CONNECTION FOR USER: None
<10.0.0.12> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/4121990a2e 10.0.0.12 '/bin/sh -c '"'"'/usr/bin/python && sleep 0'"'"''
<10.0.0.12> (0, '{"osrelease_content": "NAME=\\"CentOS Linux\\"\\nVERSION=\\"7 (Core)\\"\\nID=\\"centos\\"\\nID_LIKE=\\"rhel fedora\\"\\nVERSION_ID=\\"7\\"\\nPRETTY_NAME=\\"CentOS Linux 7 (Core)\\"\\nANSI_COLOR=\\"0;31\\"\\nCPE_NAME=\\"cpe:/o:centos:centos:7\\"\\nHOME_URL=\\"https://www.centos.org/\\"\\nBUG_REPORT_URL=\\"https://bugs.centos.org/\\"\\n\\nCENTOS_MANTISBT_PROJECT=\\"CentOS-7\\"\\nCENTOS_MANTISBT_PROJECT_VERSION=\\"7\\"\\nREDHAT_SUPPORT_PRODUCT=\\"centos\\"\\nREDHAT_SUPPORT_PRODUCT_VERSION=\\"7\\"\\n\\n", "platform_dist_result": ["centos", "7.4.1708", "Core"]}\n', '')
Using module file /usr/lib/python2.7/site-packages/ansible/modules/system/ping.py
<10.0.0.12> PUT /root/.ansible/tmp/ansible-local-27892Bsbym2/tmpDle2Wk TO /root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605/AnsiballZ_ping.py
<10.0.0.12> SSH: EXEC sftp -b - -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/4121990a2e '[10.0.0.12]'
<10.0.0.12> (0, 'sftp> put /root/.ansible/tmp/ansible-local-27892Bsbym2/tmpDle2Wk /root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605/AnsiballZ_ping.py\n', '')
<10.0.0.12> ESTABLISH SSH CONNECTION FOR USER: None
<10.0.0.12> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/4121990a2e 10.0.0.12 '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605/ /root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605/AnsiballZ_ping.py && sleep 0'"'"''
<10.0.0.12> (0, '', '')
<10.0.0.12> ESTABLISH SSH CONNECTION FOR USER: None
<10.0.0.12> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/4121990a2e -tt 10.0.0.12 '/bin/sh -c '"'"'/usr/bin/python /root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605/AnsiballZ_ping.py && sleep 0'"'"''
<10.0.0.12> (0, '\r\n{"invocation": {"module_args": {"data": "pong"}}, "ping": "pong"}\r\n', 'Shared connection to 10.0.0.12 closed.\r\n')
<10.0.0.12> ESTABLISH SSH CONNECTION FOR USER: None
<10.0.0.12> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/4121990a2e 10.0.0.12 '/bin/sh -c '"'"'rm -f -r /root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605/ > /dev/null 2>&1 && sleep 0'"'"''
<10.0.0.12> (0, '', '')
10.0.0.12 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"invocation": {
"module_args": {
"data": "pong"
}
},
"ping": "pong"
}
META: ran handlers
META: ran handlers
[root@mcw01 ~/mcw]$
ansible inventory
定义主机和主机组
还没有免密的11和13
[root@mcw01 ~/mcw]$ cat hosts
10.0.0.11
10.0.0.12
10.0.0.13
[web]
10.0.0.12
[root@mcw01 ~/mcw]$ ansible -i hosts 10.0.0.11:10.0.0.13 -m ping
The authenticity of host '10.0.0.13 (10.0.0.13)' can't be established.
ECDSA key fingerprint is SHA256:1TxynA6n0UD3ZO0xutB2zsCTeq3wtp+O3L5p34As/4Q.
ECDSA key fingerprint is MD5:b0:3d:ab:dd:d7:93:68:ae:3d:b8:7a:35:c6:03:49:1d.
Are you sure you want to continue connecting (yes/no)? 10.0.0.11 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Permission denied (publickey,password).",
"unreachable": true
}
yes
10.0.0.13 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Warning: Permanently added '10.0.0.13' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey,password).",
"unreachable": true
}
[root@mcw01 ~/mcw]$
没有免密的可以添加密码,加密码ansible_ssh_pass,免密的可以不用写密码。多个主机可以用冒号分割
[root@mcw01 ~/mcw]$ cat hosts
10.0.0.11 ansible_ssh_pass='123456'
10.0.0.12
10.0.0.13 ansible_ssh_pass='123456'
[docker]
10.0.0.1[1:3]
[docker:vars]
ansible_ssh_pass='123456'
[ansible:chidren]
docker
[root@mcw01 ~/mcw]$ ansible -i hosts 10.0.0.11:10.0.0.13 -m ping
[WARNING]: * Failed to parse /root/mcw/hosts with yaml plugin: YAML inventory has invalid structure, it should be a dictionary, got: <class
'ansible.parsing.yaml.objects.AnsibleUnicode'>
[WARNING]: * Failed to parse /root/mcw/hosts with ini plugin: /root/mcw/hosts:8: Section [ansible:chidren] has unknown type: chidren
[WARNING]: Unable to parse /root/mcw/hosts as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
10.0.0.13 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10.0.0.11 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@mcw01 ~/mcw]$ [root@mcw01 ~/mcw]$ cat hosts
10.0.0.11 ansible_ssh_pass='123456'
10.0.0.12
10.0.0.13 ansible_ssh_pass='123456'
[docker]
10.0.0.1[1:3]
[docker:vars]
ansible_ssh_pass='123456'
[ansible:chidren]
docker
[root@mcw01 ~/mcw]$ ansible -i hosts 10.0.0.11:10.0.0.12 -m ping
[WARNING]: * Failed to parse /root/mcw/hosts with yaml plugin: YAML inventory has invalid structure, it should be a dictionary, got: <class
'ansible.parsing.yaml.objects.AnsibleUnicode'>
[WARNING]: * Failed to parse /root/mcw/hosts with ini plugin: /root/mcw/hosts:8: Section [ansible:chidren] has unknown type: chidren
[WARNING]: Unable to parse /root/mcw/hosts as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
10.0.0.12 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10.0.0.11 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@mcw01 ~/mcw]$
[root@mcw01 ~/mcw]$ ansible -i hosts 10.0.0.11:10.0.0.12:10.0.0.13 -m ping
[WARNING]: * Failed to parse /root/mcw/hosts with yaml plugin: YAML inventory has invalid structure, it should be a dictionary, got: <class
'ansible.parsing.yaml.objects.AnsibleUnicode'>
[WARNING]: * Failed to parse /root/mcw/hosts with ini plugin: /root/mcw/hosts:8: Section [ansible:chidren] has unknown type: chidren
[WARNING]: Unable to parse /root/mcw/hosts as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
10.0.0.13 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10.0.0.12 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10.0.0.11 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@mcw01 ~/mcw]$
-o单行输出
[root@mcw01 ~/mcw]$ ansible -i hosts 10.0.0.11:10.0.0.12:10.0.0.13 -m ping -o
[WARNING]: * Failed to parse /root/mcw/hosts with yaml plugin: YAML inventory has invalid structure, it should be a dictionary, got: <class
'ansible.parsing.yaml.objects.AnsibleUnicode'>
[WARNING]: * Failed to parse /root/mcw/hosts with ini plugin: /root/mcw/hosts:8: Section [ansible:chidren] has unknown type: chidren
[WARNING]: Unable to parse /root/mcw/hosts as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
10.0.0.13 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
10.0.0.12 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
10.0.0.11 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
[root@mcw01 ~/mcw]$
一组主机组要添加密码等变量,需要在后面定义[主机组名称:vars]
[root@mcw01 ~/mcw]$ cat hosts
10.0.0.11 ansible_ssh_pass='123456'
10.0.0.12
10.0.0.13 ansible_ssh_pass='123456'
[docker]
10.0.0.1[1:3]
[docker:vars]
ansible_ssh_pass='123456'
[ansible:chidren]
docker
[root@mcw01 ~/mcw]$ ansible -i hosts docker -m ping -o
[WARNING]: * Failed to parse /root/mcw/hosts with yaml plugin: YAML inventory has invalid structure, it should be a dictionary, got: <class
'ansible.parsing.yaml.objects.AnsibleUnicode'>
[WARNING]: * Failed to parse /root/mcw/hosts with ini plugin: /root/mcw/hosts:8: Section [ansible:chidren] has unknown type: chidren
[WARNING]: Unable to parse /root/mcw/hosts as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
10.0.0.13 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
10.0.0.12 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
10.0.0.11 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
[root@mcw01 ~/mcw]$
把[ansible:children] docker 去掉之后,就没有警告信息了。不过这个代表的是ansible这个主机组继承的docker主机组的数据,应该是这样的。从下面那小节可以看出
[root@mcw01 ~/mcw]$ cat hosts
10.0.0.11 ansible_ssh_pass='123456'
10.0.0.12
10.0.0.13 ansible_ssh_pass='123456'
[docker]
10.0.0.1[1:3]
[docker:vars]
ansible_ssh_pass='123456'
[root@mcw01 ~/mcw]$ ansible -i hosts docker -m ping -o
10.0.0.12 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
10.0.0.13 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
10.0.0.11 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
[root@mcw01 ~/mcw]$
多个Inventory列表
inventory默认为/etc/ansible/hosts,可以修改为一个目录。 [root@mcw01 ~/mcw]$ tree inventory
inventory
├── docker
└── hosts 0 directories, 2 files
[root@mcw01 ~/mcw]$
[root@mcw01 ~/mcw]$ cat inventory/hosts
10.0.0.11 ansible_ssh_pass='123456'
10.0.0.13 ansible_ssh_pass='123456'
[root@mcw01 ~/mcw]$ cat inventory/docker
[docker]
10.0.0.1[1:3]
[docker:vars]
ansible_ssh_pass='123456'
[root@mcw01 ~/mcw]$ 注意这个参数不能放到最后,这个配置文件是分区的,放在defaults下面
[defaults] # some basic default values...
inventory = /root/mcw/inventory/
#inventory = /etc/ansible/hosts [root@mcw01 ~/mcw]$ ansible 10.0.0.11:10.0.0.13 --list-hosts
hosts (2):
10.0.0.11
10.0.0.13
[root@mcw01 ~/mcw]$ ansible docker --list-hosts
hosts (3):
10.0.0.11
10.0.0.12
10.0.0.13
[root@mcw01 ~/mcw]$ vim /root/mcw/inventory/docker
[root@mcw01 ~/mcw]$ cat /root/mcw/inventory/docker
[docker]
10.0.0.1[1:3]
[docker:vars]
ansible_ssh_pass='123456'
[ansible:children]
docker
[root@mcw01 ~/mcw]$ ansible ansible --list-hosts
hosts (3):
10.0.0.11
10.0.0.12
10.0.0.13
[root@mcw01 ~/mcw]$
动态inventory,自定义inventory脚本
程序:
[root@mcw01 ~/mcw]$ cat mcw.py
#!/usr/bin/env python
#_*_ coding: utf-8 _*_
import argparse
import sys
import json
def lists():
r={}
h=['172.17.42.10'+str(i) for i in range(1,4)]
hosts={'hosts':h}
r['docker']=hosts
return json.dumps(r,indent=4)
def hosts(name):
r = {'ansible_ssh_pass':'123456'}
cpis=dict(r.items())
return json.dumps(cpis)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-l','--list',help='hosts list',action='store_true') parser.add_argument('-H','--host',help='hosts vars')
args=vars(parser.parse_args()) if args['list']:
print(lists())
elif args['host']:
print(hosts(args['host']))
else:
parser.print_help()
[root@mcw01 ~/mcw]$
执行结果:
[root@mcw01 ~/mcw]$ python mcw.py --list
{
"docker": {
"hosts": [
"172.17.42.101",
"172.17.42.102",
"172.17.42.103"
]
}
}
[root@mcw01 ~/mcw]$
[root@mcw01 ~/mcw]$ python mcw.py -H 172.17.42.102
{"ansible_ssh_pass": "123456"}
[root@mcw01 ~/mcw]$
修改主机:
[root@mcw01 ~/mcw]$ cat mcw.py
#!/usr/bin/env python
#_*_ coding: utf-8 _*_
import argparse
import sys
import json
def lists():
r={}
h=['10.0.0.1'+str(i) for i in range(1,4)]
hosts={'hosts':h}
r['docker']=hosts
return json.dumps(r,indent=4)
def hosts(name):
r = {'ansible_ssh_pass':'123456'}
cpis=dict(r.items())
return json.dumps(cpis)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-l','--list',help='hosts list',action='store_true') parser.add_argument('-H','--host',help='hosts vars')
args=vars(parser.parse_args()) if args['list']:
print(lists())
elif args['host']:
print(hosts(args['host']))
else:
parser.print_help()
调用的执行结果如下:
[root@mcw01 ~/mcw]$ python mcw.py --list
{
"docker": {
"hosts": [
"10.0.0.11",
"10.0.0.12"
]
}
}
[root@mcw01 ~/mcw]$ python mcw.py --list
{
"docker": {
"hosts": [
"10.0.0.11",
"10.0.0.12"
]
}
}
[root@mcw01 ~/mcw]$ vim mcw.py
[root@mcw01 ~/mcw]$ python mcw.py --list
{
"docker": {
"hosts": [
"10.0.0.11",
"10.0.0.12",
"10.0.0.13"
]
}
}
[root@mcw01 ~/mcw]$ python mcw.py -H 10.0.0.13
{"ansible_ssh_pass": "123456"}
[root@mcw01 ~/mcw]$
[root@mcw01 ~/mcw]$
[root@mcw01 ~/mcw]$ ansible -i mcw.py 10.0.0.13 -m ping -o #没有执行权限,会报错。不能解析脚本插件,这是作为脚本插件的,作为一个inventory源
[WARNING]: * Failed to parse /root/mcw/mcw.py with script plugin: problem running /root/mcw/mcw.py --list ([Errno 13] Permission denied)
[WARNING]: * Failed to parse /root/mcw/mcw.py with ini plugin: /root/mcw/mcw.py:3: Expected key=value host variable assignment, got: argparse
[WARNING]: Unable to parse /root/mcw/mcw.py as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: 10.0.0.13
[root@mcw01 ~/mcw]$ ll mcw.py
-rw-r--r-- 1 root root 715 Oct 17 21:51 mcw.py
[root@mcw01 ~/mcw]$ chmod +x mcw.py
[root@mcw01 ~/mcw]$ ansible -i mcw.py 10.0.0.13 -m ping -o
10.0.0.13 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
[root@mcw01 ~/mcw]$
inventory内置参数
指定ansible执行的python解释器
Ansible Ad-Hoc 命令
ansible命令的常用选项
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 SECONDS:后台运行超时时间
-C:测试一下会改变什么内容,不会真正去执行,主要用来测试一些可能发生的变化
-f FORKS,:设置ansible并行的任务数。默认值是5
*-i INVENTORY: 指定主机清单文件的路径,默认为/etc/ansible/hosts。
ansible-playbook -l 似乎剧本里面写了all ,-l后制定一个ip主机,那么只对这个ip主机做剧本里面的任务
执行命令
[root@mcw01 ~/mcw]$ ansible docker -m shell -a 'hostname' -o
10.0.0.13 | CHANGED | rc=0 | (stdout) mcw03
10.0.0.12 | CHANGED | rc=0 | (stdout) mcw02
10.0.0.11 | CHANGED | rc=0 | (stdout) mcw01
[root@mcw01 ~/mcw]$
添加并发参数,貌似默认就有5个并发
[root@mcw01 ~/mcw]$ ansible docker -m shell -a 'sleep 10;hostname' -f 5 -o
10.0.0.13 | CHANGED | rc=0 | (stdout) mcw03
10.0.0.12 | CHANGED | rc=0 | (stdout) mcw02
10.0.0.11 | CHANGED | rc=0 | (stdout) mcw01
[root@mcw01 ~/mcw]$
异步执行功能,-P 0会返回job_id,然后针对主机根据job_id查询执行结果
[root@mcw01 ~/mcw]$ ansible docker -B 120 -P 0 -m shell -a 'sleep 10;hostname' -f 5 -o
10.0.0.12 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "ansible_job_id": "639569984173.2219", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/639569984173.2219", "started": 1}
10.0.0.13 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "ansible_job_id": "484845210255.1938", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/484845210255.1938", "started": 1}
10.0.0.11 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "ansible_job_id": "536908581108.6669", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/536908581108.6669", "started": 1}
[root@mcw01 ~/mcw]$
根据对应主机,生成的job_id,通过async_status模块查看异步任务的状态和结果
[root@mcw01 ~/mcw]$ ansible 10.0.0.11 -m async_status -a 'jid=536908581108.6669' #上面最后一个
10.0.0.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"ansible_job_id": "536908581108.6669",
"changed": true,
"cmd": "sleep 10;hostname",
"delta": "0:00:10.011848",
"end": "2022-10-17 22:15:28.807455",
"finished": 1,
"rc": 0,
"start": "2022-10-17 22:15:18.795607",
"stderr": "",
"stderr_lines": [],
"stdout": "mcw01",
"stdout_lines": [
"mcw01"
]
}
[root@mcw01 ~/mcw]$
-P 参数大于0,会自动根据job_id去轮询查询执行结果
[root@mcw01 ~/mcw]$ ansible docker -B 120 -P 1 -m shell -a 'sleep 5;hostname' -f 5 -o
10.0.0.12 | CHANGED => {"ansible_job_id": "620511648163.2293", "changed": true, "cmd": "sleep 5;hostname", "delta": "0:00:05.010433", "end": "2022-10-17 22:19:35.792721", "finished": 1, "rc": 0, "start": "2022-10-17 22:19:30.782288", "stderr": "", "stderr_lines": [], "stdout": "mcw02", "stdout_lines": ["mcw02"]}
10.0.0.13 | CHANGED => {"ansible_job_id": "928152102107.2079", "changed": true, "cmd": "sleep 5;hostname", "delta": "0:00:05.030950", "end": "2022-10-17 22:19:35.837632", "finished": 1, "rc": 0, "start": "2022-10-17 22:19:30.806682", "stderr": "", "stderr_lines": [], "stdout": "mcw03", "stdout_lines": ["mcw03"]}
10.0.0.11 | CHANGED => {"ansible_job_id": "90920163368.7394", "changed": true, "cmd": "sleep 5;hostname", "delta": "0:00:05.016046", "end": "2022-10-17 22:19:35.775778", "finished": 1, "rc": 0, "start": "2022-10-17 22:19:30.759732", "stderr": "", "stderr_lines": [], "stdout": "mcw01", "stdout_lines": ["mcw01"]}
[root@mcw01 ~/mcw]$
复制文件
批量下发文件
[root@mcw01 ~/mcw]$ ansible docker -m copy -a 'src=mcw.py dest=/root/mcw.py owner=root group=root mode=644 backup=yes' -o
10.0.0.12 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "checksum": "43eda5c263b92f73f5d8a4372b1b3f45c22f6655", "dest": "/root/mcw.py", "gid": 0, "group": "root", "md5sum": "987dc3e139ff6e84af06de81f1916539", "mode": "0644", "owner": "root", "size": 715, "src": "/root/.ansible/tmp/ansible-tmp-1666016653.42-8131-100136329222525/source", "state": "file", "uid": 0}
10.0.0.13 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "checksum": "43eda5c263b92f73f5d8a4372b1b3f45c22f6655", "dest": "/root/mcw.py", "gid": 0, "group": "root", "md5sum": "987dc3e139ff6e84af06de81f1916539", "mode": "0644", "owner": "root", "size": 715, "src": "/root/.ansible/tmp/ansible-tmp-1666016653.44-8132-195324969036986/source", "state": "file", "uid": 0}
10.0.0.11 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "checksum": "43eda5c263b92f73f5d8a4372b1b3f45c22f6655", "dest": "/root/mcw.py", "gid": 0, "group": "root", "md5sum": "987dc3e139ff6e84af06de81f1916539", "mode": "0644", "owner": "root", "size": 715, "src": "/root/.ansible/tmp/ansible-tmp-1666016653.42-8129-164733943098808/source", "state": "file", "uid": 0}
[root@mcw01 ~/mcw]$
批量验证文件下发功能
[root@mcw01 ~/mcw]$ ansible docker -m shell -a 'md5sum /root/mcw.py' -o
10.0.0.12 | CHANGED | rc=0 | (stdout) 987dc3e139ff6e84af06de81f1916539 /root/mcw.py
10.0.0.13 | CHANGED | rc=0 | (stdout) 987dc3e139ff6e84af06de81f1916539 /root/mcw.py
10.0.0.11 | CHANGED | rc=0 | (stdout) 987dc3e139ff6e84af06de81f1916539 /root/mcw.py
[root@mcw01 ~/mcw]$
包和服务管理
安装包
[root@mcw01 ~/mcw]$ ansible docker -m yum -a 'name=httpd state=latest' -f 5 -o
10.0.0.11 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "changes": {"installed": ["httpd"], "updated": []}, "msg": "", "obsoletes": {"grub2": {"dist": "x86_64", "repo": "@anaconda", "version": "1:2.02-0.64.el7.centos"}, "grub2-tools": {"dist": "x86_64", "repo": "@anaconda", "version": "1:2.02-0.64.el7.centos"}, "iwl7265-firmware": {"dist": "noarch", "repo": "@anaconda", "version": "22.0.7.0-56.el7"}}, "rc": 0, "results": ["Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-97.el7.centos.5 will be installed\n--> Processing Dependency: httpd-tools = 2.4.6-97.el7.centos.5 for package: httpd-2.4.6-97.el7.centos.5.x86_64\n--> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-97.el7.centos.5.x86_64\n--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.6-97.el7.centos.5.x86_64\n--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.4.6-97.el7.centos.5.x86_64\n--> Running transaction check\n---> Package apr.x86_64 0:1.4.8-7.el7 will be installed\n---> Package apr-util.x86_64 0:1.5.2-6.el7 will be installed\n---> Package httpd-tools.x86_64 0:2.4.6-97.el7.centos.5 will be installed\n---> Package mailcap.noarch 0:2.1.41-2.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n httpd x86_64 2.4.6-97.el7.centos.5 updates 2.7 M\nInstalling for dependencies:\n apr x86_64 1.4.8-7.el7 base 104 k\n apr-util x86_64 1.5.2-6.el7 base 92 k\n httpd-tools x86_64 2.4.6-97.el7.centos.5 updates 94 k\n mailcap noarch 2.1.41-2.el7 base 31 k\n\nTransaction Summary\n================================================================================\nInstall 1 Package (+4 Dependent packages)\n\nTotal download size: 3.0 M\nInstalled size: 10 M\nDownloading packages:\n--------------------------------------------------------------------------------\nTotal 1.1 MB/s | 3.0 MB 00:02 \nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : apr-1.4.8-7.el7.x86_64 1/5 \n Installing : apr-util-1.5.2-6.el7.x86_64 2/5 \n Installing : httpd-tools-2.4.6-97.el7.centos.5.x86_64 3/5 \n Installing : mailcap-2.1.41-2.el7.noarch 4/5 \n Installing : httpd-2.4.6-97.el7.centos.5.x86_64 5/5 \n Verifying : apr-1.4.8-7.el7.x86_64 1/5 \n Verifying : mailcap-2.1.41-2.el7.noarch 2/5 \n Verifying : httpd-tools-2.4.6-97.el7.centos.5.x86_64 3/5 \n Verifying : apr-util-1.5.2-6.el7.x86_64 4/5 \n Verifying : httpd-2.4.6-97.el7.centos.5.x86_64 5/5 \n\nInstalled:\n httpd.x86_64 0:2.4.6-97.el7.centos.5 \n\nDependency Installed:\n apr.x86_64 0:1.4.8-7.el7 apr-util.x86_64 0:1.5.2-6.el7 \n httpd-tools.x86_64 0:2.4.6-97.el7.centos.5 mailcap.noarch 0:2.1.41-2.el7 \n\nComplete!\n"]}
10.0.0.12 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "changes": {"installed": ["httpd"], "updated": []}, "msg": "", "obsoletes": {"grub2": {"dist": "x86_64", "repo": "@anaconda", "version": "1:2.02-0.64.el7.centos"}, "grub2-tools": {"dist": "x86_64", "repo": "@anaconda", "version": "1:2.02-0.64.el7.centos"}, "iwl7265-firmware": {"dist": "noarch", "repo": "@anaconda", "version": "22.0.7.0-56.el7"}}, "rc": 0, "results": ["Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Ru
.........
启动服务,验证服务运行情况。
[root@mcw01 ~/mcw]$ ansible docker -m service -a 'name=httpd state=started' -f 5 -o
10.0.0.13 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "name": "httpd", "state": "started", "status": {"ActiveEnterTimestampMonotonic": "0", "ActiveExitTimestampMonotonic": "0", "ActiveState": "inactive", "After": "tmp.mount -.mount basic.target system.slice remote-fs.target systemd-journald.socket nss-lookup.target network.target", "AllowIsolate": "no", "AmbientCapabilities": "0", "AssertResult": "no", "AssertTimestampMonotonic": "0", "Before": "shutdown.target", "BlockIOAccounting": "no", "BlockIOWeight": "18446744073709551615", "CPUAccounting": "no", "CPUQuotaPerSecUSec": "infinity", "CPUSchedulingPolicy": "0", "CPUSchedulingPriority": "0", "CPUSchedulingResetOnFork": "no", "CPUShares": "18446744073709551615", "CanIsolate": "no", "CanReload": "yes", "CanStart": "yes", "CanStop": "yes", "CapabilityBoundingSet": "18446744073709551615", "ConditionResult": "no", "ConditionTimestampMonotonic": "0", "Conflicts": "shutdown.target", "ControlPID": "0", "DefaultDependencies": "yes", "Delegate": "no", "Description": "The Apache HTTP Server", "DevicePolicy": "auto", "Documentation": "man:httpd(8) man:apachectl(8)", "EnvironmentFile": "/etc/sysconfig/httpd (ignore_errors=no)", "ExecMainCode": "0", "ExecMainExitTimestampMonotonic": "0", "ExecMainPID": "0", "ExecMainStartTimestampMonotonic": "0", "ExecMainStatus": "0", "ExecReload": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -k graceful ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "ExecStart": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -DFOREGROUND ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "ExecStop": "{ path=/bin/kill ; argv[]=/bin/kill -WINCH ${MAINPID} ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "FailureAction": "none", "FileDescriptorStoreMax": "0", "FragmentPath": "/usr/lib/systemd/system/httpd.service", "GuessMainPID": "yes", "IOScheduling": "0", "Id": "httpd.service", "IgnoreOnIsolate": "no", "IgnoreOnSnapshot": "no", "IgnoreSIGPIPE": "yes", "InactiveEnterTimestampMonotonic": "0", "InactiveExitTimestampMonotonic": "0", "JobTimeoutAction": "none", "JobTimeoutUSec": "0", "KillMode": "control-group", "KillSignal": "18", "LimitAS": "18446744073709551615", "LimitCORE": "18446744073709551615", "LimitCPU": "18446744073709551615", "LimitDATA": "18446744073709551615", "LimitFSIZE": "18446744073709551615", "LimitLOCKS": "18446744073709551615", "LimitMEMLOCK": "65536", "LimitMSGQUEUE": "819200", "LimitNICE": "0", "LimitNOFILE": "4096", "LimitNPROC": "7206", "LimitRSS": "18446744073709551615", "LimitRTPRIO": "0", "LimitRTTIME": "18446744073709551615", "LimitSIGPENDING": "7206", "LimitSTACK": "18446744073709551615", "LoadState": "loaded", "MainPID": "0", "MemoryAccounting": "no", "MemoryCurrent": "18446744073709551615", "MemoryLimit": "18446744073709551615", "MountFlags": "0", "Names": "httpd.service", "NeedDaemonReload": "no", "Nice": "0", "NoNewPrivileges": "no", "NonBlocking": "no", "NotifyAccess": "main", "OOMScoreAdjust": "0", "OnFailureJobMode": "replace", "PermissionsStartOnly": "no", "PrivateDevices": "no", "PrivateNetwork": "no", "PrivateTmp": "yes", "ProtectHome": "no", "ProtectSystem": "no", "RefuseManualStart": "no", "RefuseManualStop": "no", "RemainAfterExit": "no", "Requires": "basic.target -.mount", "RequiresMountsFor": "/var/tmp", "Restart": "no", "RestartUSec": "100ms", "Result": "success", "RootDirectoryStartOnly": "no", "RuntimeDirectoryMode": "0755", "SameProcessGroup": "no", "SecureBits": "0", "SendSIGHUP": "no", "SendSIGKILL": "yes", "Slice": "system.slice", "StandardError": "inherit", "StandardInput": "null", "StandardOutput": "journal", "StartLimitAction": "none", "StartLimitBurst": "5", "StartLimitInterval": "10000000", "StartupBlockIOWeight": "18446744073709551615", "StartupCPUShares": "18446744073709551615", "StatusErrno": "0", "StopWhenUnneeded": "no", "SubState": "dead", "SyslogLevelPrefix": "yes", "SyslogPriority": "30", "SystemCallErrorNumber": "0", "TTYReset": "no", "TTYVHangup": "no", "TTYVTDisallocate": "no", "TasksAccounting": "no", "TasksCurrent": "18446744073709551615", "TasksMax": "18446744073709551615", "TimeoutStartUSec": "1min 30s", "TimeoutStopUSec": "1min 30s", "TimerSlackNSec": "50000", "Transient": "no", "Type": "notify", "UMask": "0022", "UnitFilePreset": "disabled", "UnitFileState": "disabled", "Wants": "system.slice", "WatchdogTimestampMonotonic": "0", "WatchdogUSec": "0"}}
10.0.0.12 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "name": "httpd", "state": "started", "status": {"ActiveEnterTimestampMonotonic": "0", "ActiveExitTimestampMonotonic": "0", "ActiveState": "inactive", "After": "systemd-journald.socket network.target remote-fs.target basic.target system.slice nss-lookup.target tmp.mount -.mount", "AllowIsolate": "no", "AmbientCapabilities": "0", "AssertResult": "no", "AssertTimestampMonotonic": "0", "Before": "shutdown.target", "BlockIOAccounting": "no", "BlockIOWeight": "18446744073709551615", "CPUAccounting": "no", "CPUQuotaPerSecUSec": "infinity", "CPUSchedulingPolicy": "0", "CPUSchedulingPriority": "0", "CPUSchedulingResetOnFork": "no", "CPUShares": "18446744073709551615", "CanIsolate": "no", "CanReload": "yes", "CanStart": "yes", "CanStop": "yes", "CapabilityBoundingSet": "18446744073709551615", "ConditionResult": "no", "ConditionTimestampMonotonic": "0", "Conflicts": "shutdown.target", "ControlPID": "0", "DefaultDependencies": "yes", "Delegate": "no", "Description": "The Apache HTTP Server", "DevicePolicy": "auto", "Documentation": "man:httpd(8) man:apachectl(8)", "EnvironmentFile": "/etc/sysconfig/httpd (ignore_errors=no)", "ExecMainCode": "0", "ExecMainExitTimestampMonotonic": "0", "ExecMainPID": "0", "ExecMainStartTimestampMonotonic": "0", "ExecMainStatus": "0", "ExecReload": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -k graceful ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "ExecStart": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -DFOREGROUND ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "ExecStop": "{ path=/bin/kill ; argv[]=/bin/kill -WINCH ${MAINPID} ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "FailureAction": "none", "FileDescriptorStoreMax": "0", "FragmentPath": "/usr/lib/systemd/system/httpd.service", "GuessMainPID": "yes", "IOScheduling": "0", "Id": "httpd.service", "IgnoreOnIsolate": "no", "IgnoreOnSnapshot": "no", "IgnoreSIGPIPE": "yes", "InactiveEnterTimestampMonotonic": "0", "InactiveExitTimestampMonotonic": "0", "JobTimeoutAction": "none", "JobTimeoutUSec": "0", "KillMode": "control-group", "KillSignal": "18", "LimitAS": "18446744073709551615", "LimitCORE": "18446744073709551615", "LimitCPU": "18446744073709551615", "LimitDATA": "18446744073709551615", "LimitFSIZE": "18446744073709551615", "LimitLOCKS": "18446744073709551615", "LimitMEMLOCK": "65536", "LimitMSGQUEUE": "819200", "LimitNICE": "0", "LimitNOFILE": "4096", "LimitNPROC": "7206", "LimitRSS": "18446744073709551615", "LimitRTPRIO": "0", "LimitRTTIME": "18446744073709551615", "LimitSIGPENDING": "7206", "LimitSTACK": "18446744073709551615", "LoadState": "loaded", "MainPID": "0", "MemoryAccounting": "no", "MemoryCurrent": "18446744073709551615", "MemoryLimit": "18446744073709551615", "MountFlags": "0", "Names": "httpd.service", "NeedDaemonReload": "no", "Nice": "0", "NoNewPrivileges": "no", "NonBlocking": "no", "NotifyAccess": "main", "OOMScoreAdjust": "0", "OnFailureJobMode": "replace", "PermissionsStartOnly": "no", "PrivateDevices": "no", "PrivateNetwork": "no", "PrivateTmp": "yes", "ProtectHome": "no", "ProtectSystem": "no", "RefuseManualStart": "no", "RefuseManualStop": "no", "RemainAfterExit": "no", "Requires": "basic.target -.mount", "RequiresMountsFor": "/var/tmp", "Restart": "no", "RestartUSec": "100ms", "Result": "success", "RootDirectoryStartOnly": "no", "RuntimeDirectoryMode": "0755", "SameProcessGroup": "no", "SecureBits": "0", "SendSIGHUP": "no", "SendSIGKILL": "yes", "Slice": "system.slice", "StandardError": "inherit", "StandardInput": "null", "StandardOutput": "journal", "StartLimitAction": "none", "StartLimitBurst": "5", "StartLimitInterval": "10000000", "StartupBlockIOWeight": "18446744073709551615", "StartupCPUShares": "18446744073709551615", "StatusErrno": "0", "StopWhenUnneeded": "no", "SubState": "dead", "SyslogLevelPrefix": "yes", "SyslogPriority": "30", "SystemCallErrorNumber": "0", "TTYReset": "no", "TTYVHangup": "no", "TTYVTDisallocate": "no", "TasksAccounting": "no", "TasksCurrent": "18446744073709551615", "TasksMax": "18446744073709551615", "TimeoutStartUSec": "1min 30s", "TimeoutStopUSec": "1min 30s", "TimerSlackNSec": "50000", "Transient": "no", "Type": "notify", "UMask": "0022", "UnitFilePreset": "disabled", "UnitFileState": "disabled", "Wants": "system.slice", "WatchdogTimestampMonotonic": "0", "WatchdogUSec": "0"}}
10.0.0.11 | FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "msg": "Unable to start service httpd: Job for httpd.service failed because the control process exited with error code. See \"systemctl status httpd.service\" and \"journalctl -xe\" for details.\n"}
[root@mcw01 ~/mcw]$ systemctl status httpd.service
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Mon 2022-10-17 22:34:49 CST; 54s ago
Docs: man:httpd(8)
man:apachectl(8)
Process: 10043 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=1/FAILURE)
Process: 10041 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
Main PID: 10041 (code=exited, status=1/FAILURE) Oct 17 22:34:49 mcw01 httpd[10041]: (98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
Oct 17 22:34:49 mcw01 httpd[10041]: (98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80
Oct 17 22:34:49 mcw01 httpd[10041]: no listening sockets available, shutting down
Oct 17 22:34:49 mcw01 httpd[10041]: AH00015: Unable to open logs
Oct 17 22:34:49 mcw01 systemd[1]: httpd.service: main process exited, code=exited, status=1/FAILURE
Oct 17 22:34:49 mcw01 kill[10043]: kill: cannot find process ""
Oct 17 22:34:49 mcw01 systemd[1]: httpd.service: control process exited, code=exited status=1
Oct 17 22:34:49 mcw01 systemd[1]: Failed to start The Apache HTTP Server.
Oct 17 22:34:49 mcw01 systemd[1]: Unit httpd.service entered failed state.
Oct 17 22:34:49 mcw01 systemd[1]: httpd.service failed.
[root@mcw01 ~/mcw]$
用户管理
用openssl对密码加密。每次执行生成的不一样。这里是-1,是数字,不是英文l。
[root@mcw01 ~/mcw]$ echo ansible | openssl passwd -1 -stdin
$1$FcSSjfiL$pUtrs8BMzsnnODj/.bEru.
[root@mcw01 ~/mcw]$ echo ansible | openssl passwd -1 -stdin
$1$KSriNFoA$LwK8/pyHxja.8NPGRYUG00
[root@mcw01 ~/mcw]$ echo ansible | openssl passwd -1 -stdin
$1$hEDDgbqP$sNpyypRRWNbcg1VTQuCW6/
[root@mcw01 ~/mcw]$
批量创建用户
[root@mcw01 ~/mcw]$ ansible docker -m user -a 'name=xiaomaguohe password="$1$hEDDgbqP$sNpyypRRWNbcg1VTQuCW6/"' -f 5 -o
10.0.0.12 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "comment": "", "create_home": true, "group": 1001, "home": "/home/xiaomaguohe", "name": "xiaomaguohe", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/bash", "state": "present", "system": false, "uid": 1001}
10.0.0.13 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "comment": "", "create_home": true, "group": 1001, "home": "/home/xiaomaguohe", "name": "xiaomaguohe", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/bash", "state": "present", "system": false, "uid": 1001}
10.0.0.11 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "comment": "", "create_home": true, "group": 1001, "home": "/home/xiaomaguohe", "name": "xiaomaguohe", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/bash", "state": "present", "system": false, "uid": 1001}
[root@mcw01 ~/mcw]$
验证登录成功,用ansible这个密码。
[root@mcw01 ~/mcw]$ su - xiaomaguohe
[xiaomaguohe@mcw01 ~]$ logout
[root@mcw01 ~/mcw]$ ssh 10.0.0.13 -l xiaomaguohe
xiaomaguohe@10.0.0.13's password:
Permission denied, please try again.
xiaomaguohe@10.0.0.13's password:
Permission denied, please try again.
xiaomaguohe@10.0.0.13's password:
Last failed login: Mon Oct 17 22:43:29 CST 2022 from 10.0.0.11 on ssh:notty
There were 2 failed login attempts since the last successful login.
[xiaomaguohe@mcw03 ~]$
Ansible facts
facts所有信息
[root@mcw01 ~/mcw]$ ansible 10.0.0.13 -m setup
10.0.0.13 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"10.0.0.13",
"172.16.0.13"
],
"ansible_all_ipv6_addresses": [
"fe80::6782:98:f742:b0e8",
"fe80::6faf:5935:98b1:7f8d",
"fe80::cdd:d005:758:ad29",
"fe80::d4fb:80c5:2bc7:80e9"
],
"ansible_apparmor": {
"status": "disabled"
},
"ansible_architecture": "x86_64",
"ansible_bios_date": "07/02/2015",
"ansible_bios_version": "6.00",
"ansible_cmdline": {
"BOOT_IMAGE": "/vmlinuz-3.10.0-693.el7.x86_64",
"LANG": "en_US.UTF-8",
"crashkernel": "auto",
"quiet": true,
"rd.lvm.lv": "centos/swap",
"rhgb": true,
"ro": true,
"root": "/dev/mapper/centos-root"
},
"ansible_date_time": {
[root@mcw01 ~/mcw]$ ansible 10.0.0.13 -m setup
10.0.0.13 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"10.0.0.13",
"172.16.0.13"
],
"ansible_all_ipv6_addresses": [
"fe80::6782:98:f742:b0e8",
"fe80::6faf:5935:98b1:7f8d",
"fe80::cdd:d005:758:ad29",
"fe80::d4fb:80c5:2bc7:80e9"
],
"ansible_apparmor": {
"status": "disabled"
},
"ansible_architecture": "x86_64",
"ansible_bios_date": "07/02/2015",
"ansible_bios_version": "6.00",
"ansible_cmdline": {
"BOOT_IMAGE": "/vmlinuz-3.10.0-693.el7.x86_64",
"LANG": "en_US.UTF-8",
"crashkernel": "auto",
"quiet": true,
"rd.lvm.lv": "centos/swap",
"rhgb": true,
"ro": true,
"root": "/dev/mapper/centos-root"
},
"ansible_date_time": {
"date": "2022-10-17",
"day": "17",
"epoch": "1666017976",
"hour": "22",
"iso8601": "2022-10-17T14:46:16Z",
"iso8601_basic": "20221017T224616026674",
"iso8601_basic_short": "20221017T224616",
"iso8601_micro": "2022-10-17T14:46:16.026674Z",
"minute": "46",
"month": "10",
"second": "16",
"time": "22:46:16",
"tz": "CST",
"tz_offset": "+0800",
"weekday": "Monday",
"weekday_number": "1",
"weeknumber": "42",
"year": "2022"
},
"ansible_default_ipv4": {
"address": "10.0.0.13",
"alias": "ens33",
"broadcast": "10.0.0.255",
"gateway": "10.0.0.253",
"interface": "ens33",
"macaddress": "00:0c:29:3b:e7:8f",
"mtu": 1500,
"netmask": "255.255.255.0",
"network": "10.0.0.0",
"type": "ether"
},
"ansible_default_ipv6": {},
"ansible_device_links": {
"ids": {
"dm-0": [
"dm-name-centos-root",
"dm-uuid-LVM-dPgwZzREeFU4XPCeqlcpP8lN2yoWi5UR0ZmzJBkIPuFo9MclDJ2EFsWc9dsEkMKU"
],
"dm-1": [
"dm-name-centos-swap",
"dm-uuid-LVM-dPgwZzREeFU4XPCeqlcpP8lN2yoWi5URvkvhq0DHBdCqWbyactVt1ViDOksA632r"
],
"sda2": [
"lvm-pv-uuid-tXyMIX-7OPp-Sz1l-2m6Z-9aWg-1NHr-j1w32L"
],
"sr0": [
"ata-VMware_Virtual_IDE_CDROM_Drive_10000000000000000001"
]
},
"labels": {
"sr0": [
"CentOS\\x207\\x20x86_64"
]
},
"masters": {
"sda2": [
"dm-0",
"dm-1"
]
},
"uuids": {
"dm-0": [
"fdafc50d-fb7e-4d66-a450-300c4ac8956c"
],
"dm-1": [
"2707bb63-44e7-4aa9-81e8-d7f2d5b9686f"
],
"sda1": [
"6838ae3d-d71e-48b2-809b-d39f412c0b41"
],
"sr0": [
"2017-09-06-10-51-00-00"
]
}
},
"ansible_devices": {
"dm-0": {
"holders": [],
"host": "",
"links": {
"ids": [
"dm-name-centos-root",
"dm-uuid-LVM-dPgwZzREeFU4XPCeqlcpP8lN2yoWi5UR0ZmzJBkIPuFo9MclDJ2EFsWc9dsEkMKU"
],
"labels": [],
"masters": [],
"uuids": [
"fdafc50d-fb7e-4d66-a450-300c4ac8956c"
]
},
"model": null,
"partitions": {},
"removable": "0",
"rotational": "1",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "",
"sectors": "38658048",
"sectorsize": "512",
"size": "18.43 GB",
"support_discard": "0",
"vendor": null,
"virtual": 1
},
"dm-1": {
"holders": [],
"host": "",
"links": {
"ids": [
"dm-name-centos-swap",
"dm-uuid-LVM-dPgwZzREeFU4XPCeqlcpP8lN2yoWi5URvkvhq0DHBdCqWbyactVt1ViDOksA632r"
],
"labels": [],
"masters": [],
"uuids": [
"2707bb63-44e7-4aa9-81e8-d7f2d5b9686f"
]
},
"model": null,
"partitions": {},
"removable": "0",
"rotational": "1",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "",
"sectors": "1638400",
"sectorsize": "512",
"size": "800.00 MB",
"support_discard": "0",
"vendor": null,
"virtual": 1
},
"sda": {
"holders": [],
"host": "SCSI storage controller: LSI Logic / Symbios Logic 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (rev 01)",
"links": {
"ids": [],
"labels": [],
"masters": [],
"uuids": []
},
"model": "VMware Virtual S",
"partitions": {
"sda1": {
"holders": [],
"links": {
"ids": [],
"labels": [],
"masters": [],
"uuids": [
"6838ae3d-d71e-48b2-809b-d39f412c0b41"
]
},
"sectors": "1638400",
"sectorsize": 512,
"size": "800.00 MB",
"start": "2048",
"uuid": "6838ae3d-d71e-48b2-809b-d39f412c0b41"
},
"sda2": {
"holders": [
"centos-root",
"centos-swap"
],
"links": {
"ids": [
"lvm-pv-uuid-tXyMIX-7OPp-Sz1l-2m6Z-9aWg-1NHr-j1w32L"
],
"labels": [],
"masters": [
"dm-0",
"dm-1"
],
"uuids": []
},
"sectors": "40302592",
"sectorsize": 512,
"size": "19.22 GB",
"start": "1640448",
"uuid": null
}
},
"removable": "0",
"rotational": "1",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "deadline",
"sectors": "41943040",
"sectorsize": "512",
"size": "20.00 GB",
"support_discard": "0",
"vendor": "VMware,",
"virtual": 1
},
"sr0": {
"holders": [],
"host": "IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)",
"links": {
"ids": [
"ata-VMware_Virtual_IDE_CDROM_Drive_10000000000000000001"
],
"labels": [
"CentOS\\x207\\x20x86_64"
],
"masters": [],
"uuids": [
"2017-09-06-10-51-00-00"
]
},
"model": "VMware IDE CDR10",
"partitions": {},
"removable": "1",
"rotational": "1",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "cfq",
"sectors": "8830976",
"sectorsize": "2048",
"size": "4.21 GB",
"support_discard": "0",
"vendor": "NECVMWar",
"virtual": 1
}
},
"ansible_distribution": "CentOS",
"ansible_distribution_file_parsed": true,
"ansible_distribution_file_path": "/etc/redhat-release",
"ansible_distribution_file_variety": "RedHat",
"ansible_distribution_major_version": "7",
"ansible_distribution_release": "Core",
"ansible_distribution_version": "7.4",
"ansible_dns": {
"nameservers": [
"223.5.5.5"
]
},
"ansible_domain": "",
"ansible_effective_group_id": 0,
"ansible_effective_user_id": 0,
"ansible_ens33": {
"active": true,
"device": "ens33",
"features": {
"busy_poll": "off [fixed]",
"fcoe_mtu": "off [fixed]",
"generic_receive_offload": "on",
"generic_segmentation_offload": "on",
"highdma": "off [fixed]",
"hw_tc_offload": "off [fixed]",
"l2_fwd_offload": "off [fixed]",
"large_receive_offload": "off [fixed]",
"loopback": "off [fixed]",
"netns_local": "off [fixed]",
"ntuple_filters": "off [fixed]",
"receive_hashing": "off [fixed]",
"rx_all": "off",
"rx_checksumming": "off",
"rx_fcs": "off",
"rx_vlan_filter": "on [fixed]",
"rx_vlan_offload": "on",
"rx_vlan_stag_filter": "off [fixed]",
"rx_vlan_stag_hw_parse": "off [fixed]",
"scatter_gather": "on",
"tcp_segmentation_offload": "on",
"tx_checksum_fcoe_crc": "off [fixed]",
"tx_checksum_ip_generic": "on",
"tx_checksum_ipv4": "off [fixed]",
"tx_checksum_ipv6": "off [fixed]",
"tx_checksum_sctp": "off [fixed]",
"tx_checksumming": "on",
"tx_fcoe_segmentation": "off [fixed]",
"tx_gre_csum_segmentation": "off [fixed]",
"tx_gre_segmentation": "off [fixed]",
"tx_gso_partial": "off [fixed]",
"tx_gso_robust": "off [fixed]",
"tx_ipip_segmentation": "off [fixed]",
"tx_lockless": "off [fixed]",
"tx_mpls_segmentation": "off [fixed]",
"tx_nocache_copy": "off",
"tx_scatter_gather": "on",
"tx_scatter_gather_fraglist": "off [fixed]",
"tx_sctp_segmentation": "off [fixed]",
"tx_sit_segmentation": "off [fixed]",
"tx_tcp6_segmentation": "off [fixed]",
"tx_tcp_ecn_segmentation": "off [fixed]",
"tx_tcp_mangleid_segmentation": "off",
"tx_tcp_segmentation": "on",
"tx_udp_tnl_csum_segmentation": "off [fixed]",
"tx_udp_tnl_segmentation": "off [fixed]",
"tx_vlan_offload": "on [fixed]",
"tx_vlan_stag_hw_insert": "off [fixed]",
"udp_fragmentation_offload": "off [fixed]",
"vlan_challenged": "off [fixed]"
},
"hw_timestamp_filters": [],
"ipv4": {
"address": "10.0.0.13",
"broadcast": "10.0.0.255",
"netmask": "255.255.255.0",
"network": "10.0.0.0"
},
"ipv6": [
{
"address": "fe80::6782:98:f742:b0e8",
"prefix": "64",
"scope": "link"
},
{
"address": "fe80::6faf:5935:98b1:7f8d",
"prefix": "64",
"scope": "link"
},
{
"address": "fe80::cdd:d005:758:ad29",
"prefix": "64",
"scope": "link"
}
],
"macaddress": "00:0c:29:3b:e7:8f",
"module": "e1000",
"mtu": 1500,
"pciid": "0000:02:01.0",
"promisc": false,
"speed": 1000,
"timestamping": [
"tx_software",
"rx_software",
"software"
],
"type": "ether"
},
"ansible_ens34": {
"active": true,
"device": "ens34",
"features": {
"busy_poll": "off [fixed]",
"fcoe_mtu": "off [fixed]",
"generic_receive_offload": "on",
"generic_segmentation_offload": "off [requested on]",
"highdma": "off [fixed]",
"hw_tc_offload": "off [fixed]",
"l2_fwd_offload": "off [fixed]",
"large_receive_offload": "off [fixed]",
"loopback": "off [fixed]",
"netns_local": "off [fixed]",
"ntuple_filters": "off [fixed]",
"receive_hashing": "off [fixed]",
"rx_all": "off [fixed]",
"rx_checksumming": "off [fixed]",
"rx_fcs": "off [fixed]",
"rx_vlan_filter": "off [fixed]",
"rx_vlan_offload": "off [fixed]",
"rx_vlan_stag_filter": "off [fixed]",
"rx_vlan_stag_hw_parse": "off [fixed]",
"scatter_gather": "off",
"tcp_segmentation_offload": "off",
"tx_checksum_fcoe_crc": "off [fixed]",
"tx_checksum_ip_generic": "off [fixed]",
"tx_checksum_ipv4": "off [fixed]",
"tx_checksum_ipv6": "off [fixed]",
"tx_checksum_sctp": "off [fixed]",
"tx_checksumming": "off",
"tx_fcoe_segmentation": "off [fixed]",
"tx_gre_csum_segmentation": "off [fixed]",
"tx_gre_segmentation": "off [fixed]",
"tx_gso_partial": "off [fixed]",
"tx_gso_robust": "off [fixed]",
"tx_ipip_segmentation": "off [fixed]",
"tx_lockless": "off [fixed]",
"tx_mpls_segmentation": "off [fixed]",
"tx_nocache_copy": "off",
"tx_scatter_gather": "off [fixed]",
"tx_scatter_gather_fraglist": "off [fixed]",
"tx_sctp_segmentation": "off [fixed]",
"tx_sit_segmentation": "off [fixed]",
"tx_tcp6_segmentation": "off [fixed]",
"tx_tcp_ecn_segmentation": "off [fixed]",
"tx_tcp_mangleid_segmentation": "off [fixed]",
"tx_tcp_segmentation": "off [fixed]",
"tx_udp_tnl_csum_segmentation": "off [fixed]",
"tx_udp_tnl_segmentation": "off [fixed]",
"tx_vlan_offload": "off [fixed]",
"tx_vlan_stag_hw_insert": "off [fixed]",
"udp_fragmentation_offload": "off [fixed]",
"vlan_challenged": "off [fixed]"
},
"hw_timestamp_filters": [],
"ipv4": {
"address": "172.16.0.13",
"broadcast": "172.16.0.255",
"netmask": "255.255.255.0",
"network": "172.16.0.0"
},
"ipv6": [
{
"address": "fe80::d4fb:80c5:2bc7:80e9",
"prefix": "64",
"scope": "link"
}
],
"macaddress": "00:0c:29:3b:e7:99",
"module": "pcnet32",
"mtu": 1500,
"pciid": "0000:02:02.0",
"promisc": false,
"timestamping": [
"rx_software",
"software"
],
"type": "ether"
},
"ansible_env": {
"HOME": "/root",
"LANG": "en_US.UTF-8",
"LESSOPEN": "||/usr/bin/lesspipe.sh %s",
"LOGNAME": "root",
"LS_COLORS": "rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:",
"MAIL": "/var/mail/root",
"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin",
"PWD": "/root",
"SHELL": "/bin/bash",
"SHLVL": "2",
"SSH_CLIENT": "10.0.0.11 16479 22",
"SSH_CONNECTION": "10.0.0.11 16479 10.0.0.13 22",
"SSH_TTY": "/dev/pts/1",
"TERM": "xterm",
"USER": "root",
"XDG_RUNTIME_DIR": "/run/user/0",
"XDG_SESSION_ID": "15",
"_": "/usr/bin/python"
},
"ansible_fibre_channel_wwn": [],
"ansible_fips": false,
"ansible_form_factor": "Other",
"ansible_fqdn": "mcw03",
"ansible_hostname": "mcw03",
"ansible_hostnqn": "",
"ansible_interfaces": [
"ens34",
"lo",
"ens33"
],
"ansible_is_chroot": false,
"ansible_iscsi_iqn": "",
"ansible_kernel": "3.10.0-693.el7.x86_64",
"ansible_kernel_version": "#1 SMP Tue Aug 22 21:09:27 UTC 2017",
"ansible_lo": {
"active": true,
"device": "lo",
"features": {
"busy_poll": "off [fixed]",
"fcoe_mtu": "off [fixed]",
"generic_receive_offload": "on",
"generic_segmentation_offload": "on",
"highdma": "on [fixed]",
"hw_tc_offload": "off [fixed]",
"l2_fwd_offload": "off [fixed]",
"large_receive_offload": "off [fixed]",
"loopback": "on [fixed]",
"netns_local": "on [fixed]",
"ntuple_filters": "off [fixed]",
"receive_hashing": "off [fixed]",
"rx_all": "off [fixed]",
"rx_checksumming": "on [fixed]",
"rx_fcs": "off [fixed]",
"rx_vlan_filter": "off [fixed]",
"rx_vlan_offload": "off [fixed]",
"rx_vlan_stag_filter": "off [fixed]",
"rx_vlan_stag_hw_parse": "off [fixed]",
"scatter_gather": "on",
"tcp_segmentation_offload": "on",
"tx_checksum_fcoe_crc": "off [fixed]",
"tx_checksum_ip_generic": "on [fixed]",
"tx_checksum_ipv4": "off [fixed]",
"tx_checksum_ipv6": "off [fixed]",
"tx_checksum_sctp": "on [fixed]",
"tx_checksumming": "on",
"tx_fcoe_segmentation": "off [fixed]",
"tx_gre_csum_segmentation": "off [fixed]",
"tx_gre_segmentation": "off [fixed]",
"tx_gso_partial": "off [fixed]",
"tx_gso_robust": "off [fixed]",
"tx_ipip_segmentation": "off [fixed]",
"tx_lockless": "on [fixed]",
"tx_mpls_segmentation": "off [fixed]",
"tx_nocache_copy": "off [fixed]",
"tx_scatter_gather": "on [fixed]",
"tx_scatter_gather_fraglist": "on [fixed]",
"tx_sctp_segmentation": "on",
"tx_sit_segmentation": "off [fixed]",
"tx_tcp6_segmentation": "on",
"tx_tcp_ecn_segmentation": "on",
"tx_tcp_mangleid_segmentation": "on",
"tx_tcp_segmentation": "on",
"tx_udp_tnl_csum_segmentation": "off [fixed]",
"tx_udp_tnl_segmentation": "off [fixed]",
"tx_vlan_offload": "off [fixed]",
"tx_vlan_stag_hw_insert": "off [fixed]",
"udp_fragmentation_offload": "on",
"vlan_challenged": "on [fixed]"
},
"hw_timestamp_filters": [],
"ipv4": {
"address": "127.0.0.1",
"broadcast": "",
"netmask": "255.0.0.0",
"network": "127.0.0.0"
},
"ipv6": [
{
"address": "::1",
"prefix": "128",
"scope": "host"
}
],
"mtu": 65536,
"promisc": false,
"timestamping": [
"rx_software",
"software"
],
"type": "loopback"
},
"ansible_local": {},
"ansible_lsb": {},
"ansible_lvm": {
"lvs": {
"root": {
"size_g": "18.43",
"vg": "centos"
},
"swap": {
"size_g": "0.78",
"vg": "centos"
}
},
"pvs": {
"/dev/sda2": {
"free_g": "0",
"size_g": "19.21",
"vg": "centos"
}
},
"vgs": {
"centos": {
"free_g": "0",
"num_lvs": "2",
"num_pvs": "1",
"size_g": "19.21"
}
}
},
"ansible_machine": "x86_64",
"ansible_machine_id": "9c116b87e41d4108aa3772cb45766f57",
"ansible_memfree_mb": 1275,
"ansible_memory_mb": {
"nocache": {
"free": 1650,
"used": 173
},
"real": {
"free": 1275,
"total": 1823,
"used": 548
},
"swap": {
"cached": 0,
"free": 799,
"total": 799,
"used": 0
}
},
"ansible_memtotal_mb": 1823,
"ansible_mounts": [
{
"block_available": 167483,
"block_size": 4096,
"block_total": 203945,
"block_used": 36462,
"device": "/dev/sda1",
"fstype": "xfs",
"inode_available": 409272,
"inode_total": 409600,
"inode_used": 328,
"mount": "/boot",
"options": "rw,relatime,attr2,inode64,noquota",
"size_available": 686010368,
"size_total": 835358720,
"uuid": "6838ae3d-d71e-48b2-809b-d39f412c0b41"
},
{
"block_available": 4040310,
"block_size": 4096,
"block_total": 4829696,
"block_used": 789386,
"device": "/dev/mapper/centos-root",
"fstype": "xfs",
"inode_available": 9631409,
"inode_total": 9664512,
"inode_used": 33103,
"mount": "/",
"options": "rw,relatime,attr2,inode64,noquota",
"size_available": 16549109760,
"size_total": 19782434816,
"uuid": "fdafc50d-fb7e-4d66-a450-300c4ac8956c"
}
],
"ansible_nodename": "mcw03",
"ansible_os_family": "RedHat",
"ansible_pkg_mgr": "yum",
"ansible_proc_cmdline": {
"BOOT_IMAGE": "/vmlinuz-3.10.0-693.el7.x86_64",
"LANG": "en_US.UTF-8",
"crashkernel": "auto",
"quiet": true,
"rd.lvm.lv": [
"centos/root",
"centos/swap"
],
"rhgb": true,
"ro": true,
"root": "/dev/mapper/centos-root"
},
"ansible_processor": [
"0",
"GenuineIntel",
"Intel(R) Core(TM) i5-3230M CPU @ 2.60GHz"
],
"ansible_processor_cores": 1,
"ansible_processor_count": 1,
"ansible_processor_threads_per_core": 1,
"ansible_processor_vcpus": 1,
"ansible_product_name": "VMware Virtual Platform",
"ansible_product_serial": "VMware-56 4d 73 0d c4 f8 d6 8e-49 9a aa d0 4b 3b e7 8f",
"ansible_product_uuid": "0D734D56-F8C4-8ED6-499A-AAD04B3BE78F",
"ansible_product_version": "None",
"ansible_python": {
"executable": "/usr/bin/python",
"has_sslcontext": true,
"type": "CPython",
"version": {
"major": 2,
"micro": 5,
"minor": 7,
"releaselevel": "final",
"serial": 0
},
"version_info": [
2,
7,
5,
"final",
0
]
},
"ansible_python_version": "2.7.5",
"ansible_real_group_id": 0,
"ansible_real_user_id": 0,
"ansible_selinux": {
"status": "disabled"
},
"ansible_selinux_python_present": true,
"ansible_service_mgr": "systemd",
"ansible_ssh_host_key_ecdsa_public": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGyISYkhvbLT8t+3cPzqR90VU2jZ86IhYoLxgDCECSQiVFwxi017qOfcIjxacb6/i/K6PEo9kSEcAIIPzqVwk5I=",
"ansible_ssh_host_key_ed25519_public": "AAAAC3NzaC1lZDI1NTE5AAAAICoAiTwDt4QEjQ4OvpXI4MG6bsyeePHoZPDD+wt0RR9F",
"ansible_ssh_host_key_rsa_public": "AAAAB3NzaC1yc2EAAAADAQABAAABAQC8Cz0BUtBytTrJP25idcQLh0Q2DG7opqrIshMhGRc/sbwZOqe2kmFv3EEedHK5Flz2LOtxMURGRioGfgkobGeFUgfs+qCXhF4JHTno8bDQMpcS3shr4kRWl0jVvRqcka7Aq7b3zokGpJmJ8lXSZnTDhsliQPG7fyYSn1nORQdbRbQ5uVXvKYFDPn5rTWBu1lRz/8z5xGQU2ejLVj6f1QGNCWgxYVj7jd8LW81jg8zQ5aZH+GjlMuZGVBW225eWsIlOvHs/8gQzOtansD7PUk1klivueby8/KyTVBkrxGkTIKbKSv9b8U9742dsq1zAsyJ0Ij6Ney4RqlDG7B49BfFf",
"ansible_swapfree_mb": 799,
"ansible_swaptotal_mb": 799,
"ansible_system": "Linux",
"ansible_system_capabilities": [
"cap_chown",
"cap_dac_override",
"cap_dac_read_search",
"cap_fowner",
"cap_fsetid",
"cap_kill",
"cap_setgid",
"cap_setuid",
"cap_setpcap",
"cap_linux_immutable",
"cap_net_bind_service",
"cap_net_broadcast",
"cap_net_admin",
"cap_net_raw",
"cap_ipc_lock",
"cap_ipc_owner",
"cap_sys_module",
"cap_sys_rawio",
"cap_sys_chroot",
"cap_sys_ptrace",
"cap_sys_pacct",
"cap_sys_admin",
"cap_sys_boot",
"cap_sys_nice",
"cap_sys_resource",
"cap_sys_time",
"cap_sys_tty_config",
"cap_mknod",
"cap_lease",
"cap_audit_write",
"cap_audit_control",
"cap_setfcap",
"cap_mac_override",
"cap_mac_admin",
"cap_syslog",
"35",
"36+ep"
],
"ansible_system_capabilities_enforced": "True",
"ansible_system_vendor": "VMware, Inc.",
"ansible_uptime_seconds": 3384,
"ansible_user_dir": "/root",
"ansible_user_gecos": "root",
"ansible_user_gid": 0,
"ansible_user_id": "root",
"ansible_user_shell": "/bin/bash",
"ansible_user_uid": 0,
"ansible_userspace_architecture": "x86_64",
"ansible_userspace_bits": "64",
"ansible_virtualization_role": "guest",
"ansible_virtualization_type": "VMware",
"discovered_interpreter_python": "/usr/bin/python",
"gather_subset": [
"all"
],
"module_setup": true
},
"changed": false
}
[root@mcw01 ~/mcw]$
全部返回结果
facts查看指定信息
[root@mcw01 ~/mcw]$ ansible 10.0.0.13 -m setup -a 'filter=ansible_all_ipv4_addresses'
10.0.0.13 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"10.0.0.13",
"172.16.0.13"
],
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
[root@mcw01 ~/mcw]$
使用facter扩展facts信息,使用ohai扩展facts信息
Ansible role 以Nginx为案例
查看目录结构
[root@mcw01 ~/mcw]$ tree
.
├── roles
│ └── nginx
│ ├── files
│ │ └── index.html
│ ├── handlers
│ │ └── main.yaml
│ ├── tasks
│ │ └── main.yaml
│ ├── templates
│ │ └── nginx.conf.j2
│ └── vars
│ └── main.yaml
└── site.yaml 7 directories, 6 files
[root@mcw01 ~/mcw]$
查看文件内容,下面的是有错误的
[root@mcw01 ~/mcw]$ cat site.yaml
- hosts: 10.0.0.12
roles:
- { role: nginx ,version: 1.0.15}
[root@mcw01 ~/mcw]$ cat roles/nginx/tasks/main.yaml
- name: Install nginx package
yum: name=nginx-{{ version }} state=present
- name: Copy nginx.conf Template
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf owner=root group=root backup=yes mode=0644
notify: restart nginx
- name: Copy index html
copy: src=index.html dest=/usr/share/nginx/html/index.html owner=root group=root backup=yes mode=0644
- name: make sure nginx service running
service: name=nginx state=started
[root@mcw01 ~/mcw]$ cat roles/nginx/handlers/main.yaml
- name: restart nginx
service: name=nginx state=restarted
[root@mcw01 ~/mcw]$ cat roles/nginx/templates/nginx.conf.j2 |grep '\{{'
worker_processes {{ ansible_processor_cores }};
[root@mcw01 ~/mcw]$ cat roles/nginx/files/index.html
hello mcw
[root@mcw01 ~/mcw]$ cat roles/nginx/templates/nginx.conf.j2
user nginx;
worker_processes {{ ansible_processor_cores }};
error_log /var/log/nginx/error.log;
pid /run/nginx.pid; include /usr/share/nginx/modules/*.conf; events {
worker_connections 1024;
} http {
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 /var/log/nginx/access.log main; sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096; include /etc/nginx/mime.types;
default_type application/octet-stream; include /etc/nginx/conf.d/*.conf; server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html; # Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf; error_page 404 /404.html;
location = /404.html {
} error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
} }
[root@mcw01 ~/mcw]$
查看主机2是没有安装Nginx的
[root@mcw02 ~]$ rpm -qa|grep nginx
[root@mcw02 ~]$
错误:
直接是-hosts是不行的,前面得加个- name起个名字
[root@mcw01 ~/mcw]$ cat site.yaml
- hosts: 10.0.0.12
remote_user: root
roles:
- { role: nginx, version: 1.0.15 }
[root@mcw01 ~/mcw]$ ansible-playbook site.yaml --syntax-check
[WARNING]: Unable to parse /root/mcw/inventory as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: No JSON object could be decoded Syntax Error while loading YAML.
mapping values are not allowed in this context The error appears to be in '/root/mcw/site.yaml': line 2, column 16, but may
be elsewhere in the file depending on the exact syntax problem. The offending line appears to be: - hosts: 10.0.0.12
remote_user: root
^ here
起个名字之后报错变了:变成其它问题了
[root@mcw01 ~/mcw]$ cat site.yaml
- name: install nginx
hosts: 10.0.0.12
roles:
- { role: nginx ,version: 1.0.15}
[root@mcw01 ~/mcw]$ ansible-playbook site.yaml
[WARNING]: Unable to parse /root/mcw/inventory as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: No JSON object could be decoded Syntax Error while loading YAML.
mapping values are not allowed in this context The error appears to be in '/root/mcw/roles/nginx/tasks/main.yaml': line 2, column 8, but may
be elsewhere in the file depending on the exact syntax problem. The offending line appears to be: - name: Install nginx package
yum: name=nginx-{{ version }} state=present
^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance: with_items:
- {{ foo }} Should be written as: with_items:
- "{{ foo }}"
[root@mcw01 ~/mcw]$
多了两个空格都不行。- 空格 name:,下面的模块跟-只差两个字符的距离,空格多了就报错
[root@mcw01 ~/mcw]$ cat roles/nginx/tasks/main.yaml
- name: Install nginx package
yum: name=nginx-{{ version }} state=present
- name: Copy nginx.conf Template
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf owner=root group=root backup=yes mode=0644
notify: restart nginx
- name: Copy index html
copy: src=index.html dest=/usr/share/nginx/html/index.html owner=root group=root backup=yes mode=0644
- name: make sure nginx service running
service: name=nginx state=started
[root@mcw01 ~/mcw]$ ansible-playbook site.yaml --syntax-check
ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: No JSON object could be decoded Syntax Error while loading YAML.
mapping values are not allowed in this context The error appears to be in '/root/mcw/roles/nginx/tasks/main.yaml': line 7, column 9, but may
be elsewhere in the file depending on the exact syntax problem. The offending line appears to be: - name: Copy index html
copy: src=index.html dest=/usr/share/nginx/html/index.html owner=root group=root backup=yes mode=0644
^ here
[root@mcw01 ~/mcw]$
正确的文件配置
[root@mcw01 ~/mcw]$ cat site.yaml
- name: install nginx
hosts: 10.0.0.12
roles:
- { role: nginx ,version: 1.0.15}
[root@mcw01 ~/mcw]$ cat roles/nginx/tasks/main.yaml
- name: Install nginx package
yum: name=nginx-{{ version }} state=present
- name: Copy nginx.conf Template
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf owner=root group=root backup=yes mode=0644
notify: restart nginx
- name: Copy index html
copy: src=index.html dest=/usr/share/nginx/html/index.html owner=root group=root backup=yes mode=0644
- name: make sure nginx service running
service: name=nginx state=started
[root@mcw01 ~/mcw]$ cat roles/nginx/handlers/main.yaml
- name: restart nginx
service: name=nginx state=restarted
[root@mcw01 ~/mcw]$ cat roles/nginx/templates/nginx.conf.j2 |grep '\{{'
worker_processes {{ ansible_processor_cores }};
[root@mcw01 ~/mcw]$ cat roles/nginx/files/index.html
hello mcw
[root@mcw01 ~/mcw]$
部署role
语法检查没有问题,就部署,因为版本没有,就改了个有的版本
[root@mcw01 ~/mcw]$ ansible-playbook site.yaml --syntax-check playbook: site.yaml
[root@mcw01 ~/mcw]$ ansible-playbook site.yaml PLAY [install nginx] ****************************************************************************************************************************** TASK [Gathering Facts] *****************************************************************************************************************************
ok: [10.0.0.12] TASK [Install nginx package] ***********************************************************************************************************************
fatal: [10.0.0.12]: FAILED! => {"changed": false, "msg": "No package matching 'nginx-1.0.15' found available, installed or updated", "rc": 126, "results": ["No package matching 'nginx-1.0.15' found available, installed or updated"]} PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$ vim site.yaml
[root@mcw01 ~/mcw]$ cat site.yaml
- name: install nginx
hosts: 10.0.0.12
roles:
- { role: nginx ,version: 1.20.1 }
[root@mcw01 ~/mcw]$ ansible-playbook site.yaml PLAY [install nginx] ****************************************************************************************************************************** TASK [Gathering Facts] *****************************************************************************************************************************
ok: [10.0.0.12] TASK [Install nginx package] ***********************************************************************************************************************
changed: [10.0.0.12] TASK [Copy nginx.conf Template] ********************************************************************************************************************
changed: [10.0.0.12] TASK [nginx : Copy index html] *********************************************************************************************************************
changed: [10.0.0.12] TASK [make sure nginx service running] *************************************************************************************************************
changed: [10.0.0.12] RUNNING HANDLER [restart nginx] ********************************************************************************************************************
changed: [10.0.0.12] PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=6 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
虽然多级目录不存在,但是这里yum安装默认生成的目录,然后将配置文件替换掉生成文件
[root@mcw02 ~]$ ls /usr/share/nginx/
html modules
[root@mcw02 ~]$
分析role
[root@mcw01 ~/mcw]$ cat site.yaml
- name: install nginx
hosts: 10.0.0.12
roles:
- { role: nginx ,version: 1.0.15}
[root@mcw01 ~/mcw]$ cat roles/nginx/tasks/main.yaml
- name: Install nginx package
yum: name=nginx-{{ version }} state=present
- name: Copy nginx.conf Template
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf owner=root group=root backup=yes mode=0644
notify: restart nginx
- name: Copy index html
copy: src=index.html dest=/usr/share/nginx/html/index.html owner=root group=root backup=yes mode=0644
- name: make sure nginx service running
service: name=nginx state=started
[root@mcw01 ~/mcw]$ cat roles/nginx/handlers/main.yaml
- name: restart nginx
service: name=nginx state=restarted
[root@mcw01 ~/mcw]$ cat roles/nginx/templates/nginx.conf.j2 |grep '\{{'
worker_processes {{ ansible_processor_cores }};
[root@mcw01 ~/mcw]$ cat roles/nginx/files/index.html
hello mcw
[root@mcw01 ~/mcw]$
playbook基本语法案例
Nginx剧本案例和检查
[root@mcw01 ~/mcw]$ cat nginx.yaml
- hosts: all
tasks:
- name: install nginx package
yum: name=nginx state=present
- name: copy nginx.conf
template: src=./nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify:
- ReStart Nginx Service
handlers:
- name: ReStart Nginx Service
service: name=nginx state=restarted
[root@mcw01 ~/mcw]$ cat hosts
[nginx]
10.0.0.1[1:3]
[nginx:vars]
ansible_python_interpreter=/usr/bin/python
ansible_ssh_pass='123456'
[root@mcw01 ~/mcw]$
[root@mcw01 ~/mcw]$ cat hosts #定义主机组,定义这个主机组有的变量,变量包含解释器路径和密码
[nginx]
10.0.0.1[1:3]
[nginx:vars]
ansible_python_interpreter=/usr/bin/python
ansible_ssh_pass='123456'
[root@mcw01 ~/mcw]$ grep worker_processes nginx.conf.j2 #模板使用工作进程数,是和ansible进程核数相同
worker_processes {{ ansible_processor_cores }}; [root@mcw01 ~/mcw]$ ansible-playbook -i hosts nginx.yaml --syntax-check #检查语法 playbook: nginx.yaml
[root@mcw01 ~/mcw]$ ansible-playbook -i hosts nginx.yaml --list-task #检查剧本有哪些任务。这里只有两个 playbook: nginx.yaml play #1 (all): all TAGS: []
tasks:
install nginx package TAGS: []
copy nginx.conf TAGS: []
[root@mcw01 ~/mcw]$ ansible-playbook -i hosts nginx.yaml --list-hosts #检查剧本执行的主机列表 playbook: nginx.yaml play #1 (all): all TAGS: []
pattern: [u'all']
hosts (3):
10.0.0.11
10.0.0.13
10.0.0.12
[root@mcw01 ~/mcw]$
把Nginx yum安装的,没有注释掉 的配置拿出来,改了个工作进程数配置
[root@mcw01 ~/mcw]$ cat nginx.conf.j2
user nginx;
worker_processes {{ ansible_processor_cores }};
error_log /var/log/nginx/error.log;
pid /run/nginx.pid; include /usr/share/nginx/modules/*.conf; events {
worker_connections 1024;
} http {
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 /var/log/nginx/access.log main; sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096; include /etc/nginx/mime.types;
default_type application/octet-stream; include /etc/nginx/conf.d/*.conf; server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html; # Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf; error_page 404 /404.html;
location = /404.html {
} error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
} }
[root@mcw01 ~/mcw]$
Nginx剧本执行
部署过程。我的一台部署了gitlab,好像是它的Nginx进程占用了80端口,导致yum装的没法启动
[root@mcw01 ~/mcw]$ ansible-playbook -i hosts nginx.yaml -f 3 PLAY [all] ***************************************************************************************************************************************** TASK [Gathering Facts] *****************************************************************************************************************************
ok: [10.0.0.12]
ok: [10.0.0.11]
ok: [10.0.0.13] TASK [install nginx package] ***********************************************************************************************************************
changed: [10.0.0.12]
changed: [10.0.0.11]
changed: [10.0.0.13] TASK [copy nginx.conf] *****************************************************************************************************************************
changed: [10.0.0.12]
changed: [10.0.0.13]
changed: [10.0.0.11] RUNNING HANDLER [ReStart Nginx Service] ************************************************************************************************************
changed: [10.0.0.12]
changed: [10.0.0.13]
fatal: [10.0.0.11]: FAILED! => {"changed": false, "msg": "Unable to start service nginx: Job for nginx.service failed because the control process exited with error code. See \"systemctl status nginx.service\" and \"journalctl -xe\" for details.\n"} NO MORE HOSTS LEFT ********************************************************************************************************************************* PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=3 changed=2 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
10.0.0.12 : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.13 : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$ ss -lntup|grep 80
tcp LISTEN 0 1024 127.0.0.1:8080 *:* users:(("bundle",pid=2132,fd=9),("bundle",pid=2128,fd=9),("bundle",pid=917,fd=9))
tcp LISTEN 0 511 *:80 *:* users:(("nginx",pid=769,fd=7),("nginx",pid=706,fd=7))
tcp LISTEN 0 511 *:8060 *:* users:(("nginx",pid=769,fd=8),("nginx",pid=706,fd=8))
tcp LISTEN 0 50 *:3306 *:* users:(("mysqld",pid=1480,fd=14))
tcp LISTEN 0 50 :::8081 :::* users:(("java",pid=1850,fd=160))
[root@mcw01 ~/mcw]$ systemctl status nginx.service
● nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Tue 2022-10-18 20:31:34 CST; 56s ago
Process: 6315 ExecStart=/usr/sbin/nginx (code=exited, status=1/FAILURE)
Process: 6313 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
Process: 6311 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS) Oct 18 20:31:31 mcw01 nginx[6315]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Oct 18 20:31:32 mcw01 nginx[6315]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Oct 18 20:31:32 mcw01 nginx[6315]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Oct 18 20:31:33 mcw01 nginx[6315]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Oct 18 20:31:33 mcw01 nginx[6315]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Oct 18 20:31:34 mcw01 nginx[6315]: nginx: [emerg] still could not bind()
Oct 18 20:31:34 mcw01 systemd[1]: nginx.service: control process exited, code=exited status=1
Oct 18 20:31:34 mcw01 systemd[1]: Failed to start The nginx HTTP and reverse proxy server.
Oct 18 20:31:34 mcw01 systemd[1]: Unit nginx.service entered failed state.
Oct 18 20:31:34 mcw01 systemd[1]: nginx.service failed.
[root@mcw01 ~/mcw]$
查看端口是否开启监听,配置文件是否正确
[root@mcw01 ~/mcw]$ ansible -i hosts all -m shell -a 'netstat -tpln|grep :80' -f 3
10.0.0.12 | CHANGED | rc=0 >>
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2130/nginx: master
tcp6 0 0 :::80 :::* LISTEN 2130/nginx: master
10.0.0.13 | CHANGED | rc=0 >>
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2024/nginx: master
tcp6 0 0 :::80 :::* LISTEN 2024/nginx: master
10.0.0.11 | CHANGED | rc=0 >>
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 917/unicorn master
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 706/nginx: master p
tcp 0 0 0.0.0.0:8060 0.0.0.0:* LISTEN 706/nginx: master p
tcp6 0 0 :::8081 :::* LISTEN 1850/java
[root@mcw01 ~/mcw]$ ansible -i hosts all -m shell -a 'grep worker_processes /etc/nginx/nginx.conf' -f 3
10.0.0.13 | CHANGED | rc=0 >>
worker_processes 1;
10.0.0.12 | CHANGED | rc=0 >>
worker_processes 1;
10.0.0.11 | CHANGED | rc=0 >>
worker_processes 1;
[root@mcw01 ~/mcw]$
只运行一个任务,指定一个任务运行。如果只需要修改Nginx配置,只运行这个任务就行。貌似现在使用这个参数不行,不可识别的参数了。有时间再研究有没有替代的参数或者是没写对参数
[root@mcw01 ~/mcw]$ ansible -i hosts all -f 3 --start-at-task='copy nginx.conf'
Ansible Playbook常用参数
- hosts: 10.0.0.12:10.0.0.13
patterns:
remote_user: root
sudo: yes
sudo_user: machangwei
gather_facts: no
accelerate: no
accelerate_port: 5099
max_fail_percentage: 30
connection: local
serial: 15
vars:
nginx_port: 80
vars_files:
- name: "password vaes"
prompt: "Enter password"
default: "secret"
private: yes
encrypt: "md5_crypt"
confirm: yes
salt: 1234
salt_size: 8
pre_tasks:
- name: pre_tasks
shell: hostname
roles:
- docker
- { role: docker,version: '1.5.0', when: "ansible_system == 'Linux'", tags: [docker,install] }
- { role: docker, when: ansible_all_ipv4_addresses == '10.0.0.12' }
tasks:
- include: tasks.yaml
- include: tasks.yaml ansible_distribution='CentOS' ansible_distribution_VERSION='6.6'
- { include: tasks.yaml, version: '1.1', package: [nginx,httpd] }
- include: tasks_10.0.0.12.yaml
when: ansible_all_ipv4_addresses == '10.0.0.12'
post_tasks:
- name: post_tasks
shell: hostname
handlers:
- include: handlers.yml
- hosts: 10.0.0.12:10.0.0.13 #目标主机支持'Ad-Hoc'模式的所有
patterns:
remote_user: root #远程SSH认证用户
sudo: yes #设置‘playbook sudo’操作
sudo_user: machangwei #设置‘playbook sudo’用户
gather_facts: no #设置‘facts’信息收集
accelerate: no #设置'accelerate'模式
accelerate_port: 5099 #设置'accelerate'端口
max_fail_percentage: 30 #设置'palayboook tasks'失败百分比
connection: local #设置远程连接方式
serial: 15 #设置'playbook'并发数目
vars: #设置'playbook'变量
nginx_port: 80
vars_files: #设置'playbook'变量引用文件
- name: "password vaes"
prompt: "Enter password" #使用'prompt'模块加密输入变量
default: "secret"
private: yes
encrypt: "md5_crypt"
confirm: yes
salt: 1234
salt_size: 8
pre_tasks: #设置'playbook'运行之前的'task'
- name: pre_tasks
shell: hostname
roles: #设置引入'role'
- docker
- { role: docker,version: '1.5.0', when: "ansible_system == 'Linux'", tags: [docker,install] }
- { role: docker, when: ansible_all_ipv4_addresses == '10.0.0.12' }
tasks: #设置引入'task'
- include: tasks.yaml
- include: tasks.yaml ansible_distribution='CentOS' ansible_distribution_VERSION='6.6'
- { include: tasks.yaml, version: '1.1', package: [nginx,httpd] }
- include: tasks_10.0.0.12.yaml
when: ansible_all_ipv4_addresses == '10.0.0.12'
post_tasks: #设置'playbook'运行之后的'tasks'
- name: post_tasks
shell: hostname
handlers: #设置'palybooks'的'handlers'
- include: handlers.yml
playbook变量与引用
1、通过Inventory文件定义主机以及主机组变量
对每台主机设置变量名key。使用debug模块查看变量的值,inventory_hostname,当前执行到的主机
[root@mcw01 ~/mcw]$ cat variable.yaml
- hosts: all
gather_facts: False
tasks:
- name: display Host Variable from hostfile
debug: msg="The {{ inventory_hostname }} Vaule is {{ key }}"
[root@mcw01 ~/mcw]$ [root@mcw01 ~/mcw]$ cat hosts
10.0.0.11 key=11 ansible_ssh_pass='123456'
10.0.0.12 key=12 ansible_ssh_pass='123456'
10.0.0.13 key=13 ansible_ssh_pass='123456'
[nginx]
10.0.0.1[1:3]
[nginx:vars]
ansible_python_interpreter=/usr/bin/python
ansible_ssh_pass='123456'
[root@mcw01 ~/mcw]$ ansible-playbook -i hosts variable.yaml PLAY [all] ***************************************************************************************************************************************** TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The 10.0.0.11 Vaule is 11"
}
ok: [10.0.0.12] => {
"msg": "The 10.0.0.12 Vaule is 12"
}
ok: [10.0.0.13] => {
"msg": "The 10.0.0.13 Vaule is 13"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.13 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
下面看主机组变量的设置
[root@mcw01 ~/mcw]$ cat variable.yaml
- hosts: all
gather_facts: False
tasks:
- name: display Host Variable from hostfile
debug: msg="The {{ inventory_hostname }} Vaule is {{ key }}"
[root@mcw01 ~/mcw]$ cat hosts
#10.0.0.11 key=11 ansible_ssh_pass='123456'
#10.0.0.12 key=12 ansible_ssh_pass='123456'
#10.0.0.13 key=13 ansible_ssh_pass='123456'
[nginx]
10.0.0.1[1:3]
[nginx:vars]
ansible_python_interpreter=/usr/bin/python
ansible_ssh_pass='123456'
key=nginx
[root@mcw01 ~/mcw]$ ansible-playbook -i hosts variable.yaml PLAY [all] ***************************************************************************************************************************************** TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The 10.0.0.11 Vaule is nginx"
}
ok: [10.0.0.12] => {
"msg": "The 10.0.0.12 Vaule is nginx"
}
ok: [10.0.0.13] => {
"msg": "The 10.0.0.13 Vaule is nginx"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.13 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
2、通过/etc/ansible/下的文件定义主机以及主机组变量
要在剧本执行当前目录下创建主机变量目录和主机组变量。主机变量里面按照主机ip为文件名,里面定义变量,冒号隔开;主机组变量里面写个文件然后定义变量就行
下面是主机变量
[root@mcw01 ~/mcw]$ tree
.
├── group_vars
│ └── nginx
├── hosts
├── host_vars
│ ├── 10.0.0.11
│ ├── 10.0.0.12
│ └── 10.0.0.13
└── variable.yaml 2 directories, 6 files
[root@mcw01 ~/mcw]$ cat group_vars/*
key: NGINX
[root@mcw01 ~/mcw]$ cat host_vars/*
key: 10.0.0.11
key: 10.0.0.12
key: 10.0.0.13
[root@mcw01 ~/mcw]$
[root@mcw01 ~/mcw]$
[root@mcw01 ~/mcw]$ head host_vars/*
==> host_vars/10.0.0.11 <==
key: 10.0.0.11 ==> host_vars/10.0.0.12 <==
key: 10.0.0.12 ==> host_vars/10.0.0.13 <==
key: 10.0.0.13
[root@mcw01 ~/mcw]$ cat group_vars/nginx
key: NGINX
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml PLAY [all] ***************************************************************************************************************************************** TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.12] => {
"msg": "The 10.0.0.12 Vaule is 10.0.0.12"
}
ok: [10.0.0.13] => {
"msg": "The 10.0.0.13 Vaule is 10.0.0.13"
}
ok: [10.0.0.11] => {
"msg": "The 10.0.0.11 Vaule is 10.0.0.11"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.13 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
下面是主机组变量,主机组变量失败,以后再研究一下吧
[root@mcw01 ~/mcw]$ ls
group_vars hosts host_vars variable.yaml
[root@mcw01 ~/mcw]$ mv host_vars ..
[root@mcw01 ~/mcw]$ ls
group_vars hosts variable.yaml
[root@mcw01 ~/mcw]$ cat group_vars/nginx
key: NGINX
[root@mcw01 ~/mcw]$ cat variable.yaml
- hosts: all
gather_facts: False
tasks:
- name: display Host Variable from hostfile
debug: msg="The {{ inventory_hostname }} Vaule is {{ key }}"
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml PLAY [all] ***************************************************************************************************************************************** TASK [display Host Variable from hostfile] *********************************************************************************************************
fatal: [10.0.0.11]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'key' is undefined\n\nThe error appears to be in '/root/mcw/variable.yaml': line 4, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: display Host Variable from hostfile\n ^ here\n"}
fatal: [10.0.0.13]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'key' is undefined\n\nThe error appears to be in '/root/mcw/variable.yaml': line 4, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: display Host Variable from hostfile\n ^ here\n"}
fatal: [10.0.0.12]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'key' is undefined\n\nThe error appears to be in '/root/mcw/variable.yaml': line 4, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: display Host Variable from hostfile\n ^ here\n"} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
10.0.0.12 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
10.0.0.13 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$ ls
group_vars hosts variable.yaml
下面是出错的,我放到ansible配置文件同级目录下不行。yum装的,不知道哪里的问题
[root@mcw01 /etc/ansible]$ head host_vars/*
==> host_vars/10.0.0.11 <==
key: 10.0.0.11 ==> host_vars/10.0.0.12 <==
key: 10.0.0.12 ==> host_vars/10.0.0.13 <==
key: 10.0.0.13
[root@mcw01 /etc/ansible]$ cat group_vars/nginx
key: NGINX
[root@mcw01 /etc/ansible]$ cd /root/mcw
[root@mcw01 ~/mcw]$ ls
hosts variable.yaml
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml PLAY [all] ***************************************************************************************************************************************** TASK [display Host Variable from hostfile] *********************************************************************************************************
fatal: [10.0.0.11]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'key' is undefined\n\nThe error appears to be in '/root/mcw/variable.yaml': line 4, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: display Host Variable from hostfile\n ^ here\n"}
fatal: [10.0.0.12]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'key' is undefined\n\nThe error appears to be in '/root/mcw/variable.yaml': line 4, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: display Host Variable from hostfile\n ^ here\n"}
fatal: [10.0.0.13]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'key' is undefined\n\nThe error appears to be in '/root/mcw/variable.yaml': line 4, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: display Host Variable from hostfile\n ^ here\n"} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
10.0.0.12 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
10.0.0.13 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
3、通过ansible-playbook命令行传入
命令行传入单个变量。这里不知道读取的那里的host文件
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml -e "key=KEY" PLAY [all] ***************************************************************************************************************************************** TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The 10.0.0.11 Vaule is KEY"
}
ok: [10.0.0.12] => {
"msg": "The 10.0.0.12 Vaule is KEY"
}
ok: [10.0.0.13] => {
"msg": "The 10.0.0.13 Vaule is KEY"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.13 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
命令行传入多个变量之json格式文件
[root@mcw01 ~/mcw]$ vim var.json
[root@mcw01 ~/mcw]$ cat var.json
{ "key": "JSON" }
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml -e "@var.json" PLAY [all] ***************************************************************************************************************************************** TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The 10.0.0.11 Vaule is JSON"
}
ok: [10.0.0.12] => {
"msg": "The 10.0.0.12 Vaule is JSON"
}
ok: [10.0.0.13] => {
"msg": "The 10.0.0.13 Vaule is JSON"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.13 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
命令行传入多个变量之yaml格式文件
[root@mcw01 ~/mcw]$ vim var.yaml
[root@mcw01 ~/mcw]$ cat var.yaml
key: YAML
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml -e "@var.yaml" PLAY [all] ***************************************************************************************************************************************** TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The 10.0.0.11 Vaule is YAML"
}
ok: [10.0.0.12] => {
"msg": "The 10.0.0.12 Vaule is YAML"
}
ok: [10.0.0.13] => {
"msg": "The 10.0.0.13 Vaule is YAML"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.13 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
4、在playbook文件内使用vars
[root@mcw01 ~/mcw]$ cat variable.yaml
- hosts: all
gather_facts: False
vars:
key: Ansible
tasks:
- name: display Host Variable from hostfile
debug: msg="The {{ inventory_hostname }} Vaule is {{ key }}"
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml PLAY [all] ***************************************************************************************************************************************** TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The 10.0.0.11 Vaule is Ansible"
}
ok: [10.0.0.12] => {
"msg": "The 10.0.0.12 Vaule is Ansible"
}
ok: [10.0.0.13] => {
"msg": "The 10.0.0.13 Vaule is Ansible"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.13 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
5、在playbook文件内使用vars_files
[root@mcw01 ~/mcw]$ cat var.yaml
key: mcwYAML
[root@mcw01 ~/mcw]$ cat variable.yaml
- hosts: all
gather_facts: False
vars_files:
- var.yaml
tasks:
- name: display Host Variable from hostfile
debug: msg="The {{ inventory_hostname }} Vaule is {{ key }}"
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml PLAY [all] ***************************************************************************************************************************************** TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The 10.0.0.11 Vaule is mcwYAML"
}
ok: [10.0.0.12] => {
"msg": "The 10.0.0.12 Vaule is mcwYAML"
}
ok: [10.0.0.13] => {
"msg": "The 10.0.0.13 Vaule is mcwYAML"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.13 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
6、使用register内的变量
直接把注册的变量打印出来
[root@mcw01 ~/mcw]$ vim variable.yaml
[root@mcw01 ~/mcw]$ cat variable.yaml
- hosts: all
gather_facts: False
tasks:
- name: register variable
shell: hostname
register: info
- name: display Host Variable from hostfile
debug: msg="The varibale is {{ info }}"
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml PLAY [all] ***************************************************************************************************************************************** TASK [register variable] ***************************************************************************************************************************
changed: [10.0.0.12]
changed: [10.0.0.13]
changed: [10.0.0.11] TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The varibale is {'stderr_lines': [], u'changed': True, u'end': u'2022-10-18 22:42:21.431996', 'failed': False, u'stdout': u'mcw01', u'cmd': u'hostname', u'rc': 0, u'start': u'2022-10-18 22:42:21.407263', u'stderr': u'', u'delta': u'0:00:00.024733', 'stdout_lines': [u'mcw01'], 'ansible_facts': {u'discovered_interpreter_python': u'/usr/bin/python'}}"
}
ok: [10.0.0.12] => {
"msg": "The varibale is {'stderr_lines': [], u'changed': True, u'end': u'2022-10-18 22:42:21.161343', 'failed': False, u'stdout': u'mcw02', u'cmd': u'hostname', u'rc': 0, u'start': u'2022-10-18 22:42:21.133783', u'stderr': u'', u'delta': u'0:00:00.027560', 'stdout_lines': [u'mcw02'], 'ansible_facts': {u'discovered_interpreter_python': u'/usr/bin/python'}}"
}
ok: [10.0.0.13] => {
"msg": "The varibale is {'stderr_lines': [], u'changed': True, u'end': u'2022-10-18 22:42:21.119016', 'failed': False, u'stdout': u'mcw03', u'cmd': u'hostname', u'rc': 0, u'start': u'2022-10-18 22:42:21.107955', u'stderr': u'', u'delta': u'0:00:00.011061', 'stdout_lines': [u'mcw03'], 'ansible_facts': {u'discovered_interpreter_python': u'/usr/bin/python'}}"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.12 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.13 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
只打印注册的变量的标准输出,如果是shell命令,那么就是直接是shell命令的返回结果。取标准输出,相当于python字典取值的方法
[root@mcw01 ~/mcw]$ vim variable.yaml
[root@mcw01 ~/mcw]$ cat variable.yaml
- hosts: all
gather_facts: False
tasks:
- name: register variable
shell: hostname
register: info
- name: display Host Variable from hostfile
debug: msg="The varibale is {{ info['stdout'] }}"
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml PLAY [all] ***************************************************************************************************************************************** TASK [register variable] ***************************************************************************************************************************
changed: [10.0.0.13]
changed: [10.0.0.12]
changed: [10.0.0.11] TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The varibale is mcw01"
}
ok: [10.0.0.12] => {
"msg": "The varibale is mcw02"
}
ok: [10.0.0.13] => {
"msg": "The varibale is mcw03"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.12 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.13 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
7、使用vars_prompt传入
命令行需要传参,私有的话,输入的值是看不到的。可以设置默认值
[root@mcw01 ~/mcw]$ cat variable.yaml
- hosts: all
gather_facts: False
vars_prompt:
- name: "one"
prompt: "please input one value"
private: no
- name: "two"
prompt: "please input two value"
default: 'good'
private: yes
tasks:
- name: display one value
debug: msg="one value is {{ one }}"
- name: display two value
debug: msg="two value is {{ two }}"
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml -l 10.0.0.12
please input one value: name
please input two value [good]: PLAY [all] ***************************************************************************************************************************************** TASK [display one value] ***************************************************************************************************************************
ok: [10.0.0.12] => {
"msg": "one value is name"
} TASK [display two value] ***************************************************************************************************************************
ok: [10.0.0.12] => {
"msg": "two value is xiangjiao"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$ ansible-playbook variable.yaml -l 10.0.0.12
please input one value: name
please input two value [good]: PLAY [all] ***************************************************************************************************************************************** TASK [display one value] ***************************************************************************************************************************
ok: [10.0.0.12] => {
"msg": "one value is name"
} TASK [display two value] ***************************************************************************************************************************
ok: [10.0.0.12] => {
"msg": "two value is good"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$ ansible-playbook variable.yaml -l 10.0.0.12
please input one value:
please input two value [good]: PLAY [all] ***************************************************************************************************************************************** TASK [display one value] ***************************************************************************************************************************
ok: [10.0.0.12] => {
"msg": "one value is "
} TASK [display two value] ***************************************************************************************************************************
ok: [10.0.0.12] => {
"msg": "two value is good"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
playbook循环
1.标准Loops(多个普通变量(可以用字典形式)循环任务)
with_items
[root@mcw01 ~/mcw]$ cat loops.yaml
- hosts: all
gather_facts: False
tasks:
- name: debug loops
debug: msg="name ------>{{ item }}"
with_items:
- one
- two
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12 PLAY [all] ***************************************************************************************************************************************** TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item=one) => {
"msg": "name ------>one"
}
ok: [10.0.0.12] => (item=two) => {
"msg": "name ------>two"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
字典形式的变量
[root@mcw01 ~/mcw]$ cat loops.yaml
- hosts: all
gather_facts: False
tasks:
- name: debug loops
debug: msg="name ------>{{ item.key }} vaule---->{{ item.vaule }}"
with_items:
- {key: "one", vaule: "VAULE1"}
- {key: "two", vaule: "VAULE2"} [root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12 PLAY [all] ***************************************************************************************************************************************** TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item={u'vaule': u'VAULE1', u'key': u'one'}) => {
"msg": "name ------>one vaule---->VAULE1"
}
ok: [10.0.0.12] => (item={u'vaule': u'VAULE2', u'key': u'two'}) => {
"msg": "name ------>two vaule---->VAULE2"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
对所有主机都循环这两个任务
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml PLAY [all] ***************************************************************************************************************************************** TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.11] => (item={u'vaule': u'VAULE1', u'key': u'one'}) => {
"msg": "name ------>one vaule---->VAULE1"
}
ok: [10.0.0.11] => (item={u'vaule': u'VAULE2', u'key': u'two'}) => {
"msg": "name ------>two vaule---->VAULE2"
}
ok: [10.0.0.12] => (item={u'vaule': u'VAULE1', u'key': u'one'}) => {
"msg": "name ------>one vaule---->VAULE1"
}
ok: [10.0.0.12] => (item={u'vaule': u'VAULE2', u'key': u'two'}) => {
"msg": "name ------>two vaule---->VAULE2"
}
ok: [10.0.0.13] => (item={u'vaule': u'VAULE1', u'key': u'one'}) => {
"msg": "name ------>one vaule---->VAULE1"
}
ok: [10.0.0.13] => (item={u'vaule': u'VAULE2', u'key': u'two'}) => {
"msg": "name ------>two vaule---->VAULE2"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.13 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
2、嵌套Loops(一对多嵌套组合循环任务)
[root@mcw01 ~/mcw]$ vim loops.yaml
[root@mcw01 ~/mcw]$ cat loops.yaml
- hosts: all
gather_facts: False
tasks:
- name: debug loops
debug: msg="name ------>{{ item[0] }} vaule---->{{ item[1] }}"
with_nested:
- ['A']
- ['a','b','c']
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12 PLAY [all] ***************************************************************************************************************************************** TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item=[u'A', u'a']) => {
"msg": "name ------>A vaule---->a"
}
ok: [10.0.0.12] => (item=[u'A', u'b']) => {
"msg": "name ------>A vaule---->b"
}
ok: [10.0.0.12] => (item=[u'A', u'c']) => {
"msg": "name ------>A vaule---->c"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
3、散列loops(含嵌套字段的循环任务)
注意引用字典变量的是需要用到jinja2引用变量的方法。实现了如下数据结构的循环
{
"xiaoma": {"name":“xiaoma”,"shell":"bash"},
"daguo": {"name":"daguo","shell":"zsh"}
}
[root@mcw01 ~/mcw]$ vim loops.yaml
[root@mcw01 ~/mcw]$ cat loops.yaml
- hosts: all
gather_facts: False
vars:
user:
xiaoma:
name: xiaoma
shell: bash
daguo:
name: daguo
shell: zsh
tasks:
- name: debug loops
debug: msg="name ------->{{ item.key }} vaule --->{{ item.value.name }}" shell ---->{{ item.value.shell }}
with_dict: "{{ user }}"
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12 PLAY [all] ***************************************************************************************************************************************** TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item={u'key': u'xiaoma', u'value': {u'shell': u'bash', u'name': u'xiaoma'}}) => {
"msg": "name ------->xiaoma vaule --->xiaoma"
}
ok: [10.0.0.12] => (item={u'key': u'daguo', u'value': {u'shell': u'zsh', u'name': u'daguo'}}) => {
"msg": "name ------->daguo vaule --->daguo"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
4、文件匹配loops(满足条件的文件做同样的任务)
这个有问题,它找的是主机1上的文件,而我命令行让它查的是主机2上的文件,主机二上实际是没有这个yaml文件的
[root@mcw01 ~/mcw]$ ls
loops.yaml
[root@mcw01 ~/mcw]$ cat loops.yaml
- hosts: all
gather_facts: False
tasks:
- name: debug loops
debug: msg="files ------->{{ item }}"
with_fileglob:
- /root/*.yaml
[root@mcw01 ~/mcw]$ ls /root/
anaconda-ks.cfg hosts mcw nginx-role.tar.gz
gitlab2-hook.hpi host_vars mcw2 nginx.yaml
gitlab-ce-10.0.0-ce.0.el7.x86_64.rpm inventory mcw3 roles
gitlab-hook jenkins-2.73.1-1.1.noarch.rpm mcw.py site.yaml
gitlab-hook.hpi jpress-web-newest multibranch-scan-webhook-trigger.hpi sonarqube-8.9.9.56886.zip
group_vars jpress-web-newest.tar.gz nginx.conf.j2 tomcat
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12 PLAY [all] ***************************************************************************************************************************************** TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item=/root/nginx.yaml) => {
"msg": "files ------->/root/nginx.yaml"
}
ok: [10.0.0.12] => (item=/root/site.yaml) => {
"msg": "files ------->/root/site.yaml"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
如下,主机2实际是没有的
[root@mcw02 ~]$ ls
10.0.0.11 apache-tomcat-8.0.27 demo.sh jpress-web-newest.tar.gz logs mcw.py sonar-scanner-cli-4.7.0.2747-linux.zip
anaconda-ks.cfg apache-tomcat-8.0.27.tar.gz jpress-web-newest jpress-web-newest.war mcw sonarqube tomcat
[root@mcw02 ~]$
5、随机选择loops(任务变量随机)
[root@mcw01 ~/mcw]$ vim loops.yaml
[root@mcw01 ~/mcw]$ cat loops.yaml
- hosts: all
gather_facts: False
tasks:
- name: debug loops
debug: msg="name ------->{{ item }}"
with_random_choice:
- "ansible1"
- "ansible2"
- "ansible3"
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12 PLAY [all] ***************************************************************************************************************************************** TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item=ansible1) => {
"msg": "name ------->ansible1"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12 PLAY [all] ***************************************************************************************************************************************** TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item=ansible2) => {
"msg": "name ------->ansible2"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12 PLAY [all] ***************************************************************************************************************************************** TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item=ansible3) => {
"msg": "name ------->ansible3"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12 PLAY [all] ***************************************************************************************************************************************** TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item=ansible3) => {
"msg": "name ------->ansible3"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
6、条件判断loops(可实现任务重试当某个任务失败时)
[root@mcw01 ~/mcw]$ cat loops.yaml
- hosts: all
gather_facts: False
tasks:
- name: debug loops
shell: cat /root/Ansible
register: host
until: host.stdout.startswith("Master")
retries: 5
delay: 5
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12 PLAY [all] ***************************************************************************************************************************************** TASK [debug loops] *********************************************************************************************************************************
FAILED - RETRYING: debug loops (5 retries left). #多次重试任务
FAILED - RETRYING: debug loops (4 retries left).
FAILED - RETRYING: debug loops (3 retries left).
FAILED - RETRYING: debug loops (2 retries left).
FAILED - RETRYING: debug loops (1 retries left).
fatal: [10.0.0.12]: FAILED! => {"attempts": 5, "changed": true, "cmd": "cat /root/Ansible", "delta": "0:00:00.011660", "end": "2022-10-18 23:55:23.791639", "msg": "non-zero return code", "rc": 1, "start": "2022-10-18 23:55:23.779979", "stderr": "cat: /root/Ansible: No such file or directory", "stderr_lines": ["cat: /root/Ansible: No such file or directory"], "stdout": "", "stdout_lines": []} PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$ 当我们在执行重试时,立马创建文件并输入数据,让它成功读取。于是ansible就不重试了,成功读取到信息
[root@mcw02 ~]$ echo "Master" >>/root/Ansible
[root@mcw02 ~]$ [root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12 PLAY [all] ***************************************************************************************************************************************** TASK [debug loops] *********************************************************************************************************************************
FAILED - RETRYING: debug loops (5 retries left).
FAILED - RETRYING: debug loops (4 retries left).
changed: [10.0.0.12] PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
7、文件优先匹配Loops(遍历文件使用匹配上的第一个作为变量)
这个有问题,回头再看看
[root@mcw01 ~/mcw]$ vim loops.yaml
[root@mcw01 ~/mcw]$ cat loops.yaml
- hosts: all
gather_facts: True
tasks:
- name: debug loops
debug: msg="file --------> {{ item }}"
with_first_found:
- "{{ ansible_distribution }}.yaml"
- "default.yaml"
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12 PLAY [all] ***************************************************************************************************************************************** TASK [Gathering Facts] *****************************************************************************************************************************
ok: [10.0.0.12] TASK [debug loops] *********************************************************************************************************************************
fatal: [10.0.0.12]: FAILED! => {"msg": "No file was found when using first_found. Use errors='ignore' to allow this task to be skipped if no files are found"} PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
8、register Loops
register: ret 任务单个执行注册变量,在传给其它任务
任务多个循环 执行结果注册变量,再传给其它任务,多个结果for循环调用
[root@mcw01 ~/mcw]$ cat loops.yaml
- hosts: all
gather_facts: True
tasks:
- name: debug loops
shell: "{{ item }}"
with_items:
- hostname
- uname
register: ret
- name: display loops
debug: msg="{% for i in ret.results %} {{ i.stdout }} {% endfor %}"
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12 PLAY [all] ***************************************************************************************************************************************** TASK [Gathering Facts] *****************************************************************************************************************************
ok: [10.0.0.12] TASK [debug loops] *********************************************************************************************************************************
changed: [10.0.0.12] => (item=hostname)
changed: [10.0.0.12] => (item=uname) TASK [display loops] *******************************************************************************************************************************
ok: [10.0.0.12] => {
"msg": " mcw02 Linux "
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.12 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
playbook lookups
1、lookup file
[root@mcw01 ~/mcw]$ ls
loops.yaml mcw.conf
[root@mcw01 ~/mcw]$ cat loops.yaml
- hosts: all
gather_facts: False
vars:
contents: "{{ lookup('file','mcw.conf') }}"
tasks:
- name: debug lookups
debug: msg="The contents is {% for i in contents.split("\n") %} {{ i }} {% endfor %}"
[root@mcw01 ~/mcw]$ cat mcw.conf
db: mysql
hostname: mcw
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.11 PLAY [all] ***************************************************************************************************************************************** TASK [debug lookups] *******************************************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The contents is db: mysql hostname: mcw "
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
2、lookups password
加密字符串。调用密码,输出时会使用加密后的字符串
[root@mcw01 ~/mcw]$ cat loops.yaml
- hosts: all
gather_facts: False
vars:
contents: "{{ lookup('password','ansible_book') }}"
tasks:
- name: debug lookups
debug: msg="The contents is {{ contents }}"
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.11 PLAY [all] ***************************************************************************************************************************************** TASK [debug lookups] *******************************************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The contents is 7EKiRimgFJ88AyYAxe5,"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
上面那个貌似还在本地生成了一个密码文件
[root@mcw01 ~/mcw]$ ls
ansible_book loops.yaml mcw.conf
[root@mcw01 ~/mcw]$ cat ansible_book
7EKiRimgFJ88AyYAxe5,
[root@mcw01 ~/mcw]$
3、lookups pipe 将shell命令的打印信息赋值给变量
使用日期
[root@mcw01 ~/mcw]$ cat loops.yaml
- hosts: all
gather_facts: False
vars:
contents: "{{ lookup('pipe','date +%Y-%m-%d') }}"
tasks:
- name: debug lookups
debug: msg="The contents is {% for i in contents.split("\n") %} {{ i }} {% endfor %}"
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.11 PLAY [all] ***************************************************************************************************************************************** TASK [debug lookups] *******************************************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The contents is 2022-10-19 "
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
4、lookups redis_kv
5、lookups template jinja模板渲染完后再读取
[root@mcw01 ~/mcw]$ cat lookups.j2
worker_processes {{ ansible_processor_cores }};
IPaddress {{ ansible_ens33.ipv4.address }}
[root@mcw01 ~/mcw]$ cat loops.yaml
- hosts: all
gather_facts: True
vars:
contents: "{{ lookup('template','./lookups.j2') }}"
tasks:
- name: debug lookups
debug: msg="The contents is {% for i in contents.split("\n") %} {{ i }} {% endfor %}"
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.11 PLAY [all] ***************************************************************************************************************************************** TASK [Gathering Facts] *****************************************************************************************************************************
ok: [10.0.0.11] TASK [debug lookups] *******************************************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The contents is worker_processes 1; IPaddress 10.0.0.11 "
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
如果需要用到ansible内置变量,需要收集facts信息,否则使用的话就是未定义的
[root@mcw01 ~/mcw]$ cat lookups.j2
worker_processes {{ ansible_processor_cores }};
IPaddress {{ ansible_ens33.ipv4.address }}
[root@mcw01 ~/mcw]$ cat loops.yaml
- hosts: all
gather_facts: False
vars:
contents: "{{ lookup('template','./lookups.j2') }}"
tasks:
- name: debug lookups
debug: msg="The contents is {% for i in contents.split("\n") %} {{ i }} {% endfor %}"
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.11 PLAY [all] ***************************************************************************************************************************************** TASK [debug lookups] *******************************************************************************************************************************
fatal: [10.0.0.11]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: {{ lookup('template','./lookups.j2') }}: 'ansible_processor_cores' is undefined\n\nThe error appears to be in '/root/mcw/loops.yaml': line 6, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: debug lookups\n ^ here\n"} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
playbook conditionals 逻辑判断when
条件判断在每个name的最下面。满足条件执行,不满足不执行
[root@mcw01 ~/mcw]$ cat loops.yaml
- hosts: all
tasks:
- name: Host 10.0.0.11 run this task
debug: msg="{{ ansible_default_ipv4.address }}"
when: ansible_default_ipv4.address == "10.0.0.11"
- name: memtotal < 500M and processor_cores == 2 run this task
debug: msg="{{ ansible_fqdn }}"
when: ansible_memtotal_mb < 500 and ansible_processor_cores == 2
- name: all host run this task
shell: hostname
register: info
- name: Hostname is python Machie run this task
debug: msg="{{ ansible_fqdn }}"
when: info['stdout'] == "python"
- name: Hostname is startswith M run this task
debug: msg="{{ ansible_fqdn }}"
when: info['stdout'].startswith('M')
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.11 PLAY [all] ***************************************************************************************************************************************** TASK [Gathering Facts] *****************************************************************************************************************************
ok: [10.0.0.11] TASK [Host 10.0.0.11 run this task] ****************************************************************************************************************
ok: [10.0.0.11] => {
"msg": "10.0.0.11"
} TASK [memtotal < 500M and processor_cores == 2 run this task] **************************************************************************************
skipping: [10.0.0.11] TASK [all host run this task] **********************************************************************************************************************
changed: [10.0.0.11] TASK [Hostname is python Machie run this task] *****************************************************************************************************
skipping: [10.0.0.11] TASK [Hostname is startswith M run this task] ******************************************************************************************************
skipping: [10.0.0.11] PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=3 changed=1 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
Jinja2 filter 常用filter
感觉太严格了,有点拼写错误,又没有准确的提示,太难找拼写错误了有时候是
[root@mcw01 ~/mcw]$ cat lookups.yaml
- hosts: all
gather_facts: False
vars:
list: [1,2,3,4,5]
one: "1"
str: "string"
tasks:
- name: run commands
shell: df -h
register: info
- name: debug pprint filter
debug: msg="{{ info.stdout | pprint }}"
- name: debug int capitalize filter
debug: msg="The int value {{ one | int }}" The lower value is {{ str | capitalize }}
- name: debug default filter
debug: msg="The Variable value is {{ ansible | default('ansible is not define') }}"
- name: debug list max and min filter
debug: msg="The list max value is {{list | max}} The list min value is {{ list | min }}"
- name: debug ramdom filter
debug: msg="The list ramdom value is {{ list | random }} and generate a random value is {{ 1000|random(1,10) }}"
- name: debug join filter
debug: msg="The join filter value is {{ list | join("+") }}"
- name: debug replace and regex_replace filter
debug: msg="The replace value is {{ str | replace('t','T') }} The regex_replace vaule is {{ str | regex_replace('.*tr(.*)$','\\1') }}"
[root@mcw01 ~/mcw]$ ansible-playbook lookups.yaml -l 10.0.0.11 PLAY [all] ***************************************************************************************************************************************** TASK [run commands] ********************************************************************************************************************************
changed: [10.0.0.11] TASK [debug pprint filter] *************************************************************************************************************************
ok: [10.0.0.11] => {
"msg": "u'Filesystem Size Used Avail Use% Mounted on\\n/dev/mapper/centos-root 19G 6.4G 13G 35% /\\ndevtmpfs 1.4G 0 1.4G 0% /dev\\ntmpfs 1.4G 128K 1.4G 1% /dev/shm\\ntmpfs 1.4G 8.7M 1.4G 1% /run\\ntmpfs 1.4G 0 1.4G 0% /sys/fs/cgroup\\n/dev/sda1 797M 143M 655M 18% /boot\\ntmpfs 284M 0 284M 0% /run/user/0'"
} TASK [debug int capitalize filter] *****************************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The int value 1"
} TASK [debug default filter] ************************************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The Variable value is ansible is not define"
} TASK [debug list max and min filter] ***************************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The list max value is 5 The list min value is 1"
} TASK [debug ramdom filter] *************************************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The list ramdom value is 5 and generate a random value is 291"
} TASK [debug join filter] ***************************************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The join filter value is 1+2+3+4+5"
} TASK [debug replace and regex_replace filter] ******************************************************************************************************
ok: [10.0.0.11] => {
"msg": "The replace value is sTring The regex_replace vaule is ing"
} PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=8 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
内置变量的使用案例
[root@mcw01 ~/mcw]$ ls
docker hosts jinja.j2 template.yaml
[root@mcw01 ~/mcw]$ cat template.yaml
- hosts: all
tasks:
- name: test template
template: src=jinja.j2 dest=/root/cpis
[root@mcw01 ~/mcw]$ cat jinja.j2
==========
groups info
{{ groups }}
=================== ================docker groups info ============
{% for host in groups['docker'] %}
={{ hostvars[host]['inventory_hostname'] }} eth0 IP is {{ hostvars[host]['ansible_default_ipv4']['address'] }}
+{{ hostvars[host]['inventory_hostname'] }} groups is {{ group_names }}
_{{ hostvars[host]['inventory_hostname'] }} short is {{ inventory_hostname_short }}
*{{ play_hosts }}
@{{ inventory_dir }}
{% endfor %}
[root@mcw01 ~/mcw]$ cat hosts
10.0.0.11 ansible_ssh_pass='123456'
10.0.0.12 ansible_ssh_pass='123456'
10.0.0.13 ansible_ssh_pass='123456'
[root@mcw01 ~/mcw]$ cat docker
[docker]
10.0.0.1[1:3]
[docker:vars]
ansible_python_interpreter=/usr/bin/python
ansible_ssh_pass='123456'
[root@mcw01 ~/mcw]$ ansible-playbook template.yaml PLAY [all] ***************************************************************************************************************************************** TASK [Gathering Facts] *****************************************************************************************************************************
ok: [10.0.0.13]
ok: [10.0.0.12]
ok: [10.0.0.11] TASK [test template] *******************************************************************************************************************************
ok: [10.0.0.13]
ok: [10.0.0.12]
ok: [10.0.0.11] PLAY RECAP *****************************************************************************************************************************************
10.0.0.11 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.12 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.13 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@mcw01 ~/mcw]$
[root@mcw01 ~/mcw]$ ansible all -m shell -a "cat /root/cpis"
10.0.0.12 | CHANGED | rc=0 >>
==========
groups info
{'ungrouped': [], 'all': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13'], u'ansible': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13'], u'docker': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']}
=================== ================docker groups info ============
=10.0.0.11 eth0 IP is 10.0.0.11
+10.0.0.11 groups is [u'ansible', u'docker']
_10.0.0.11 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
=10.0.0.12 eth0 IP is 10.0.0.12
+10.0.0.12 groups is [u'ansible', u'docker']
_10.0.0.12 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
=10.0.0.13 eth0 IP is 10.0.0.13
+10.0.0.13 groups is [u'ansible', u'docker']
_10.0.0.13 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
10.0.0.13 | CHANGED | rc=0 >>
==========
groups info
{'ungrouped': [], 'all': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13'], u'ansible': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13'], u'docker': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']}
=================== ================docker groups info ============
=10.0.0.11 eth0 IP is 10.0.0.11
+10.0.0.11 groups is [u'ansible', u'docker']
_10.0.0.11 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
=10.0.0.12 eth0 IP is 10.0.0.12
+10.0.0.12 groups is [u'ansible', u'docker']
_10.0.0.12 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
=10.0.0.13 eth0 IP is 10.0.0.13
+10.0.0.13 groups is [u'ansible', u'docker']
_10.0.0.13 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
10.0.0.11 | CHANGED | rc=0 >>
==========
groups info
{'ungrouped': [], 'all': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13'], u'ansible': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13'], u'docker': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']}
=================== ================docker groups info ============
=10.0.0.11 eth0 IP is 10.0.0.11
+10.0.0.11 groups is [u'ansible', u'docker']
_10.0.0.11 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
=10.0.0.12 eth0 IP is 10.0.0.12
+10.0.0.12 groups is [u'ansible', u'docker']
_10.0.0.12 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
=10.0.0.13 eth0 IP is 10.0.0.13
+10.0.0.13 groups is [u'ansible', u'docker']
_10.0.0.13 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
[root@mcw01 ~/mcw]$
用ansible-vault保护敏感数据
工具子命令
[root@mcw01 ~/mcw]$ ansible-vault -h
usage: ansible-vault [-h] [--version] [-v]
{create,decrypt,edit,view,encrypt,encrypt_string,rekey}
... encryption/decryption utility for Ansible data files positional arguments:
{create,decrypt,edit,view,encrypt,encrypt_string,rekey}
create Create new vault encrypted file
decrypt Decrypt vault encrypted file
edit Edit vault encrypted file
view View vault encrypted file
encrypt Encrypt YAML file
encrypt_string Encrypt a string
rekey Re-key a vault encrypted file optional arguments:
--version show program's version number, config file location,
configured module search path, module location,
executable location and exit
-h, --help show this help message and exit
-v, --verbose verbose mode (-vvv for more, -vvvv to enable
connection debugging) See 'ansible-vault <command> --help' for more information on a specific
command.
[root@mcw01 ~/mcw]$
命令的基本使用
先添加vim作为编辑器到环境变量
[root@mcw01 ~]$ vim .bash_profile
[root@mcw01 ~]$ grep vim .bash_profile
export EDITOR=vim
[root@mcw01 ~]$ source .bash_profile
[root@mcw01 ~]$
我这里都是123456
下面是我们编辑过程中,输入的内容
查看编辑的文件内容,是加密的
我们修改的话可以输入文件的密码,然后进入编辑模式,此时文件内容不是加密的
编辑完之后保存退出
我们rekey变更加密数据的密钥,然后可以用新密码进入文件,可以编辑文件内容了。
1、保护ansible role中的敏感数据(未写,有时间再补充)
2、使用加密做用户认证
3、保护Nginx中的ssl密钥
参考:https://blog.csdn.net/qq_39122146/article/details/109173969
ansible使用详解的更多相关文章
- Ansible配置详解
目录 Ansible配置详解 参考 配置优先级 配置参数说明 Ansible配置详解
- Ansible配置文件ansible.cfg详解
Ansible是一个系列文章,我会尽量以通俗易懂.诙谐幽默的总结方式给大家呈现这些枯燥的知识点,让学习变的有趣一些. Ansible系列博文直达链接:Ansible入门系列 前言 此时外面小雨淅淅沥沥 ...
- ansible 配置详解
ansible 安装方式 ansible安装常用两种方式,yum安装和pip程序安装.下面我们来详细介绍一下这两种安装方式. 使用 pip(python的包管理模块)安装 首先,我们需要安装一个pyt ...
- ansible配置文件详解
# ansible配置文件配置 配置项介绍 , 配置文件ansible.cfg, 运行playbook时,默认时在yaml文件所在路径寻找,然后再去/etc/ansible/下寻找 [defaults ...
- ansible 变量详解
定义变量的方法 1. 主机变量,在hosts文件中设置变量, [atlanta] host1 http_port= maxRequestsPerChild= host2 http_port= maxR ...
- Ansible Playbook 详解
一.playbook 的简单使用 1.创建文件实例 (1)编辑配置文件 [root@tiejiangSRC1 ~]# cd /etc/ansible/ [root@tiejiangSRC1 ansib ...
- ansible命令详解
查看ansible版本 import ansible print(ansible.__version__) 命令参数 -m:要执行的模块,默认为command -a:模块的参数 -u:ssh连接的用户 ...
- 2、Ansible配置文件详解
0.配置文件 两个核心文件:ansible.cfg和hosts文件,默认都存放在/etc/ansible目录下. ansible.cfg:主要设置一些ansible初始化的信息,比如日志存放路径.模块 ...
- ansible playbook详解
ansible playbook是由yml语法书写,结构清晰,可读性强,所以必须掌握yml基础语法 语法 描述 缩进 YAML使用固定的缩进风格表示层级结构,每个缩进由两个空格组成,不能使用tabs键 ...
- linux shell ansible 命令详解
也可以参考ansible 模块介绍的其他文章:https://www.cnblogs.com/guxiaobei/p/8316903.html 安装ansible yum install epel-r ...
随机推荐
- 精彩预告 | OpenHarmony即将亮相MTSC 2023
MTSC 2023 第 12 届中国互联网测试开发大会(深圳站)即将于 2023 年 11 月 25 日,在深圳登喜路国际大酒店举办,大会将以"1 个主会场+4 个平行分会场"的形 ...
- 【开源三方库】crypto-js加密算法库的使用方法
OpenAtom OpenHarmony(简称"OpenHarmony")三方库,是经过验证可在OpenHarmony系统上可重复使用的软件组件,可帮助开发者快速开发OpenHa ...
- Linux系统中查找文件的方法
-name 必须用到的选项.表明要求系统按照文件名查找. 一般格式:find /(dirname) -name filename 具体文件名查找法: 如果知道了某个文件的文件名,而不知道这个文件放到哪 ...
- 面向切面编程AOP[一](java 代码详解)
前言 说句实话,在工作中,使用的aop不是特别多,但是特别重要,一般是辅助程序,在现代开发者辅助程序相当重要,比如说我们需要打印一些log,但是我们不可能去卸载我们的业务程序中,因为这太..... 正 ...
- jenkins 持续集成和交付 —— 触发器(六)
前言 什么是触发器呢?当某种条件达到的时候将会触发某个机关. 正文 jenkins 内置4种触发器: 1.触发远程构建 2.其他工程构建后触发 3.定时触发 4.轮询SCM 那么就来介绍一下这几种吧. ...
- 利用navicat 完成两台服务器之间的数据库迁移,安全可靠
首先,准备工作先做好 1. 工具,navicat,我这里用的是navicat12+ 2. 建立两台服务器的链接,即新建链接,mysql,同时,需要在迁移目标服务器上面实现建立好对应的数据库,即如果有1 ...
- ORA-01555:snapshot too old: rollback segment number X with name "XXXX" too small
ORA-01555:snapshot too old: rollback segment number X with name "XXXX" too small 在查询快照的时候 ...
- 初接触:从创建工程到导出gerber(学习Altium Designer)
学习Altium Designer Altium Designer的工程文件后缀为.PrjPcb,主要包含Source Documents和Libraries.Source Documents里面有S ...
- 第 10 章 使用pyecharts 进行数据展示
第 10 章 使用pyecharts 进行数据展示 10.1 安装 pyecharts pyecharts 是一个用于生成 Echarts 图表的类库, Echarts 是百度开源的一个数据可视化JS ...
- Docker部署Node应用简单实践
简介: 本文将从零至一,介绍如何在云服务器上通过 Docker 容器运行一个简单的Node应用. 前言 本文将从零至一,介绍如何在云服务器上通过 Docker 容器运行一个简单的Node应用.本文假设 ...