2017-02-23 101 views
2

Я хочу предоставить приложение Spring Boot в контейнер Docker для Windows, который размещен на Windows Docker Host (который виртуализирован на Mac, но это еще одна история;)) с Ansible. Я уже успешно использовал Ansible Windows Modules до provision a Spring Boot app to Windows.Как сделать проверку работоспособности в приложении Spring Boot, запущенном внутри Windows Docker Контейнер Windows с Ansible?

Я в заключительной главе и просто хотел добавить проверку работоспособности в самом конце. Как указано в 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, Контейнеры there´s a known limitation так, что вы не можете использовать localhost сейчас. Мы должны использовать внутренний IP-адрес Hyper-V для Windows Docker Containers (вы можете увидеть IP после запуска docker inspect <yourContainerIdHere> внутри выхода JSON в NetworkSettings.Networks.nat.IPAddress).

Мой вопрос: Как я могу получить Windows, Docker Container's Hyper-V внутренний IP-адрес, вывод его в отладочный заявление и сделать медицинские проверки похож на тот, который я обрисовал?

ответ

2

После долгого путешествия, чтобы просто провести медицинскую проверку, я нашел решение.

Сначала мы должны получить Docker Container's IP-адрес, который можно было бы легко сделать на Powershell с этой командой:

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

Мы просто должны использовать win_shell module.

Но поскольку это использует механизм шаблонов Docker, Jinja2 templating не знает, на этот раз он не должен интерпретировать эту команду. Нам нужно спрятать фигурные скобки правильно, что описано в 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 - мы просто прочитать содержимое этого файла и зарегистрировать output- переменная.

Это кажется легким, снова мы используем win_shell:

win_shell: cat container_ip.txt 
register: win_shell_txt_return 

Но эй, that's не вся история -> потому что в Windows, есть nice carriage return line feeds :), который загрязняет наш IP-адрес с \r\n в конце концов, и наша проверка работоспособности снова потерпит неудачу.

Но опять же, there's помощь: анзибль имеет хорошие 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