Ansible:将文件复制到Docker Volume

时间:2018-10-05 15:31:16

标签: docker ansible

我运行一本Ansible Playbook,该手册收集机器的特定信息并将日期存储在文件中。每个主机一个。因此,我最终得到了大量文件,这些文件现在应该发送到基于Docker的应用程序中以进行进一步处理。

Actuall我需要将其存储在特定的文件夹中并创建一个卷,以便容器能够读取文件。

这需要/ tmp / incoming的存在/创建... 现在,如果Monitor应用程序被移动或需要第二个实例,则必须访问文件系统并创建目录。

所以我想创建一个更动态的卷:

docker volume create --name monitor-incoming:/var/www/monitor/incoming

现在Docker容器将能够访问该卷。但是我可以使用Ansible将文件“复制”到此远程卷吗?将它们发送到监控程序而不是/ tmp / incoming吗?

3 个答案:

答案 0 :(得分:1)

您可以使用以下任何一种方法:

  1. 具有标准Ansible file/copy模块的Ansible非SSH docker连接。取自Ansible documentation的示例:
- name: create jenkins container
  docker_container:
    docker_host: myserver.net:4243
    name: my_jenkins
    image: jenkins

- name: add container to inventory
  add_host:
    name: my_jenkins
    ansible_connection: docker
    ansible_docker_extra_args: "--tlsverify --tlscacert=/path/to/ca.pem --tlscert=/path/to/client-cert.pem --tlskey=/path/to/client-key.pem -H=tcp://myserver.net:4243"
    ansible_user: jenkins
  changed_when: false

- name: create directory for ssh keys
  delegate_to: my_jenkins
  file:
    path: "/var/jenkins_home/.ssh/jupiter"
    state: directory
  1. 使用docker cli的Ansible command模块。这种方法使我获得了更多的成功。
- name: remove temporary data-only container
  become: yes
  docker_container:
    name: your_temp_data_container
    state: absent

- name: recreate data volume
  become: yes
  docker_volume:
    name: your_data_volume
    state: present

- name: create temporary data-only container
  become: yes
  docker_container:
    name: your_temp_data_container
    image: tianon/true
    state: present
    volumes:
    - your_data_volume:/data

- name: copy folder contents to data volume via temporary data-only container
  become: yes
  command: docker cp /some_data_path_on_this_ansible_host/. your_temp_data_container:/data

- name: remove temporary data-only container
  become: yes
  docker_container:
    name: your_temp_data_container
    state: absent

答案 1 :(得分:0)

我没有docker环境可以对此进行测试,但我认为您可以在主机上使用docker run图像上的bash进行以下操作:

  • 绑定要复制文件所在的主机目录(我假设我们正在复制/path/to/filename/on/host)。我将该目录绑定到容器内的/tmp/source/
  • 在容器中的某个位置绑定monitor-incoming卷。我选择将其绑定到/tmp/destination/
  • 运行一个简单的cp命令(由于bash映像的入口点本身就是bash,因此我们只需添加该命令即可运行)。

以下是命令:

docker run \
  --mount source=monitor-incoming,target=/tmp/destination \
  --mount type=bind,source=/path/to/filename/on/host,target=/tmp/source \
  bash:4.4 \
  cp "/tmp/source" "/tmp/destination/path/to/destination/inside/volume/"

这未经测试,但我认为应遵循这些原则。请注意,如果该脚本使用得相当频繁,则可能应该有一个专用于该任务的容器,而不是多次调用docker run

我不确定是否有更直接的方法不涉及在容器内运行cp ...

答案 2 :(得分:0)

我希望我们可以使用内置模块来做到这一点,但是除非我们有一个内置模块,否则您可以在单个任务中将文件添加到命名卷中:

- name: actual config file is in the volume
  command:
    cmd: docker run --rm -iv your-config-volume:/v busybox sh -c 'cat > /v/config.yml'
    stdin: "{{ lookup('file', 'config.yml') | regex_replace('\\r\\n', '\\n') }}"

在这里,我们使用command module创建一个附加了your-config-volume卷的临时容器。

sh -c 'cat > /v/config.yml'命令将所有stdin保存到文件中。

最后,根据您的角色,我们将stdin设置为config.yml文件。

仅在运行Windows时才需要regex_replace('\\r\\n', '\\n')部分。