目录
(2)匹配非匹配范围内的主机,或者非匹配范围内的组匹配出来的主机
6.accelerate(加速模块ansible1.5版本后很少用)
1.安装并配置ansible,在控制节点上安装并配置ansible
主机清单(常见为INI格式)
一.定义主机列表
1.每行写一个
可以是域名、主机名、IP地址,此时它们没有被分到任何一个组内,属于ungroup
[student@workstation ~]$ cat myhosts
servera.xxx.com
serverb
172.25.xxx.xx
[student@workstation ~]$ ansible-inventory -i myhosts --graph #-i指定主机文件,--graph创建库存图
@all:
|--@ungrouped:
| |--172.25.xxx.xx
| |--servera.xxx.com
| |--serverb
2.主机组
(1)定义简单主机组
[student@workstation ~]$ cat myhosts1
[webservers]
servera
serverb
[dbservers]
serverc
serverd.lab.example.com
[student@workstation ~]$ ansible-inventory -i myhosts1 --graph
#默认的主机文件是/etc/ansible/hosts,使用其他文件时需要指定
@all:
|--@dbservers:
| |--serverc
| |--serverd.lab.example.com
|--@ungrouped:
|--@webservers:
| |--servera
| |--serverb
(2)指定多台主机时可以通过书写范围来表示
[student@workstation ~]$ cat myhosts2
[mywebservers]
server[a:d] #以“[x:y]”来表示从x到y的范围
[student@workstation ~]$ ansible mywebservers -i myhosts2 --list-hosts
#通过指定具体的主机文件中的组名来查看组下主机
hosts (4):
servera
serverb
serverc
serverd
(3)定义嵌套主机组
[student@workstation ~]$ cat myhosts1
[webservers]
servera
serverb
[dbservers]
serverc
serverd.lab.example.com
[conment:children] #以“:children表示包含若干组”
webservers
[student@workstation ~]$ ansible conment -i myhosts1 --list-hosts
hosts (2):
servera
serverb
二.匹配主机和组
1.匹配所有主机
(1)all
[student@workstation ~]$ ansible all -i myhosts1 --list-hosts
hosts (4):
serverc
serverd.lab.example.com
servera
serverb
(2)特殊使用*号,单独使用无效
[student@workstation ~]$ ansible * -i myhosts1 --list-hosts
[WARNING]: Could not match supplied host pattern, ignoring: myhosts1
[WARNING]: No hosts matched, nothing to do
hosts (0):
[student@workstation ~]$ ansible \* -i myhosts1 --list-hosts #转义
hosts (4):
serverc
serverd.lab.example.com
servera
serverb
[student@workstation ~]$ ansible '*' -i myhosts1 --list-hosts #单引号
hosts (4):
serverc
serverd.lab.example.com
servera
serverb
[student@workstation ~]$ ansible "*" -i myhosts1 --list-hosts #双引号
hosts (4):
serverc
serverd.lab.example.com
servera
serverb
[student@workstation ~]$ ansible '''*''' -i myhosts1 --list-hosts #三引号
hosts (4):
serverc
serverd.lab.example.com
servera
serverb
2.匹配指定主机或组
(1)匹配一个或多个组
[student@workstation ~]$ ansible webservers -i myhosts1 --list-hosts
hosts (2):
servera
serverb
[student@workstation ~]$ ansible webservers,dbservers -i myhosts1 --list-hosts
#多个组以“,”分隔,这行也可以理解为属于“webservers”或“dbservers”组的主机
hosts (4):
servera
serverb
serverc
serverd.lab.example.com
(2)匹配一个或多个主机
[student@workstation ~]$ ansible servera -i myhosts1 --list-hosts
hosts (1):
servera
[student@workstation ~]$ ansible servera,serverc -i myhosts1 --list-hosts
#多个主机以“,”分隔
hosts (2):
servera
serverc
3.匹配未分配组的主机
[student@workstation ~]$ ansible ungrouped -i myhosts1 --list-hosts
hosts (1):
haha
4.通配符匹配
(1)以什么开头或结尾的主机,或者是通过组名匹配出来的主机
[student@workstation ~]$ ansible 'server*' -i myhosts1 --list-hosts
hosts (4):
servera
serverb
serverc
serverd.lab.example.com
[student@workstation ~]$ ansible '*.com' -i myhosts1 --list-hosts
hosts (1):
serverd.lab.example.com
[student@workstation ~]$ ansible 'web*' -i myhosts1 --list-hosts
hosts (2):
servera
serverb
[student@workstation ~]$ ansible 'db*' -i myhosts1 --list-hosts
hosts (2):
serverc
serverd.lab.example.com
(2)匹配非匹配范围内的主机,或者非匹配范围内的组匹配出来的主机
[student@workstation ~]$ ansible '!*.com' -i myhosts1 --list-hosts
#使用"!"
hosts (4):
haha
serverc
servera
serverb
[student@workstation ~]$ ansible '!web*' -i myhosts1 --list-hosts
#匹配出来的是"dbservers"组内的主机
hosts (3):
haha
serverc
serverd.lab.example.com
[student@workstation ~]$ ansible 'server*,!*.com' -i myhosts1 --list-hosts
#匹配以"server"开头但不以".com"结尾的主机
hosts (3):
servera
serverb
serverc
[student@workstation ~]$ ansible 'w*,!*s' -i myhosts1 --list-hosts
#匹配以"w"开头但不以"s"结尾的组内的主机
hosts (2):
server1
serverh
[student@workstation ~]$ cat myhosts1
haha
[webservers]
servera
serverb
[dbservers]
serverc
serverd.lab.example.com
[webservers1]
server1
serverh
[conment:children]
webservers
(3)匹配包含某关键字的主机或包含某关键的组内的主机
[student@workstation ~]$ ansible '*server*' -i myhosts1 --list-hosts
hosts (6):
servera
serverb
serverc
serverd.lab.example.com
server1
serverh
[student@workstation ~]$ ansible '*web*' -i myhosts1 --list-hosts
hosts (4):
servera
serverb
server1
serverh
(4)匹配同时属于两个组的主机
[student@workstation ~]$ ansible-inventory -i myhosts1 --graph
@all:
|--@conment:
| |--@webservers:
| | |--servera
| | |--serverb
|--@dbservers:
| |--serverc
| |--serverd.lab.example.com
|--@ungrouped:
| |--haha
|--@webservers1:
| |--server1
| |--servera
| |--serverh
[student@workstation ~]$ ansible 'webservers,&webservers1' -i myhosts1 --list-hosts
#逻辑与“&”,逻辑或见“2(1)示例,逻辑非“!”见4(2)示例
hosts (1):
servera
5.正则表达式匹配
[student@workstation ~]$ ansible-inventory -i myhosts1 --graph
@all:
|--@conment:
| |--@webservers:
| | |--servera
| | |--serverb
|--@dbservers:
| |--serverc
| |--serverd.lab.example.com
|--@ungrouped:
| |--haha
|--@webservers1:
| |--server1
| |--servera
| |--serverh
[student@workstation ~]$ ansible '~^(s|c)' -i myhosts1 --list-hosts
#“~”表示标记这是一个正则表达式,以“s”开头或以“c”开头,以“s”开头的输出后,没有以“c”开头的主机,但有以“c”开头的组,会输出其下的主机
hosts (6):
servera
serverb
serverc
serverd.lab.example.com
server1
serverh
[student@workstation ~]$ ansible '~^(o|c)' -i myhosts1 --list-hosts
hosts (2):
servera
serverb
6.通过limit来匹配主机
[student@workstation ~]$ ansible server* -i myhosts1 --list-hosts --limit servera #可以在后面直接指定
hosts (1):
servera
[student@workstation ~]$ ansible server* -i myhosts1 --list-hosts --limit @list #可以指定定义好主机的文件
hosts (1):
servera
[student@workstation ~]$ cat list
servera
ansible配置文件
一.优先级
一般情况下的主要就是"ANSIBLE_CONFIG=指定.cfg文件的绝对路径" > ./ansible.cfg" > "~/.ansible.cfg" > "/etc/ansible/ansible.cfg"
[student@workstation ~]$ ansible --version
ansible 2.8.0
config file = /etc/ansible/ansible.cfg #当前使用的是"/etc/ansible/ansible.cfg"
configured module search path = ['/home/student/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible
python version = 3.6.8 (default, Apr 3 2019, 17:26:03) [GCC 8.2.1 20180905 (Red Hat 8.2.1-3)]
ANSIBLE_CONFIG用法示例
[student@workstation ~]$ cat ansible.cfg
[defaults]
inventory=/home/student/myhosts1
[student@workstation ~]$ ll
total 12
-rw-rw-r--. 1 student student 45 Oct 12 10:30 ansible.cfg
-rw-rw-r--. 1 student student 8 Oct 12 09:34 list
-rw-rw-r--. 1 student student 149 Oct 12 08:58 myhosts1
[student@workstation ~]$ ANSIBLE_CONFIG=/home/student/ansible ansible webservers --list-hosts
hosts (2):
servera
serverb
[student@workstation ~]$ ansible --version
ansible 2.8.0
config file = /home/student/ansible.cfg #此时默认配置文件就变了
configured module search path = ['/home/student/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible
python version = 3.6.8 (default, Apr 3 2019, 17:26:03) [GCC 8.2.1 20180905 (Red Hat 8.2.1-3)]
[student@workstation ~]$ export ANSIBLE_CONFIG=/home/student/ansible.cfg
#也可以export声明这个文件的路径,可以通过unset进行取消配置
[student@workstation ~]$ ansible --version
ansible 2.8.0
config file = /home/student/ansible.cfg
configured module search path = ['/home/student/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible
python version = 3.6.8 (default, Apr 3 2019, 17:26:03) [GCC 8.2.1 20180905 (Red Hat 8.2.1-3)]
二.配置文件详解
1.defaults部分
[defaults]
inventory= #指定清单文件路径
remote_user= #用来在受管节点上登录的用户名,不指定则为当前用户
become=True #连接后是否在受管节点上切换用户,一般是切换到root
become_method=sudo #以sudo方式切换,也可以选择su
become_user=root #在受管节点上要切换的用户,默认root
sudo_user=root #默认执行命令的用户
ask_sudo_pass=True #是否需要sudo密码
become_ask_pass=False #是否为切换方式提示输入密码,默认false
host_key_checking=False #首次连接时是否检查ssh主机的密钥
ask_pass=True #是否提示输入ssh连接密码,使用公钥验证应为false
library=/usr/share/my_modules/ #指定存放ansible模块的目录
timeout=10 #远程连接超时时间,以秒为单位
log_path=/var/log/ansible.log #指定ansible的日志存储文件位置
private_key_file=/path/to/file #私钥密钥路径
roles_path=/etc/ansible/roles # role存放目录
forks= 5 #设置默认多少个进程同时运行,进程并发数,默认5个
remote_port = 22 #连接受管节点的管理端口,ssh22端口
poll_interval=15 #轮询间隔时间,默认15秒
module_name = #默认执行的模块
#action_plugins = /usr/share/ansible/plugins/action
#become_plugins = /usr/share/ansible/plugins/become
#cache_plugins = /usr/share/ansible/plugins/cache
#callback_plugins = /usr/share/ansible/plugins/callback
#connection_plugins = /usr/share/ansible/plugins/connection
#lookup_plugins = /usr/share/ansible/plugins/lookup
#inventory_plugins = /usr/share/ansible/plugins/inventory
#vars_plugins = /usr/share/ansible/plugins/vars
#filter_plugins = /usr/share/ansible/plugins/filter
#test_plugins = /usr/share/ansible/plugins/test
#terminal_plugins = /usr/share/ansible/plugins/terminal
#strategy_plugins = /usr/share/ansible/plugins/strategy
#此上等等为各插件存放位置
2.privilege_escalation
[privilege_escalation]
become=True #是否切换用户
become_method=sudo #以什么方式切换
become_user=root #切换到哪个用户
become_ask_pass=False #是否需要sudo密码
3.paramiko_connection
[paramiko_connection]
record_host_keys=False #是否记录新主机的密钥,类似于保存用户在此节点的密码
pty=False #是否禁用sudo功能
look_for_keys=False #是否在~/.ssh中寻找密钥文件
host_key_auto_add=True #是否自动添加主机密钥
4.ssh_connection
[ssh_connection]
scp_if_ssh = smart
#设置传输机制,smart先尝试sftp后尝试scp,True只使用scp,False只使用sftp
transfer_method = smart
#同scp_if_ssh,两者同时设置时后者覆盖前者,但在scp_if_ssh基础上新增了piped模式表示通过ssh的'dd'来传输,并且在smart模式下,尝试传输顺序为sftp-scp-piped
sftp_batch_mode = False # 是否批处理模式来传输文件
usetty = True #是否启动管道传输
retries = 3 #重试与主机重连次数
5.persistent_connection
[persistent_connection]
connect_timeout = 30
#持久链接超时时间,在这个值之前收到连接请求,连接才不会被关闭,默认30秒
command_timeout = 30
#命令超时时间,意思是设置在连接超时前分配多少时间等待命令请求或RPC调用请求,需要小于等于持久连接超时时间
6.accelerate(加速模块ansible1.5版本后很少用)
7.selinux
[selinux]
special_context_filesystems=nfs,vboxsf,fuse,ramfs,9p
#处理selinux时需要的特殊文件系统
libvirt_lxc_noseclabel = yes
#是否允许libvirt_lxc相关链接有或没有selinux的情况下运行
8.简单测试是否能够进行节点通信
[student@workstation ~]$ cat ansible.cfg
[defaults]
inventory=/home/student/myhosts1
remote_user=root
become_user=True
become_method=sudo
host_key_checking=False
ask_pass=False
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False
[student@workstation ~]$ cat myhosts1
[webservers]
servera
serverb
[dbservers]
serverc
serverd.lab.example.com
[conment:children]
webservers
[student@workstation ~]$ ansible all -m ping
serverd.lab.example.com | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
serverc | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
serverb | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
servera | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
主机清单和配置文件练习
1.安装并配置ansible,在控制节点上安装并配置ansible
(1)创建静态inventory文件/home/devops/ansible/inventory,要求如下:
servera属于dev组
serverb属于test和balancers组
serverc和serverd属于prod组
prod组属于Webserver组
(2)创建ansible配置文件/home/devops/ansible/ansible.cfg,要求如下:
使用/home/devops/ansible/inventory清单文件
角色role目录路径为/home/devops/ansible/roles
没有/home/devops/ansible目录需要先创建该目录
[kiosk@foundation0 ~]$ rht-vmctl start all
Error: bastion not started (is already running)
Error: workstation not started (is already running)
Error: servera not started (is already running)
Error: serverb not started (is already running)
Error: serverc not started (is already running)
Error: serverd not started (is already running)
[kiosk@foundation0 ~]$ ssh devops@workstation
Activate the web console with: systemctl enable --now cockpit.socket
Last login: Mon Jun 19 18:46:41 2023 from 172.25.250.250
[devops@workstation ~]$ mkdir /home/devops/ansible
到该目录下创建inventory文件,ansible.cfg文件,roles文件,参照/etc/ansible/ansible.cfg配置内容
[devops@workstation ~]$ cd /home/devops/ansible/
[devops@workstation ansible]$ ll
total 12
-rw-r--r--. 1 root root 114 Jun 19 19:19 ansible.cfg
-rw-r--r--. 1 root root 148 Jun 19 19:19 inventory
-rw-r--r--. 1 root root 1 Jun 19 19:03 roles
[devops@workstation ~]$ cat /etc/ansible/ansible.cfg
[devops@workstation ansible]$ cat ansible.cfg
[defaults]
inventory=/home/devops/ansible/inventory
roles_path=/home/devops/ansible/roles
host_key_checking=False
[devops@workstation ansible]$ cat inventory
[dev]
servera
[test]
serverb
[balancers]
serverb
[prod]
server[c:d]
[Webserver:children]
prod
[all:vars]
ansible_user=root
ansible_password=redhat
测试连通性
[devops@workstation ansible]$ ansible all -m ping
servera | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
serverd | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
serverc | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
serverb | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
2.创建并运行 Ansibie ad-hoc 命令
创建一个 shell 脚本名为 adhoc.sh 用以运行 ad-hoc 命令 . 为每个受控节点配罝 yum仓库. 要求如下:
仓库1:
Name:RH294_Base
Description:RH294 base software
Baseurl:http://content.example.com/rhel8.0/x86_64/dvd/BaseOS
需要验证钦件包GPG签名
GPG key:/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
启用此软件仓库
仓库2:
Name:RH294_Stream
Description:RH294 stream software
Base url: http://content.example.com/rhel8.0/x86_64/dvd/AppStream
需要验证软件包GPG签名
GPG key:/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
启用此软件仓库
[devops@workstation ansible]$ sudo vim adhoc.sh
#!/bin/bash
ansible all -m yum_repository -a 'name=RH294_Base \
description="RH294 base software" \
baseurl="http://content.example.com/rhel8.0/x86_64/dvd/BaseOS" \
gpgcheck=yes \
gpgkey=/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release \
enabled=yes'
ansible all -m yum_repository -a 'name=RH294_Stream \
description="RH294 stream software" \
baseurl="http://content.example.com/rhel8.0/x86_64/dvd/AppStream" \
gpgcheck=yes \
gpgkey=/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release \
enabled=yes'
[devops@workstation ansible]$ sudo chmod +x adhoc.sh
[devops@workstation ansible]$ ./adhoc.sh
serverb | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"repo": "RH294_Base",
"state": "present"
}
serverc | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"repo": "RH294_Base",
"state": "present"
}
servera | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"repo": "RH294_Base",
"state": "present"
}
serverd | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"repo": "RH294_Base",
"state": "present"
}
serverb | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"repo": "RH294_Stream",
"state": "present"
}
servera | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"repo": "RH294_Stream",
"state": "present"
}
serverd | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"repo": "RH294_Stream",
"state": "present"
}
serverc | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"repo": "RH294_Stream",
"state": "present"
}
[devops@workstation ansible]$ ansible all -m command -a 'ls /etc/yum.repos.d'
serverd | CHANGED | rc=0 >>
redhat.repo
RH294_Base.repo
RH294_Stream.repo
rhel_dvd.repo
serverc | CHANGED | rc=0 >>
redhat.repo
RH294_Base.repo
RH294_Stream.repo
rhel_dvd.repo
servera | CHANGED | rc=0 >>
redhat.repo
RH294_Base.repo
RH294_Stream.repo
rhel_dvd.repo
serverb | CHANGED | rc=0 >>
redhat.repo
RH294_Base.repo
RH294_Stream.repo
rhel_dvd.repo
[devops@workstation ansible]$ ansible all -m command -a 'cat /etc/yum.repos.d/RH294_Base.repo'
serverd | CHANGED | rc=0 >>
[RH294_Base]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/BaseOS
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 base software
serverc | CHANGED | rc=0 >>
[RH294_Base]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/BaseOS
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 base software
serverb | CHANGED | rc=0 >>
[RH294_Base]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/BaseOS
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 base software
servera | CHANGED | rc=0 >>
[RH294_Base]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/BaseOS
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 base software
[devops@workstation ansible]$ ansible all -m command -a 'cat /etc/yum.repos.d/RH294_Stream.repo'
serverd | CHANGED | rc=0 >>
[RH294_Stream]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/AppStream
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 stream software
serverc | CHANGED | rc=0 >>
[RH294_Stream]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/AppStream
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 stream software
serverb | CHANGED | rc=0 >>
[RH294_Stream]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/AppStream
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 stream software
servera | CHANGED | rc=0 >>
[RH294_Stream]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/AppStream
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 stream software