繁体   English   中英

delegate_to 忽略配置的 ssh_port

[英]delegate_to ignores configured ssh_port

用例:我们正在使用默认 linux 映像(目前为 Ubuntu 22.04)将虚拟机部署到云中。 部署一台机器后,我们配置我们的默认用户,将SSH端口从22改为2222为Ansible。

旁注:我们通过 inte.net 使用跳转概念 - Ansible 自动化平台 / AWS => inte.net => SSH 跳转主机 => 目标主机

为了保持 Ansible 连接到新机器的可能性,在更改 SSH 端口后,我发现多个 Stack Overflow / 博客条目,检查和设置ansible_ssh_port ,基本上是通过在端口 22 和 2222 上运行wait_for并设置 SSH 变量取决于结果(下面的代码)。
现在这对第一个 SSH 主机(jumphost)工作正常,但由于建立 ssh 连接的问题,第二个主机总是失败。

旁注:SSH 守护进程正在运行。 如果我从跳转主机使用我的用户,我可以从 22/2222 获得 SSH 响应(取决于当前部署的 state)。

从问题编辑

部署任务应该只在目标主机上运行。 也不是跳转主机。

我首先在 jumphost 上运行部署并确保它已启动、运行和配置。

之后,我在 jumphost 后面的所有机器上运行部署以配置它们。

这也确保如果我需要重新启动,我不会意外杀死所有隧道 ssh session。


Ansible库存示例

all:
  hosts:
  children:
    jumphosts:
      hosts:
        example_jumphost:
          ansible_host: 123.123.123.123
    cloud_hosts:
      hosts:
        example_cloud_host01: #local DNS is resolved on the jumphost - no ansible_host here (yet)
          ansible_ssh_common_args: '-oProxyCommand="ssh -W %h:%p -oStrictHostKeyChecking=no -q ansible@123.123.123.123 -p 2222"' #Tunnel through the appropriate jumphost
          delegation_host: "ansible@123.123.123.123" #delegate jobs to the jumphost in each project if needed

vars:
   ansible_ssh_port: 2222

SSH check_port角色

- name: Set SSH port to 2222
  set_fact:
    ansible_ssh_port: 2222

- name: "Check backend port 2222"
  wait_for:
    port: 2222
    state: "started"
    host: "{{ inventory_hostname }}"
    connect_timeout: "5"
    timeout: "5"
#  delegate_to: "{{ delegation_host }}"
#  vars:
#    ansible_ssh_port: 2222
  ignore_errors: true
    register: ssh_port

- name: "Check backend port 22"
  wait_for:
    port: "22"
    state: "started"
    host: "{{ inventory_hostname }}"
    connect_timeout: "5"
    timeout: "5"
#  delegate_to: "{{ delegation_host }}"
#  vars:
#    ansible_ssh_port: 2222
  ignore_errors: true
  register: ssh_port_default
  when: 
    - ssh_port is defined
    - ssh_port.state is undefined

- name: Set backend SSH port to 22
  set_fact:
    ansible_ssh_port: 22
  when: 
    - ssh_port_default.state is defined

剧本本身

- hosts: "example_cloud_host01"
  gather_facts: false
  roles:
  - role: check_port #check if we already have the correct port or need 22
  - role: sshd #Set Port to 2222 and restart sshd
  - role: check_port #check the port again, after it has been changed
  - role: install_apps
  - role: configure_apps

错误信息:

delegate_to用于任务Check backend port 2222

fatal: [example_cloud_host01 -> ansible@123.123.123.123]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 123.123.123.123 port 22: Connection refused", "unreachable": true}

这让我感到困惑,因为我希望委托主机使用与目标主机相同的ansible_ssh_port

没有delegate_to任务Check backend port 2222Check backend port 22

fatal: [example_cloud_host01]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"}, "changed": false, "elapsed": 5, "msg": "Timeout when waiting for example_cloud_host01:2222"}
fatal: [example_cloud_host01]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"}, "changed": false, "elapsed": 5, "msg": "Timeout when waiting for example_cloud_host01:22"}

