Ansible部署RSA密钥失败:vid_rsa.pub文件无法定位排查
Ansible 无法找到目标主机生成的SSH密钥文件的问题分析与解决
我刚梳理完你的问题,核心矛盾其实出在Ansible lookup('file')模块的执行逻辑上,结合你的Playbook代码、报错信息和目标主机的文件检查结果,原因和解决方案如下:
问题根源
lookup('file')是在控制节点执行的
你用run_once: True在某一台目标主机上生成了vid_rsa.pub,但lookup('file', '/home/dbadmin/.ssh/vid_rsa.pub')是去你运行ansible-playbook的控制节点上查找这个文件,而非生成密钥的目标主机。控制节点上根本没有这个路径下的文件,所以必然触发找不到文件的报错。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




