Ansible 使用介绍
环境信息
- Centos 7
- ansible-core 2.16
- Docker image python:3.12.3
安装
ansible-core
版本及 Python 版本支持对应关系
ansible-core Version | Control Node Python | Target Python / PowerShell |
---|---|---|
2.16 | Python 3.10 - 3.12 | Python 2.7 Python 3.6 - 3.12 Powershell 3 - 5.1 |
为了环境部署方便灵活,可以选择使用 python:3.12.3
的 Docker 镜像,以其为基础环境安装 ansible-core 2.16
或者直接使用 ansible
镜像启动。
docker run --rm -it python:3.12.3 bash |
配置
Ansible 主配置文件为 /etc/ansible/ansible.cfg
,其中的配置都可以被 ansible-playbook
或者命令行参数覆盖。
ansible 默认会读取环境变量
ANSIBLE_CONFIG
指定的配置文件,当前路径下的ansible.cfg
,以及用户家目录下的.ansible.cfg
,以及/etc/ansible/ansible.cfg
作为配置文件,已第一个找到的为准
常用配置说明
配置项 | 说明 | 示例 |
---|---|---|
inventory |
指定 inventory (主机列表)文件的路径,默认为 /etc/ansible/hosts |
|
remote_user |
(未指定用户时)连接远程主机时使用的用户 | |
remote_port |
连接远程主机时使用的(默认)端口 | |
host_key_checking |
默认启用。检查主机密钥可以防止服务器欺骗和中间人攻击。 如果主机重新安装并且在 know_hosts 中拥有不同的密钥,ansible 会提示确认密钥。如果要禁用此行为,可以配置为 False |
|
ask_pass |
默认为 False。当设置为 True 时,ansible 要求输入远端服务器的密码,即使配置了免密登录 | |
log_path |
日志文件,默认 /var/log/ansible.log |
|
pattern |
当没有给出 pattern 时的默认 pattern ,默认值是 * 即所有主机 |
inventory 配置文件
默认的 inventory 配置文件路径为 /etc/ansible/hosts
,主要用来配置 Managed Hosts 列表
主机列表中的主机可以单独出现,也可以位于某个或者多个组中([]
开头的行)
ansible-demo1.local |
常用配置说明
配置项 | 说明 | 示例 |
---|---|---|
ansible_ssh_host |
远程主机地址 | |
ansible_ssh_port |
远程主机端口 | |
ansible_ssh_user |
连接远程主机的 ssh 用户 | |
ansible_ssh_pass |
连接远程主机的 ssh 用户密码,建议使用 key 连接 | |
ansible_ssh_private_key_file |
连接远程主机的 ssh 私钥文件路径 | |
ansible_sudo_pass |
sudo 密码(这种方式并不安全,强烈建议使用 --ask-sudo-pass ) |
|
ansible_connection |
与主机的连接类型.比如:local , ssh 或者 paramiko Ansible 1.2 以前默认使用 paramiko 。1.2 以后默认使用 smart ,smart 方式会根据是否支持 ControlPersist , 来判断 ssh 方式是否可行. |
|
ansible_shell_type |
目标系统的 shell 类型.默认情况下,命令的执行使用 sh 语法,可设置为 csh 或 fish . |
|
ansible_python_interpreter |
目标主机的 python 路径 系统中有多个 Python, 或者命令路径不是 /usr/bin/python |
变量
在 inventory 的配置中,可以添加变量,以在 playbook 中使用变量,实现对不同主机的个性化配置。变量分好几个层级:
- 主机变量: 跟在主机后面直接设置,变量的作用域仅限于主机。由于对变量名没有限制,所以前面的那些 ansible 的配置如果打错字了也不会报错,ansible 会认为这是一个主机变量
/etc/ansible/hosts 127.0.0.1 http_port=80 maxRequestPerChild=808
- 组变量: 组变量需要新开一个 section, 配置在名为 [组名:vars] 的 section 中
/etc/ansible/hosts [localloops]
127.0.0.[1:5] ansible_connection=paramiko ansible_ssh_user=root
[localloops:vars]
http_port=8080
ansible 使用
在配置好 inventory 后,要使 ansible 可以连接到 Managed Host,需要使用密码或者 key 的方式进行认证,建议使用 Private Key 的方式进行认证。参考文档配置 ssh 公私钥免密码认证过程
配置完 hosts 之后,在命令行中可以调用一些命令来使用 ansible,如 ansible all -m ping
。命令行的 ansible 工具大体格式如下:
ansible <pattern> -m <module> -a <arguments> |
pattern
是一个标识,指定出了要操作的目标主机,可以使用以下方式匹配主机:
all
代表所有主机section 名
代表组内的所有主机主机名
代表一个主机。如果主机名和组名冲突,则以先出现的为准。ip/域名
或者192.168.1.*
代表一个 IP 或者一组 IPa:b
a 和 b 都是组,取得两个组的并集。 a 和 b 都是 host,表示 或 的关系a:!b
a 和 b 都是组,取得属于 a 但是不属于 b 组中的主机a:&b
a组和b组的交集a[0]
取得 a 组中的第一个主机,依次类推。a[0:25]
代表 a 组中的第 1 个到第 25 个主机,也可以使用a[0-25]
ansible 命令常用选项
选项 | 说明 | 示例 |
---|---|---|
-m, --module-name |
指定模块 默认为 command |
ansible all -m ping |
--become-user 'BECOME_USER' |
切换到指定的用户执行操作,默认为 root 需要配合 -b, --become 选项使用 |
ansible all -m command -a "ls /root/" -b --become-user root |
-b, --become |
提升权限到 root 权限,需要用户有 sudo 权限 |
|
--list-hosts |
列出 pattern 匹配的主机列表,不执行其他任何操作 | ansible --list-hosts |
-C, --check |
不执行任何实际操作,而是对要执行的操作进行验证 | |
-k, --ask-pass |
询问连接密码 | |
-o, --one-line |
输出到一行里面 | |
-f ,--forks |
指定并发执行的数量,默认为 5 |
ansible 常用模块
command
command
是 ansible 默认的模块。command 模块不支持 shell 变量,也不支持管道等 shell 相关的东西.如果你想使用 shell 相关的这些东西, 请使用 shell
模块. [2]
shell
shell
模块启动一个 shell
然后执行命令
ansible raleigh -m shell -a 'echo $TERM' |
使用 Ansible ad hoc 命令行接口时(与使用 Playbooks 的情况相反),尤其要注意 shell 引号的规则。比如在上面的例子中,如果使用双引号 "echo $TERM"
,会求出 TERM
变量在当前系统的值,而我们实际希望的是把这个命令传递 到其它机器执行。
ping
用来测试到目标服务器的连通性
ansible all -m ping |
setup
使用 setup
模块,ansible 可以收集各个 Managed Hosts 的 facts,其中包含了 Managed Hosts 的很多元数据。
ansible k8s-master-nodes[0] -m setup |
配合 setup
模块的 filter
参数,可以从输出中过滤出各种信息
ansible fm-k8s-uat-master-nodes[0] -m setup -a "filter=ansible_default_ipv4" |
常见错误
Permission denied
在以普通用户 ssh 登陆远程主机(Managed Host)的情况下,执行某些操作可能因为普通用户权限不足导致操作失败
ansible my-hosts -m command -a "cat /root/.ssh/authorized_keys" |
此种情况,可以使用以下方式解决。***前提是远程登陆使用的用户具有 sudo
权限***。建议使用 -b
选项。
- 使用
sudo
命令。如果用户没有sudo
权限,ansible 会被阻塞,后台等待用户输入sudo
密码,直到等待超时失败。具体报错参考以下示例中的k8s-master2
输出ansible my-hosts -m command -a "sudo cat /root/.ssh/authorized_keys"
k8s-master1 | CHANGED | rc=0 >>
no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="echo 'Please login as the user \"centos\" rather than the user \"root\".';echo;sleep 10" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCGKLNMv82MQJUuQ9aZPsDofBj96aQlS1kNV2doSwyLatgMNBZ6rzgQuNOJ2DH87IzD1mZ0wL7iApvk6gkxSxcz5tmbU8dfYOYJdlBlhxGk2Nkg2V3P9FPC0hBY73szEV+1DUoqwl+COAsAXO9Uiebr0faQvWOkVT7pypunnjPrBBUaaXn2IcoPIdXZfXVLjXH2JbWSHL5J+yIGHewSMzZ/Xx7u6hwxUP0QLFHrnhD0WDukoBjoUZ2sshMP+DHgoyWjCg+uVpmjJAksp80f34WfNku5Grt90kYEj+N+x2JQ1Y4aQIXASIwDshicbJIsl+RMIMmwe+TElUJ6g9aa0qCr op2-east1-1031
k8s-master3 | CHANGED | rc=0 >>
no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="echo 'Please login as the user \"centos\" rather than the user \"root\".';echo;sleep 10" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCGKLNMv82MQJUuQ9aZPsDofBj96aQlS1kNV2doSwyLatgMNBZ6rzgQuNOJ2DH87IzD1mZ0wL7iApvk6gkxSxcz5tmbU8dfYOYJdlBlhxGk2Nkg2V3P9FPC0hBY73szEV+1DUoqwl+COAsAXO9Uiebr0faQvWOkVT7pypunnjPrBBUaaXn2IcoPIdXZfXVLjXH2JbWSHL5J+yIGHewSMzZ/Xx7u6hwxUP0QLFHrnhD0WDukoBjoUZ2sshMP+DHgoyWjCg+uVpmjJAksp80f34WfNku5Grt90kYEj+N+x2JQ1Y4aQIXASIwDshicbJIsl+RMIMmwe+TElUJ6g9aa0qCr op2-east1-1031
k8s-master2 | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"module_stderr": "Shared connection to 172.31.30.115 closed.\r\n",
"module_stdout": "[sudo] password for centos: \r\n\r\n{\"changed\": true, \"end\": \"2023-09-01 09:24:40.247480\", \"stdout\": \"\", \"cmd\": [\"sudo\", \"cat\", \"/root/.ssh/authorized_keys\"], \"failed\": true, \"delta\": \"0:05:02.696092\", \"stderr\": \"\\nWe trust you have received the usual lecture from the local System\\nAdministrator. It usually boils down to these three things:\\n\\n #1) Respect the privacy of others.\\n #2) Think before you type.\\n #3) With great power comes great responsibility.\\n\\nsudo: timed out reading password\", \"rc\": 1, \"invocation\": {\"module_args\": {\"creates\": null, \"executable\": null, \"_uses_shell\": false, \"strip_empty_ends\": true, \"_raw_params\": \"sudo cat /root/.ssh/authorized_keys\", \"removes\": null, \"argv\": null, \"warn\": true, \"chdir\": null, \"stdin_add_newline\": true, \"stdin\": null}}, \"start\": \"2023-09-01 09:19:37.551388\", \"warnings\": [\"Consider using 'become', 'become_method', and 'become_user' rather than running sudo\"], \"msg\": \"non-zero return code\"}\r\n",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
"rc": 1
} - 使用
ansible -b
选项。如果用户没有sudo
权限, ansible 会因为没有输入sudo
密码而执行失败,具体报错(Missing sudo password
)参考以下示例中的k8s-master2
输出ansible my-hosts -m command -a "cat /root/.ssh/authorized_keys" -b
k8s-master2 | FAILED | rc=-1 >>
Missing sudo password
k8s-master1 | CHANGED | rc=0 >>
no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="echo 'Please login as the user \"centos\" rather than the user \"root\".';echo;sleep 10" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCGKLNMv82MQJUuQ9aZPsDofBj96aQlS1kNV2doSwyLatgMNBZ6rzgQuNOJ2DH87IzD1mZ0wL7iApvk6gkxSxcz5tmbU8dfYOYJdlBlhxGk2Nkg2V3P9FPC0hBY73szEV+1DUoqwl+COAsAXO9Uiebr0faQvWOkVT7pypunnjPrBBUaaXn2IcoPIdXZfXVLjXH2JbWSHL5J+yIGHewSMzZ/Xx7u6hwxUP0QLFHrnhD0WDukoBjoUZ2sshMP+DHgoyWjCg+uVpmjJAksp80f34WfNku5Grt90kYEj+N+x2JQ1Y4aQIXASIwDshicbJIsl+RMIMmwe+TElUJ6g9aa0qCr op2-east1-1031
[WARNING]: Platform linux on host k8s-uat-master3 is using the discovered Python interpreter at /usr/bin/python, but future installation of
another Python interpreter could change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more
information.
k8s-master3 | CHANGED | rc=0 >>
no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="echo 'Please login as the user \"centos\" rather than the user \"root\".';echo;sleep 10" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCGKLNMv82MQJUuQ9aZPsDofBj96aQlS1kNV2doSwyLatgMNBZ6rzgQuNOJ2DH87IzD1mZ0wL7iApvk6gkxSxcz5tmbU8dfYOYJdlBlhxGk2Nkg2V3P9FPC0hBY73szEV+1DUoqwl+COAsAXO9Uiebr0faQvWOkVT7pypunnjPrBBUaaXn2IcoPIdXZfXVLjXH2JbWSHL5J+yIGHewSMzZ/Xx7u6hwxUP0QLFHrnhD0WDukoBjoUZ2sshMP+DHgoyWjCg+uVpmjJAksp80f34WfNku5Grt90kYEj+N+x2JQ1Y4aQIXASIwDshicbJIsl+RMIMmwe+TElUJ6g9aa0qCr op2-east1-1031