Ansible成功登录Docker私有仓库但未写入凭证至~/.docker/config.json
这种情况我之前也碰到过,结合你给出的版本信息(Ansible 2.3.2.0 + Docker 17.12),问题大概率出在旧版Ansible docker_login模块的兼容性或路径配置上,以下是一步步的排查和解决思路:
1. 核心原因:用户上下文与config.json路径不匹配
Docker的登录凭证是存在用户级别的config.json文件里的:
- 普通用户:
~/.docker/config.json - root用户:
/root/.docker/config.json
Ansible执行任务时,如果用了sudo(become: yes),默认会操作root用户的config文件;而你手动登录用的可能是普通用户,这就导致拉取镜像时(比如用普通用户执行)找不到凭证。反过来,如果Ansible用普通用户执行,但拉取镜像是用root,同样会出问题。
另外,Ansible 2.3.x的docker_login模块存在已知的bug:默认不会自动识别当前执行用户的config路径,即使你没加sudo,也可能没有写入到正确的用户目录下。
2. 解决方案:指定正确的config_path
修改你的Ansible角色中的docker_login任务,显式指定config_path参数,确保凭证写入到拉取镜像时会用到的用户的config文件里:
情况1:用普通用户执行任务和拉取镜像
- name: 登录私有Docker仓库 docker_login: registry: your-registry-domain.com username: your-username password: your-password config_path: "{{ ansible_user_dir }}/.docker/config.json"
情况2:用root用户执行(加了become: yes)
- name: 登录私有Docker仓库(root用户) docker_login: registry: your-registry-domain.com username: your-username password: your-password config_path: "/root/.docker/config.json" become: yes
3. 备选方案:直接用command模块执行docker login命令
如果上述方法还是不行,可能是旧版docker_login模块和Docker 17.12的兼容性问题,此时可以绕过模块,直接用原生的docker login命令(手动登录能成功,说明命令本身没问题):
- name: 用原生命令登录私有Docker仓库 command: docker login your-registry-domain.com -u your-username -p your-password args: creates: "{{ ansible_user_dir }}/.docker/config.json" # 避免重复登录
如果需要用root执行,就把creates路径改成/root/.docker/config.json并加上become: yes。
4. 验证方法
执行完登录任务后,加一个debug任务检查config文件内容,确认凭证是否写入:
- name: 检查Docker配置文件 debug: msg: "{{ lookup('file', ansible_user_dir + '/.docker/config.json') }}"
或者直接在目标主机上查看对应路径的config.json,看是否包含你的私有仓库的auth信息。
内容的提问来源于stack exchange,提问作者Adam Mazurkiewicz

