我想将一个Spring Boot应用程序配置到Windows Docker容器中,该容器托管在Windows Docker主机上(在Mac上虚拟化,但这是另一个故事;))与Ansible。我已成功使用Ansible Windows Modules到provision 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地址,将其输出到调试语句中并执行类似于我概述的健康检查?
答案 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地址,我尝试只注册结果并进行健康检查。遗憾的是,这不起作用,因为返回的stdout
和stdout_lines
确实包含您的IP,但也包含Docker模板 - 但这次没有转义序列,这将导致任务失败(作为Davide Guerri中this 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