ansible笔记3:深入应用
3. 深入应用
3.1 Inventory进阶
3.1.1 复杂群组
我们使用编写yaml格式的配置案例来测试inventory如何定义丰富的信息
all:
hosts:
vars:
ansible_ssh_user: root
ansible_ssh_port: 22
ansible_ssh_pass: server_default_password
children:
test_01:
hosts:
10.3.10.40:
vars:
ansible_ssh_pass: GIMDvZcgqhaYhWk9
children:
test_01_01:
hosts:
192.168.1.1:
vars:
ansible_ssh_pass: JNc3k8jIl32ack1D
test_02:
hosts:
192.168.1.2:
test_03:
hosts:
192.168.1.3:
vars:
ansible_ssh_user: root
ansible_ssh_port: 22
ansible_ssh_pass: server_default_password
这里我们就定义了两个群组 test_01、test_02、test_03,且都属于 all 群组下
在上面的配置文件里,体现了 child in child 这种多层次群组的嵌套方式,有几点要注意:
- 任何在 child group 的节点都会属于 parent group
- child group 的变量 vars 都会覆盖 parent group 的变量
- 节点(主机)可以属于多个 group,但重复调用时只会跑一次
3.1.2 动态配置
上面讨论的都是静态的inventory,inventory以文件的形式存储在配置文件中,如有变更需要及时更新配置文件
有一种方式可以直接获取变更,免去文件的读写操作,即动态inventory
关于如何编写动态inventory,请移步到 开发者文档 dev inventory 部分,在Users Guide找半天就是不说怎么写,又在网上搜索了一大堆不靠谱文章,浪费大把时间。后面发现原来在 Dev Guide..
几点要求:
- 可以是脚本文件,或者是二进制可执行文件
- 要支持 --list / --host <hostname> 两个参数,别的参数如何无所谓,ansible不会支持
同样基于上面的数据,我们写一个动态的inventory案例
#!/app/ansible/py36/bin/python
# -*- coding: utf-8 -*-
# @Date: 2020-03-16
# @File: dynamic_inventory_example.py
# @Author: zhangwei
# @Desc: dynamic inventory
import argparse
import json
inventory = {
"all": {
"hosts": [],
"vars": {
"ansible_ssh_user": "root",
"ansible_ssh_port": 22
},
"children": []
},
"test_01": {
"hosts": [
"10.3.10.40"
],
"vars": {
"ansible_ssh_pass": "GIMDvZcgqhaYhWk9"
},
"children": ["test_01_01"]
},
"test_01_01": {
"hosts": [
"192.168.1.1"
],
"vars": {
"ansible_ssh_port": 25,
"ansible_ssh_pass": "other_password"
},
"children": []
},
"test_02": {
"hosts": [
"192.168.1.2"
],
"vars": {
"ansible_ssh_pass": "other_password"
},
"children": []
},
"_meta": {
"hostvars": {
"10.3.10.40": {
"ext_key": "ext_value"
}
}
}
}
if __name__ == "__main__":
# script argument
parser = argparse.ArgumentParser(description='Ansible Dynamic Inventory Script')
parser.add_argument('--list', action="store_true", help='List All Host')
parser.add_argument('--host', type=str, help='<hostname> Show Host Args')
args = parser.parse_args()
if args.list:
print(json.dumps(inventory, indent=4))
elif args.host:
pass
然后我们试一下,正常工作了
(py36) [root@VM_10_40_centos ansible-etc]# ansible -i inventory_dynamic_example.py test_01 -m ping
10.3.10.40 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.1.1 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: ssh: connect to host 192.168.1.1 port 25: Connection timed out",
"unreachable": true
}
对于动态inventory,可以使用 ansible-inventory 进行测试
# ansible-inventory 执行 --list
(py36) [root@VM_10_40_centos ansible-etc]# ansible-inventory -i inventory_dynamic_example.py --list
{
"_meta": {
"hostvars": {
"10.3.10.40": {
"ansible_ssh_pass": "GIMDvZcgqhaYhWk9",
"ansible_ssh_port": 22,
"ansible_ssh_user": "root",
"ext_key": "ext_value"
},
"192.168.1.1": {
"ansible_ssh_pass": "other_password",
"ansible_ssh_port": 25,
"ansible_ssh_user": "root"
},
"192.168.1.2": {
"ansible_ssh_pass": "other_password",
"ansible_ssh_port": 22,
"ansible_ssh_user": "root"
}
}
},
"all": {
"children": [
"test_01",
"test_02",
"ungrouped"
]
},
"test_01": {
"children": [
"test_01_01"
],
"hosts": [
"10.3.10.40"
]
},
"test_01_01": {
"hosts": [
"192.168.1.1"
]
},
"test_02": {
"hosts": [
"192.168.1.2"
]
}
}
# ansible-inventory 执行 ——host
(py36) [root@VM_10_40_centos ansible-etc]# ansible-inventory -i inventory_dynamic_example.py --host 10.3.10.40
{
"ansible_ssh_pass": "GIMDvZcgqhaYhWk9",
"ansible_ssh_port": 22,
"ansible_ssh_user": "root",
"ext_key": "ext_value"
}
抱着看报什么错误的心态跑了一下 --host,结果发现脚本中没有定义的 --host 执行内容实际上是有效的.....
好了,后面就可以丰富脚本,去生成你要的 inventory json
3.2 参数变量的应用
3.2.1 内置变量Facts
ansible默认支持的变量,也就是受控节点的一些基本信息,通过 -m setup 查看
(py36) [root@VM_10_40_centos ansible-etc]# ansible 10.3.10.40 -m setup
10.3.10.40 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"10.3.10.40"
],
"ansible_all_ipv6_addresses": [
"fe80::5054:ff:fed6:ebdd"
],
"ansible_apparmor": {
"status": "disabled"
},
"ansible_architecture": "x86_64",
"ansible_bios_date": "01/01/2011",
"ansible_bios_version": "Bochs",
"ansible_cmdline": {
"BOOT_IMAGE": "/boot/vmlinuz-3.10.0-1062.9.1.el7.x86_64",
"biosdevname": "0",
"console": "tty0",
"crashkernel": "auto",
"intel_idle.max_cstate": "1",
"intel_pstate": "disable",
"net.ifnames": "0",
"panic": "5",
"ro": true,
"root": "UUID=4b499d76-769a-40a0-93dc-4a31a59add28"
},
"ansible_date_time": {
"date": "2020-03-17",
"day": "17",
"epoch": "1584409698",
"hour": "09",
"iso8601": "2020-03-17T01:48:18Z",
"iso8601_basic": "20200317T094818993597",
"iso8601_basic_short": "20200317T094818",
"iso8601_micro": "2020-03-17T01:48:18.993682Z",
"minute": "48",
"month": "03",
"second": "18",
"time": "09:48:18",
"tz": "CST",
"tz_offset": "+0800",
"weekday": "Tuesday",
"weekday_number": "2",
"weeknumber": "11",
"year": "2020"
},
"ansible_default_ipv4": {
"address": "10.3.10.40",
"alias": "eth0",
"broadcast": "10.3.10.255",
"gateway": "10.3.10.1",
"interface": "eth0",
"macaddress": "52:54:00:d6:eb:dd",
"mtu": 1500,
"netmask": "255.255.255.0",
"network": "10.3.10.0",
"type": "ether"
},
"ansible_default_ipv6": {
"address": "fe80::5054:ff:fed6:ebdd",
"interface": "eth0",
"macaddress": "52:54:00:d6:eb:dd",
"mtu": 1500,
"prefix": "64",
"scope": "link",
"type": "ether"
},
"ansible_device_links": {
"ids": {
"sr0": [
"ata-QEMU_DVD-ROM_QM00002"
],
"vdb": [
"virtio-ldisk-9is7nzkj"
],
"vdb1": [
"virtio-ldisk-9is7nzkj-part1"
]
},
"labels": {
"sr0": [
"config-2"
]
},
"masters": {},
"uuids": {
"sr0": [
"2020-03-12-09-07-17-00"
],
"vda1": [
"4b499d76-769a-40a0-93dc-4a31a59add28"
],
"vdb1": [
"f802cf19-867e-42ad-b6bd-382bea0222fd"
]
}
},
"ansible_devices": {
"loop0": {
"holders": [],
"host": "",
"links": {
"ids": [],
"labels": [],
"masters": [],
"uuids": []
},
"model": null,
"partitions": {},
"removable": "0",
"rotational": "1",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "",
"sectors": "0",
"sectorsize": "512",
"size": "0.00 Bytes",
"support_discard": "0",
"vendor": null,
"virtual": 1
},
"sr0": {
"holders": [],
"host": "IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II]",
"links": {
"ids": [
"ata-QEMU_DVD-ROM_QM00002"
],
"labels": [
"config-2"
],
"masters": [],
"uuids": [
"2020-03-12-09-07-17-00"
]
},
"model": "QEMU DVD-ROM",
"partitions": {},
"removable": "1",
"rotational": "1",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "deadline",
"sectors": "83964",
"sectorsize": "2048",
"size": "41.00 MB",
"support_discard": "0",
"vendor": "QEMU",
"virtual": 1
},
"vda": {
"holders": [],
"host": "SCSI storage controller: Red Hat, Inc. Virtio block device",
"links": {
"ids": [],
"labels": [],
"masters": [],
"uuids": []
},
"model": null,
"partitions": {
"vda1": {
"holders": [],
"links": {
"ids": [],
"labels": [],
"masters": [],
"uuids": [
"4b499d76-769a-40a0-93dc-4a31a59add28"
]
},
"sectors": "104855519",
"sectorsize": 512,
"size": "50.00 GB",
"start": "2048",
"uuid": "4b499d76-769a-40a0-93dc-4a31a59add28"
}
},
"removable": "0",
"rotational": "1",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "mq-deadline",
"sectors": "104857600",
"sectorsize": "512",
"size": "50.00 GB",
"support_discard": "0",
"vendor": "0x1af4",
"virtual": 1
},
"vdb": {
"holders": [],
"host": "SCSI storage controller: Red Hat, Inc. Virtio block device",
"links": {
"ids": [
"virtio-ldisk-9is7nzkj"
],
"labels": [],
"masters": [],
"uuids": []
},
"model": null,
"partitions": {
"vdb1": {
"holders": [],
"links": {
"ids": [
"virtio-ldisk-9is7nzkj-part1"
],
"labels": [],
"masters": [],
"uuids": [
"f802cf19-867e-42ad-b6bd-382bea0222fd"
]
},
"sectors": "419428352",
"sectorsize": 512,
"size": "200.00 GB",
"start": "2048",
"uuid": "f802cf19-867e-42ad-b6bd-382bea0222fd"
}
},
"removable": "0",
"rotational": "1",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "mq-deadline",
"sectors": "419430400",
"sectorsize": "512",
"size": "200.00 GB",
"support_discard": "0",
"vendor": "0x1af4",
"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.6",
"ansible_dns": {
"nameservers": [
"183.60.83.19",
"183.60.82.98"
]
},
"ansible_domain": "",
"ansible_effective_group_id": 0,
"ansible_effective_user_id": 0,
"ansible_env": {
"HISTSIZE": "3000",
"HISTTIMEFORMAT": "%F %T ",
"HOME": "/root",
"LANG": "en_US.UTF-8",
"LESSOPEN": "||/usr/bin/lesspipe.sh %s",
"LOGNAME": "root",
"LS_COLORS": "rs=0:di=38;5;27:ln=38;5;51:mh=44;38;5;15:pi=40;38;5;11:so=38;5;13:do=38;5;5:bd=48;5;232;38;5;11:cd=48;5;232;38;5;3:or=48;5;232;38;5;9:mi=05;48;5;232;38;5;15:su=48;5;196;38;5;15:sg=48;5;11;38;5;16:ca=48;5;196;38;5;226:tw=48;5;10;38;5;16:ow=48;5;10;38;5;21:st=48;5;21;38;5;15:ex=38;5;34:*.tar=38;5;9:*.tgz=38;5;9:*.arc=38;5;9:*.arj=38;5;9:*.taz=38;5;9:*.lha=38;5;9:*.lz4=38;5;9:*.lzh=38;5;9:*.lzma=38;5;9:*.tlz=38;5;9:*.txz=38;5;9:*.tzo=38;5;9:*.t7z=38;5;9:*.zip=38;5;9:*.z=38;5;9:*.Z=38;5;9:*.dz=38;5;9:*.gz=38;5;9:*.lrz=38;5;9:*.lz=38;5;9:*.lzo=38;5;9:*.xz=38;5;9:*.bz2=38;5;9:*.bz=38;5;9:*.tbz=38;5;9:*.tbz2=38;5;9:*.tz=38;5;9:*.deb=38;5;9:*.rpm=38;5;9:*.jar=38;5;9:*.war=38;5;9:*.ear=38;5;9:*.sar=38;5;9:*.rar=38;5;9:*.alz=38;5;9:*.ace=38;5;9:*.zoo=38;5;9:*.cpio=38;5;9:*.7z=38;5;9:*.rz=38;5;9:*.cab=38;5;9:*.jpg=38;5;13:*.jpeg=38;5;13:*.gif=38;5;13:*.bmp=38;5;13:*.pbm=38;5;13:*.pgm=38;5;13:*.ppm=38;5;13:*.tga=38;5;13:*.xbm=38;5;13:*.xpm=38;5;13:*.tif=38;5;13:*.tiff=38;5;13:*.png=38;5;13:*.svg=38;5;13:*.svgz=38;5;13:*.mng=38;5;13:*.pcx=38;5;13:*.mov=38;5;13:*.mpg=38;5;13:*.mpeg=38;5;13:*.m2v=38;5;13:*.mkv=38;5;13:*.webm=38;5;13:*.ogm=38;5;13:*.mp4=38;5;13:*.m4v=38;5;13:*.mp4v=38;5;13:*.vob=38;5;13:*.qt=38;5;13:*.nuv=38;5;13:*.wmv=38;5;13:*.asf=38;5;13:*.rm=38;5;13:*.rmvb=38;5;13:*.flc=38;5;13:*.avi=38;5;13:*.fli=38;5;13:*.flv=38;5;13:*.gl=38;5;13:*.dl=38;5;13:*.xcf=38;5;13:*.xwd=38;5;13:*.yuv=38;5;13:*.cgm=38;5;13:*.emf=38;5;13:*.axv=38;5;13:*.anx=38;5;13:*.ogv=38;5;13:*.ogx=38;5;13:*.aac=38;5;45:*.au=38;5;45:*.flac=38;5;45:*.mid=38;5;45:*.midi=38;5;45:*.mka=38;5;45:*.mp3=38;5;45:*.mpc=38;5;45:*.ogg=38;5;45:*.ra=38;5;45:*.wav=38;5;45:*.axa=38;5;45:*.oga=38;5;45:*.spx=38;5;45:*.xspf=38;5;45:",
"MAIL": "/var/mail/root",
"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin",
"PROMPT_COMMAND": "history -a; ",
"PWD": "/root",
"SHELL": "/bin/bash",
"SHLVL": "2",
"SSH_CLIENT": "10.3.10.40 44956 22",
"SSH_CONNECTION": "10.3.10.40 44956 10.3.10.40 22",
"SSH_TTY": "/dev/pts/3",
"TERM": "xterm-256color",
"USER": "root",
"XDG_RUNTIME_DIR": "/run/user/0",
"XDG_SESSION_ID": "14407",
"_": "/usr/bin/python"
},
"ansible_eth0": {
"active": true,
"device": "eth0",
"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": "off [fixed]",
"netns_local": "off [fixed]",
"ntuple_filters": "off [fixed]",
"receive_hashing": "off [fixed]",
"rx_all": "off [fixed]",
"rx_checksumming": "on [fixed]",
"rx_fcs": "off [fixed]",
"rx_gro_hw": "off [fixed]",
"rx_udp_tunnel_port_offload": "off [fixed]",
"rx_vlan_filter": "on [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",
"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_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": "on",
"tx_tcp_ecn_segmentation": "on",
"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": "off [fixed]",
"tx_vlan_stag_hw_insert": "off [fixed]",
"udp_fragmentation_offload": "on",
"vlan_challenged": "off [fixed]"
},
"hw_timestamp_filters": [],
"ipv4": {
"address": "10.3.10.40",
"broadcast": "10.3.10.255",
"netmask": "255.255.255.0",
"network": "10.3.10.0"
},
"ipv6": [
{
"address": "fe80::5054:ff:fed6:ebdd",
"prefix": "64",
"scope": "link"
}
],
"macaddress": "52:54:00:d6:eb:dd",
"module": "virtio_net",
"mtu": 1500,
"pciid": "virtio0",
"promisc": false,
"timestamping": [
"rx_software",
"software"
],
"type": "ether"
},
"ansible_fibre_channel_wwn": [],
"ansible_fips": false,
"ansible_form_factor": "Other",
"ansible_fqdn": "VM_10_40_centos",
"ansible_hostname": "VM_10_40_centos",
"ansible_hostnqn": "",
"ansible_interfaces": [
"lo",
"eth0"
],
"ansible_is_chroot": false,
"ansible_iscsi_iqn": "iqn.1994-05.com.redhat:b83e0e28a2",
"ansible_kernel": "3.10.0-1062.9.1.el7.x86_64",
"ansible_kernel_version": "#1 SMP Fri Dec 6 15:49:49 UTC 2019",
"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_gro_hw": "off [fixed]",
"rx_udp_tunnel_port_offload": "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_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": "host",
"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": {},
"pvs": {},
"vgs": {}
},
"ansible_machine": "x86_64",
"ansible_machine_id": "0ea734564f9a4e2881b866b82d679dfc",
"ansible_memfree_mb": 218,
"ansible_memory_mb": {
"nocache": {
"free": 4294,
"used": 3527
},
"real": {
"free": 218,
"total": 7821,
"used": 7603
},
"swap": {
"cached": 0,
"free": 0,
"total": 0,
"used": 0
}
},
"ansible_memtotal_mb": 7821,
"ansible_mounts": [
{
"block_available": 48708094,
"block_size": 4096,
"block_total": 51572986,
"block_used": 2864892,
"device": "/dev/vdb1",
"fstype": "ext4",
"inode_available": 13092849,
"inode_total": 13107200,
"inode_used": 14351,
"mount": "/app",
"options": "rw,relatime,data=ordered",
"size_available": 199508353024,
"size_total": 211242950656,
"uuid": "f802cf19-867e-42ad-b6bd-382bea0222fd"
},
{
"block_available": 11055498,
"block_size": 4096,
"block_total": 12868467,
"block_used": 1812969,
"device": "/dev/vda1",
"fstype": "ext4",
"inode_available": 3079802,
"inode_total": 3276800,
"inode_used": 196998,
"mount": "/",
"options": "rw,relatime,data=ordered",
"size_available": 45283319808,
"size_total": 52709240832,
"uuid": "4b499d76-769a-40a0-93dc-4a31a59add28"
}
],
"ansible_nodename": "VM_10_40_centos",
"ansible_os_family": "RedHat",
"ansible_pkg_mgr": "yum",
"ansible_proc_cmdline": {
"BOOT_IMAGE": "/boot/vmlinuz-3.10.0-1062.9.1.el7.x86_64",
"biosdevname": "0",
"console": [
"ttyS0",
"tty0"
],
"crashkernel": "auto",
"intel_idle.max_cstate": "1",
"intel_pstate": "disable",
"net.ifnames": "0",
"panic": "5",
"ro": true,
"root": "UUID=4b499d76-769a-40a0-93dc-4a31a59add28"
},
"ansible_processor": [
"0",
"GenuineIntel",
"Intel(R) Xeon(R) CPU E5-26xx v4",
"1",
"GenuineIntel",
"Intel(R) Xeon(R) CPU E5-26xx v4",
"2",
"GenuineIntel",
"Intel(R) Xeon(R) CPU E5-26xx v4",
"3",
"GenuineIntel",
"Intel(R) Xeon(R) CPU E5-26xx v4"
],
"ansible_processor_cores": 4,
"ansible_processor_count": 1,
"ansible_processor_threads_per_core": 1,
"ansible_processor_vcpus": 4,
"ansible_product_name": "Bochs",
"ansible_product_serial": "64b8834e-05b5-49a4-b257-530a27e445cc",
"ansible_product_uuid": "64B8834E-05B5-49A4-B257-530A27E445CC",
"ansible_product_version": "NA",
"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_dsa_public": "AAAAB3NzaC1kc3MAAACBAL/JsybiJu1gwQ/FQQpiu6bfNlMYe3Bx7iubTxySn0wL3021Z/hiJ4SL6qqFUX44+reC+vGBgZVcDCPUTHv3Kai9ur1q3AjRT5WvnhXvGZzAR6qi3c08wjLkRyInhllFc4vSXHwS1w2PelNLk7wpd6JRTEohaqDWgHl4XF8lEHaZAAAAFQDQT5AZ71Va6ygGq+GC2kMx+zKODQAAAIAM2hXMgDzr4BMLqmVwV4QIfKAtBIoa4iM3kDylXeZbMVvKX467n68byql+09kRoRr8kivGgqgEQ2gChZPOhPVyCHuYL+3Nt93sOLGqrgY1g7vk1voPUGCey5VL8ZUV7L8UrRPug0yykGEEDf5Pl4Zg/AGhCiuQSIogMfY+eoMbVQAAAIEAlD5p/WTB1/LkGaiOFBumFMxyfQMcmsRo4Ol8/4s5TDwp3x9wqJAM0iM1N7EU4wT5REYXmsGAO3ZSjsgN3Mgvd4JL2FhijSWfzmqLP/fVY9HNQ2q1ssCYMOV0H888xdgzYkMyPnufRDNXREXCsTUD6BFOF8YIIEnNNtcVBbSTPdw=",
"ansible_ssh_host_key_ecdsa_public": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMchCmHEoMaRlvH2hYpcJIc0PoOQOJX4HAn/8o2sMUHgQihqFzqXW1weLXF9ZRGZ2NtS2k2Dk+EQGl+59WzsfFc=",
"ansible_ssh_host_key_ed25519_public": "AAAAC3NzaC1lZDI1NTE5AAAAIJ/yY6/qip1oM5srwb+Ms1mUF2K4jVA/44eJ1SlX55Xj",
"ansible_ssh_host_key_rsa_public": "AAAAB3NzaC1yc2EAAAADAQABAAABAQCuMA4GEXCZyCYptOxTslUZpdADT5xyXAlkewi+qoUEjQNnNd/yZAxUFo8NUIOppDOSQHZJWmEQ5b4bhyrsu/eu9+y9FPkC3VYRNUGc532nuGbQUqdgd+Jyt3ucoKWY9SC2Q/IujMEgLqUvKXoBiIP3qDrBJOzp02qpgjcnw8HyBM2IE6DeRnGpcbJCRGJGtjZNB6eGg21H4/BWDd8x8pISueS5VZWkFBFtlPcnyGuWIOaN3jXl5ooDL1z3w6/mgMnOOMQhAwN6wGuycRCH33+0O2nc+qWwLNou4J9BW/ij6h+UEYXcbKSScAmDJ+nSMKChehIu/utBl5gDABf2h+Ov",
"ansible_swapfree_mb": 0,
"ansible_swaptotal_mb": 0,
"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": "Bochs",
"ansible_uptime_seconds": 432700,
"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": "kvm",
"discovered_interpreter_python": "/usr/bin/python",
"gather_subset": [
"all"
],
"module_setup": true
},
"changed": false
}
3.2.2 playbook判断
当你同一个集群下的主机配置有差异时,在playbook内应用条件判断就十分方便了。这里就拿官方例子不测试了
这个playbook的意思是关闭 test_01 群组中的 centos6 主机
- hosts: test_01
tasks:
- name: "shut down CentOS 6 systems"
command: /sbin/shutdown -t now
when:
- ansible_facts['distribution'] == "CentOS"
- ansible_facts['distribution_major_version'] == "6"
当然非常不建议用这个,同一集群环境尽可能做到统一,或者尽量拆分到不同组
3.2.3 文件模板
这些变量可以应用在多处,例如应用在playbook。
我们新建一个 playbook,playbook-jinja2-example.yml。传递一个模板到 /tmp/j2_example.txt
- hosts: 10.3.10.40
tasks:
- name: Jinja2 Template Example
template:
src: /app/ansible/ansible-playbook/{{ ansible_fqdn }}.j2
dest: /tmp/j2_example.txt
owner: root
group: root
mode: '0644'
backup: yes
然后执行这个playbook,可以发现报错了,报错信息是 VM_10_40_centos.j2 这个文件不存在
(py36) [root@VM_10_40_centos ansible-playbook]# ansible-playbook playbook-jinja2-example.yml
PLAY [10.3.10.40] ***********************************************************************************************
TASK [Gathering Facts] ******************************************************************************************
ok: [10.3.10.40]
TASK [Jinja2 Template Example] **********************************************************************************
fatal: [10.3.10.40]: FAILED! => {"changed": false, "msg": "Could not find or access '/app/ansible/ansible-playbook/VM_10_40_centos.j2' on the Ansible Controller.\nIf you are using a module and expect the file to exist on the remote, see the remote_src option"}
PLAY RECAP ******************************************************************************************************
10.3.10.40 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
这就是 facts 变量在 playbook 内的用法
这里应用到了另外一个点,jinja2的模板语法,详见:jinja2文档
关于 jinja2 的一些基本的应用为
- 如果a是字典,则{{ a['key'] }}
- 如果a是列表,则{{ a[0] }}
我们现在补充一下这个文件:/app/ansible/ansible-playbook/VM_10_40_centos.j2
让它遍历一下 facts 中的 interfaces 数据
{% for item in ansible_interfaces %}
interface: {{ item }}
{% endfor %}
再次执行,我们就得到了目标文件 /tmp/j2_example.txt,核实内容
(py36) [root@VM_10_40_centos ansible-playbook]# cat /tmp/j2_example.txt
interface: lo
interface: eth0
其实内外变量的使用差不多,就一起了
修改一下我们刚刚的playbook,添加自己的vars,例如packages
- hosts: 10.3.10.40
tasks:
- name: Jinja2 Template Example
template:
src: /app/ansible/ansible-playbook/{{ ansible_fqdn }}.j2
dest: /tmp/j2_example.txt
owner: root
group: root
mode: '0644'
backup: yes
vars:
packages:
- python3
- python3-devel
- nginx
在修改一下我们的模板文件
{% for item in packages %}
packages: {{ item }}
{% endfor %}
执行playbook,我们就得到了下面的文件
(py36) [root@VM_10_40_centos ansible-playbook]# cat /tmp/j2_example.txt
packages: python3
packages: python3-devel
packages: nginx
3.2.4 自定义Facts
目前用不上,后面待补充
3.3 同步和异步处理
3.3.1 fork参数
关于 -f 参数的说明:即一次性跑多少个节点,默认是5个
-f FORKS, --forks FORKS
specify number of parallel processes to use
(default=5)
当执行节点数
埋个坑,后面更...