如何对使用Ansible的Windows Docker Windows容器中运行的Spring Boot应用程序进行运行状况检查?

时间:2017-02-23 11:31:56

标签: windows docker spring-boot ansible

我想将一个Spring Boot应用程序配置到Windows Docker容器中,该容器托管在Windows Docker主机上(在Mac上虚拟化,但这是另一个故事;))与Ansible。我已成功使用Ansible Windows Modulesprovision a Spring Boot app to Windows

我在最后一章中,只是想在最后添加健康检查。正如没有Docker的博文中所述,这很容易:

  - 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容器there´s a known limitation,以便您暂时不能使用localhost。我们必须使用Windows Docker Containers内部Hyper-V IP地址(您可以在docker inspect <yourContainerIdHere>中的JSON输出中运行NetworkSettings.Networks.nat.IPAddress后看到IP。

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

1 个答案:

答案 0 :(得分:2)

经过长途旅行,只需进行简单的健康检查,我找到了解决方案。

首先,我们必须获取Docker Container的IP地址,使用此命令可以在Powershell上轻松完成:

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

我们只需使用win_shell module

但是因为它使用了Docker模板机制,Jinja2模板不知道,这次它不应该解释这些命令。我们必须正确地逃避花括号,这在this so q&a already中有所概述。您可以使用建议的解决方案之一:

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

"{{'{{'}} .NetworkSettings.Networks.nat.IPAddress {{'}}'}}" - 两者都适合我们。

现在从此输出中获取IP地址,我尝试只注册结果并进行健康检查。遗憾的是,这不起作用,因为返回的stdoutstdout_lines确实包含您的IP,但也包含Docker模板 - 但这次没有转义序列,这将导致任务失败(作为Davide Guerrithis so answer已经报道过的评论。

来自lanwen的以下评论提供了救援建议:我们可以将第一个win_shell输出传输到临时文本文件container_ip.txt,然后 - 在第二个win_shell任务中 - 我们只读取内容该文件并注册一个输出变量。

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

win_shell: cat container_ip.txt
register: win_shell_txt_return

但是,嘿,这不是整个故事 - &gt;因为在Windows上有nice carriage return line feeds :),它会在最后用\r\n污染我们的IP地址,并且会让我们的健康检查再次失败。

但是,有一点帮助:Ansible有一个很好的 splitlines 功能(稍微没有记录......)我们只需要跟踪[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