如何做一个健康检查的Windows启动应用程序运行在Windows Docker Windows容器与Ansible?

我想通过Ansible将Spring Boot应用程序configuration到托pipe在Windows Docker主机上的Windows Docker容器(这是Mac上虚拟化的,但这是另一回事)。 我已经成功地使用Ansible Windows模块将Spring Boot应用程序configuration到Windows 。

我在最后一章,只是想在最后加上健康检查。 正如在没有Docker的blogpost中所概述的,这很简单:

- name: Wait until our Spring Boot app is up & running win_uri: url: "http://localhost:8080/health" method: GET register: result until: result.status_code == 200 retries: 5 delay: 5 

现在使用Docker Windows容器有一个已知的限制,所以现在你不能使用localhost 。 我们必须使用Windows Docker Containers内部的Hyper-V IP地址(您可以在NetworkSettings.Networks.nat.IPAddress的JSON输出中运行docker inspect <yourContainerIdHere>后查看IP)。

我的问题是 :如何获取Windows Docker容器的Hyper-V内部IP地址,将其输出到debugging语句中,并进行类似于我所述的健康检查?

经过一段漫长的旅程才做了一个简单的健康检查,我找到了一个解决方案。

首先,我们必须获得Docker容器的IP地址,这个命令可以很容易的在Powershell上完成:

 docker inspect --format '{{ .NetworkSettings.Networks.nat.IPAddress }}' <yourInstanceIdHere> 

我们只需要使用win_shell模块 。

但是因为这个使用Docker模板机制,Jinja2模板不知道,所以这次不应该解释这些命令。 我们必须正确地摆脱花括号,这已经在这个问题上概括了 。 您可以使用建议的解决方案之一:

"{%raw%}"{{ .NetworkSettings.Networks.nat.IPAddress }}"{%endraw%}"

要么

"{{'{{'}} .NetworkSettings.Networks.nat.IPAddress {{'}}'}}" – 这两个都适合我们。

现在从这个输出中获取IP地址,我试图只注册一个结果并进行健康检查。 可悲的是,这并不奏效,因为返回的stdoutstdout_lines确实包含了你的IP,而且还包含了Docker模板 – 但是这一次没有逃逸的序列,这又会让任务失败(作为Davide Guerri的评论所以回答已经报道)。

lanwen给出了一个建议:我们可以将第一个win_shell的输出结果输出到一个临时的文本文件container_ip.txt ,然后在第二个win_shell任务中,我们只读取该文件的内容并注册一个输出变量。

这似乎很容易,我们再次使用win_shell :

 win_shell: cat container_ip.txt register: win_shell_txt_return 

但是,嘿,这不是全部 – 因为在Windows上,有很好的回车换行:) ,这会在最后污染我们的IP地址,并让我们的健康检查再次失败。

但是,有一些帮助:Ansible有一个很好的分裂线功能(稍微没有记录…)我们只需要用尾部[0]来获得IP:

 "{{ win_shell_txt_return.stdout.splitlines()[0] }}" 

现在我们可以按照我们想要的方式进行健康检查。 这是完整的解决方案:

  - name: Obtain the Docker Container´s internal IP address (because localhost doesn´t work for now https://github.com/docker/for-win/issues/458) win_shell: "docker inspect -f {% raw %}'{{ .NetworkSettings.Networks.nat.IPAddress }}' {% endraw %} {{spring_boot_app_name}} {{ '>' }} container_ip.txt" - name: Get the Docker Container´s internal IP address from the temporary txt-file (we have to do this because of templating problems, see https://stackoverflow.com/a/32279729/4964553) win_shell: cat container_ip.txt register: win_shell_txt_return - name: Define the IP as variable set_fact: docker_container_ip: "{{ win_shell_txt_return.stdout.splitlines()[0] }}" - debug: msg: "Your Docker Container has the internal IP {{ docker_container_ip }} --> Let´s do a health-check against this URI: 'http://{{ docker_container_ip }}:{{spring_boot_app.port}}/{{spring_boot_app.health_url_ending}}'" - name: Wait until our Spring Boot app is up & running win_uri: url: "http://{{ docker_container_ip }}:8080/health" method: GET register: health_result until: health_result.status_code == 200 retries: 5 delay: 5