Ansible通过不同数据中心跳转主机连接时出现错误主机连接问题
这个问题我之前也碰到过,核心原因是Ansible会缓存SSH连接会话和主机标识信息——当两个inventory里的主机名称(比如docker-1)和ansible_host完全一致时,Ansible会默认复用之前建立的连接缓存,直接忽略新inventory里的ansible_ssh_common_args配置,导致你用dc2的inventory时,还是走dc1的跳转机。
下面给你几个可行的解决方案,按推荐程度排序:
1. 给不同数据中心的主机设置唯一名称(最彻底)
最简单的方式是给每个数据中心的主机加上后缀,让Ansible把它们识别成完全不同的主机,从根源上避免缓存冲突。
修改inventory-dc1:
[all:vars] ansible_ssh_common_args='-o ProxyCommand="ssh -W %h:%p -q ubuntu@10.1.1.1"' [docker] docker-1-dc1 ansible_host=192.168.1.1 docker-2-dc1 ansible_host=192.168.1.2
修改inventory-dc2:
[all:vars] ansible_ssh_common_args='-o ProxyCommand="ssh -W %h:%p -q ubuntu@10.1.1.2"' [docker] docker-1-dc2 ansible_host=192.168.1.1 docker-2-dc2 ansible_host=192.168.1.2
之后不管切换哪个inventory,Ansible都会建立独立的连接,不会混淆。
2. 手动清除Ansible连接缓存(临时解决)
如果你不想修改主机名,可以每次切换inventory前,手动清除Ansible的SSH连接缓存目录:
rm -rf ~/.ansible/cp/
这个目录是Ansible默认存储ControlPersist连接会话的地方,清空后再运行dc2的剧本,就会重新读取新的ansible_ssh_common_args配置建立连接。
或者在运行剧本时直接禁用连接持久化:
ansible-playbook -i inventory-dc2 your-playbook.yml --ssh-common-args="-o ControlPersist=0"
这个参数会让Ansible每次连接都重新建立,不会复用旧会话,适合临时场景。
3. 修改Ansible配置全局优化缓存策略
如果你经常需要切换这类inventory,可以修改ansible.cfg(默认路径~/.ansible.cfg或/etc/ansible/ansible.cfg),调整SSH连接的缓存标识规则:
[ssh_connection] # 让control_path包含更多唯一标识,避免IP相同但跳转机不同的冲突 control_path = %(directory)s/%%h-%%p-%%r-%%user # 或者直接禁用连接持久化 control_persist = 0
这样即使主机IP相同,只要跳转机对应的SSH用户或其他参数不同,Ansible也会建立独立连接。
验证一下:修改完配置或主机名后,运行ansible -i inventory-dc2 docker -m ping,检查输出是否正常,确认是通过dc2的跳转机连接即可。
内容的提问来源于stack exchange,提问作者jreisinger