我不知道为什么会这样。 如果我手动尝试连接,它工作正常。

到目前为止我尝试了什么

  • 如上所述,我玩过delegate_tovars ……。
  • 我想看看我是否可以为delegato_to提供跳转主机的正确端口 2222。
  • 我想看看是否可以在没有delegate_to的情况下运行它(因为无论如何它应该自动使用代理命令在跳转主机上运行)。

在更改 SSH 端口后,这两种方式都没有给我一个关于如何连接到我的第二层服务器的解决方案。

现在,我把剧本分成两部分

  1. 使用端口 22 部署 sshd 配置
  2. 之后在端口 2222 上运行我们的完整部署

我会执行以下操作(我使用 localhost 作为跳转主机在清单中使用假值对此进行了一些测试,以检查 localhost 上的端口)

编辑:修改我的例子,在你对你的问题和这个答案发表评论后,试图向你展示一种方式

存货

---
all:
  vars:
    ansible_ssh_port: 2222

proxies:
  vars:
    ansible_user: ansible
  hosts:
    example_jumphost1:
      ansible_host: 123.123.123.123
    example_jumphost2:
      ansible_host: 231.231.231.231
    # ... and more jump hosts ...

cloud_hosts:
  vars:
    jump_vars: "{{ hostvars[jump_host] }}"
    ansible_ssh_common_args: '-oProxyCommand="ssh -W %h:%p -oStrictHostKeyChecking=no -q {{ jump_vars.ansible_user }}@{{ jump_vars.ansible_host }} -p {{ jump_vars.ansible_shh_port | d(22) }}"'
  children:
    cloud_hosts_north:
      vars:
        jump_host: example_jumphost1
      hosts:
        example_cloud_host01:
        example_cloud_host02:
        # ... and more ...
    
    cloud_hosts_south:
      var:
        jump_host: example_jumphost2
      hosts:
        example_cloud_host03:
        example_cloud_host04:
        # ... and more ...

    # ... and more cloud groups ...

检查端口的任务

- name: "Check backend inventory configured port {{ ansible_ssh_port }}"
  wait_for:
    port: "{{ ansible_ssh_port }}"
    state: "started"
    host: "{{ inventory_hostname }}"
    connect_timeout: "5"
    timeout: "5"
  delegate_to: "{{ jump_host }}"
  ignore_errors: true
  register: ssh_port

- name: "Check backend default ssh port if relevant"
  wait_for:
    port: "22"
    state: "started"
    host: "{{ inventory_hostname }}"
    connect_timeout: "5"
    timeout: "5"
  delegate_to: "{{ jump_host }}"
  ignore_errors: true
  register: ssh_port_default
  when: ssh_port is failed

- name: "Set backend SSH port to 22 if we did not change it yet"
  set_fact:
    ansible_ssh_port: 22
  when:
    - ssh_port_default is not skipped
    - ssh_port_default is success

请注意,如果对端口22 / 2222的检查均失败,您配置的端口仍将是2222 ,但任何后续任务显然都会失败。 在检查这些相关主机后,您可能希望快速失败:

- name: "Fail host if no port is available"
  fail:
    msg:
      - "Host {{ inventory_hostname }}" does not have"
      - "any ssh port available (tested 22 and 2222)"
  when:
    - ssh_port is failed
    - ssh_port_default is failed

有了这个,您可以在您的游戏中使用不同的目标来访问相关主机:

  • 对于跳跃主机
    • 在单个堡垒主机上运行:例如hosts: example_jumphost1
    • 在所有堡垒主机上运行: hosts: proxies
  • 对于云主机
    • 在所有云主机上运行: hosts: cloud_hosts
    • 在单个子组上运行:例如hosts: cloud_hosts_north
    • 在除子组之外的所有云主机上运行:例如hosts: cloud_hosts:!cloud_hosts_south

有关更多信息,请参阅ansible 模式

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM