我正在使用 Ansible 和 Docker 设置服务器。我目前正在学习这两种技术,所以如果我在这里说得太愚蠢,请多多包涵。
为了运行 Docker 命令,用户必须属于 docker 用户组。因此我这样做:
- name: Ensure group "docker" exists
become: yes
group:
name: docker
state: present
- name: Add ansible user to docker group
become: yes
user:
name: "{{ansible_user}}"
groups: docker
append: yes
在稍后的剧本中(但剧本相同),我将执行以下操作:
- name: build
command: docker-compose build --pull
args:
chdir: /docker
- name: start services
command: docker-compose -f docker-compose.yml up -d
args:
chdir: /docker
这在第一次运行时永远不会起作用。“构建”任务总是失败,抱怨找不到docker(这是由于缺少访问权限)。如果我以手动身份登录,{{ansible_user}}
我可以很好地运行docker,如果我等待足够长的时间(我猜想这样Ansible就会打开一个新的SSH会话),剧本也可以正常工作,这让我相信{{ansible_user}}
由于Ansible重复使用SSH会话执行剧本中的所有任务,因此尚未选择新组。
那我该怎么办?我也试过了
- name: build
become: yes
become_user: "{{ansible_user}}"
become_method: su
command: docker-compose build --pull
args:
chdir: /docker
这样 ansible 就会进入一个新的会话,但这可能会失败,因为我需要输入密码,而且我认为没有办法直接在任务中执行此操作。
有没有关于如何以非黑客方式解决此问题的想法?我不敢相信这是一个如此罕见的用例,以至于没有标准的方法来解决这个问题。可能我只是忽略了一些东西。
答案1
我不确定它是否适合您,但我建议您尝试添加 reset_connection。
- name: reset ssh connection
meta: reset_connection
这里有一个例子。
您可能希望将其添加为处理程序,并从您的用户/组修改任务中通知它。然后还添加一个,meta: flush_handlers
以便仅在需要时重置连接。
答案2
我用过meta: reset_connection
,但它对我不起作用。
因此我使用su -c
命令,并测试它是否有效:
- name: perform docker login for ansible_ssh_user
shell: |
su -c ' docker login xxx:5000 -u xxxx -p xxxxx ' {{ ansible_ssh_user }}
# become: yes
# become_user: "{{ ansible_ssh_user }}"
when:
# if use ansible_connection=local, the var ansible_ssh_user will not defined
- ansible_connection != 'local'
- ansible_ssh_user is defined
- ansible_ssh_user != 'root'