You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Ansible部署RSA密钥失败:vid_rsa.pub文件无法定位排查

Ansible 无法找到目标主机生成的SSH密钥文件的问题分析与解决

我刚梳理完你的问题,核心矛盾其实出在Ansible lookup('file')模块的执行逻辑上,结合你的Playbook代码、报错信息和目标主机的文件检查结果,原因和解决方案如下:

问题根源

  1. lookup('file')是在控制节点执行的
    你用run_once: True在某一台目标主机上生成了vid_rsa.pub,但lookup('file', '/home/dbadmin/.ssh/vid_rsa.pub')是去你运行ansible-playbook的控制节点上查找这个文件,而非生成密钥的目标主机。控制节点上根本没有这个路径下的文件,所以必然触发找不到文件的报错。

  2. run_once的执行范围限制
    你只在单台主机生成密钥,但后续的authorized_key任务会在所有目标主机上执行——即便lookup能找到文件,也无法确保是那台生成密钥的主机的公钥(Ansible不会自动同步目标主机的文件到控制节点)。

另外,你的Playbook里还有两个小细节需要修正:

  • Add user to sudoers group任务的内容写的是devops ALL=(ALL) NOPASSWD: ALL,但你创建的用户是dbadmin,这个规则对dbadmin无效,应该改成dbadmin ALL=(ALL) NOPASSWD: ALL
  • 有两个同名的Disable Password Authentication任务,第二个实际是禁用root登录,建议改名避免混淆。

解决方案

方案1:在控制节点生成密钥(推荐,符合Ansible最佳实践)

把密钥生成放在控制节点,再统一推送到所有目标主机,逻辑更清晰,也避免跨主机文件查找的问题:

- name: Create dbadmin user
  user: 
    name: dbadmin 
    shell: /bin/bash
- name: Add dbadmin to sudoers (no password required)
  copy: 
    dest: "/etc/sudoers.d/dbadmin" 
    content: "dbadmin ALL=(ALL) NOPASSWD: ALL"
    mode: 0440  # sudoers文件需要严格权限,避免系统警告
- name: Ensure .ssh directory exists for dbadmin
  file: 
    path: /home/dbadmin/.ssh 
    owner: dbadmin 
    group: dbadmin 
    mode: 0700 
    state: directory
# 在控制节点生成RSA密钥(仅当不存在时执行)
- name: Generate RSA private key on control node
  openssl_privatekey:
    path: ~/.ssh/vid_rsa
    type: rsa
    size: 2048
    owner: "{{ ansible_user_id }}"
    mode: 0600
  delegate_to: localhost
  run_once: True
- name: Extract public key from private key on control node
  openssl_publickey:
    path: ~/.ssh/vid_rsa.pub
    privatekey_path: ~/.ssh/vid_rsa
    format: openssh
  delegate_to: localhost
  run_once: True
- name: Deploy public key to all target hosts
  authorized_key: 
    user: dbadmin 
    key: "{{ lookup('file', '~/.ssh/vid_rsa.pub') }}"
- name: Disable Password Authentication in SSHD
  lineinfile: 
    dest: /etc/ssh/sshd_config 
    regexp: '^PasswordAuthentication' 
    line: "PasswordAuthentication no" 
    state: present 
    backup: yes
- name: Disable Root Login via SSH
  lineinfile: 
    dest: /etc/ssh/sshd_config 
    regexp: '^PermitRootLogin' 
    line: "PermitRootLogin no" 
    state: present 
    backup: yes

方案2:在目标主机生成密钥后分发(适合必须在目标主机生成密钥的场景)

如果一定要在某台目标主机生成密钥,需要先把公钥拉取到控制节点,再推送到其他主机:

- name: Create dbadmin user
  user: 
    name: dbadmin 
    shell: /bin/bash
- name: Add dbadmin to sudoers (no password required)
  copy: 
    dest: "/etc/sudoers.d/dbadmin" 
    content: "dbadmin ALL=(ALL) NOPASSWD: ALL"
    mode: 0440
- name: Ensure .ssh directory exists for dbadmin
  file: 
    path: /home/dbadmin/.ssh 
    owner: dbadmin 
    group: dbadmin 
    mode: 0700 
    state: directory
# 在单台目标主机生成密钥
- name: Generate RSA key for dbadmin on one host
  command: su dbadmin -c 'ssh-keygen -q -t rsa -f /home/dbadmin/.ssh/vid_rsa -N ""'
  args: 
    creates: /home/dbadmin/.ssh/vid_rsa 
  run_once: True
  register: key_generated
# 把公钥拉取到控制节点的临时目录
- name: Fetch public key from target host to control node
  fetch:
    src: /home/dbadmin/.ssh/vid_rsa.pub
    dest: /tmp/fetched_vid_rsa.pub
    flat: yes
  when: key_generated.changed
  run_once: True
# 分发拉取到的公钥到所有目标主机
- name: Deploy public key to all hosts
  authorized_key: 
    user: dbadmin 
    key: "{{ lookup('file', '/tmp/fetched_vid_rsa.pub') }}"
# SSHD配置任务...

内容的提问来源于stack exchange,提问作者user_01_02

火山引擎 最新活动