Тайм-аут соединения закрытого узла Jenkins Slave истек / закрыт - Контейнер Docker - Шаг перезапуска - Конфигурация выбирает старый порт

Дженкинс версия: 1.643.2

Версия плагина Docker: 0.16.0

В моей среде Jenkins у меня есть мастер Jenkins с 2-5 серверами подчиненных узлов (slave1, slave2, slave3).

Каждый из этих подчиненных устройств настраивается в глобальной конфигурации Jenkins с помощью подключаемого модуля Docker.

Все работает в эту минуту.

Я видел, как наша система мониторинга выдавала несколько предупреждений о высоком использовании пространства SWAP на slave3 (для бывшего IP: 11.22.33.44), поэтому я ssh'ed к этой машине и запустил: sudo docker ps который дал мне действительный вывод для текущих запущенных контейнеров докера на этой машине slave3.

Запустив ps -eo pmem,pcpu,vsize,pid,cmd | sort -k 1 -nr | head -10 на машине целевого ведомого (где работали 4 контейнера) я обнаружил, что топ-5 процессов, потребляющих всю оперативную память, были java -jar slave.jar работает внутри каждого контейнера. Поэтому я подумал, почему бы не перезапустить дерьмо и не вернуть себе память. В следующем выводе я вижу, каково было состояние sudo docker ps Команда до и после docker restart <container_instance> шаг. SCROLL правильно, вы заметите, что во 2-й строке для идентификатора контейнера заканчивается ...0a02виртуальный порт (указанный в заголовке NAMES) на машине хоста (slave3) был 1053 (который был сопоставлен с портом виртуального IP-адреса контейнера 22 для SSH). Круто, что это значит, когда из Дженкинс Manage Node В разделе, если вы попытаетесь перезапустить контейнер ведомого устройства, Дженкинс попытается подключиться к IP-адресу HOST IP 11.22.33.44:1053 и сделать все возможное, чтобы успешно запустить подчиненное устройство. Итак, Дженкинс где-то держит этот ПОРТ (1053).

CONTAINER ID        IMAGE                                                   COMMAND                  CREATED             STATUS              PORTS                  NAMES
ae3eb02a278d        docker.someinstance.coolcompany.com:443/jenkins-slave-stable-image:1.1   "bash -c '/usr/sbin/s"   26 hours ago        Up 26 hours         0.0.0.0:1048->22/tcp   lonely_lalande
d4745b720a02        docker.someinstance.coolcompany.com:443/jenkins-slave-stable-image:1.1   "bash -c '/usr/sbin/s"   9 days ago          Up About an hour    0.0.0.0:1053->22/tcp   cocky_yonath
bd9e451265a6        docker.someinstance.coolcompany.com:443/jenkins-slave-stable-image:1.1   "bash -c '/usr/sbin/s"   9 days ago          Up About an hour    0.0.0.0:1050->22/tcp   stoic_bell
0e905a6c3851        docker.someinstance.coolcompany.com:443/jenkins-slave-stable-image:1.1   "bash -c '/usr/sbin/s"   9 days ago          Up About an hour    0.0.0.0:1051->22/tcp   serene_tesla

sudo docker restart d4745b720a02; echo $?
d4745b720a02
0

CONTAINER ID        IMAGE                                                   COMMAND                  CREATED             STATUS              PORTS                  NAMES
ae3eb02a278d        docker.someinstance.coolcompany.com:443/jenkins-slave-stable-image:1.1   "bash -c '/usr/sbin/s"   26 hours ago        Up 26 hours         0.0.0.0:1048->22/tcp   lonely_lalande
d4745b720a02        docker.someinstance.coolcompany.com:443/jenkins-slave-stable-image:1.1   "bash -c '/usr/sbin/s"   9 days ago          Up 4 seconds        0.0.0.0:1054->22/tcp   cocky_yonath
bd9e451265a6        docker.someinstance.coolcompany.com:443/jenkins-slave-stable-image:1.1   "bash -c '/usr/sbin/s"   9 days ago          Up About an hour    0.0.0.0:1050->22/tcp   stoic_bell
0e905a6c3851        docker.someinstance.coolcompany.com:443/jenkins-slave-stable-image:1.1   "bash -c '/usr/sbin/s"   9 days ago          Up About an hour    0.0.0.0:1051->22/tcp   serene_tesla

После запуска sudo docker restart <instanceIDofContainer> Я побежал free -h / grep -i swap /proc/meminfo и обнаружил, что ОЗУ (которое ранее использовалось полностью и показывало только оставшиеся 230 МБ свободного места) теперь свободно 1 ГБ, а размер SWAP, составляющий всего 1 ГБ, использовался 1 ГБ (я пробовал оба варианта подкачки 60 или 10), теперь 450 МБ свободного пространства подкачки. Таким образом, проблема оповещения была решена. Здорово.

НО, теперь, как вы заметили из sudo docker ps вывод выше, после шага перезапуска, для этого идентификатора контейнера ...0a02Я теперь получил новый ПОРТ # 1054!

Когда я перешел к "Управление узлами"> "Попытался перевести этот узел в автономный режим, остановил его и перезапустил", Дженкинс НЕ забирает НОВЫЙ ПОРТ (1054). Он все еще каким-то образом выбирает старый порт 1053 (при попытке установить соединение SSH с 11.22.33.44 (IP-адрес хоста) на порту 1053 (который сопоставлен с портом № 22 виртуального IP-адреса контейнера (ssh)).

Как я могу изменить этот порт или конфигурацию в Jenkins для этого подчиненного контейнера, чтобы Jenkins видел новый PORT и мог успешно перезапустить?

PS: Нажав "Настроить" на узле, чтобы увидеть, что его конфигурация НЕ показывает мне ничего, кроме поля " Имя". Обычно в обычном ведомом устройстве есть много полей (где вы можете определить метки, корневой каталог, метод запуска, свойства переменных env, инструменты для подчиненного окружения, но я предполагаю, что для этих контейнеров Docker я не вижу ничего, кроме просто Имя поля). Нажатие Test Connection в глобальной конфигурации Jenkins (в разделе плагина Docker) показывает, что он успешно находит Docker версии 1.8.3.

Прямо сейчас, поскольку порт 1053 (telnet) не работает, так как теперь это 1054 для экземпляра экземпляра этого контейнера (после шага перезапуска), шаг повторного запуска Jenkins завершается неудачно на этапе соединения SSH (первое, что он делает для соединения через метод SSH).

[07/27/17 17:17:19] [SSH] Opening SSH connection to 11.22.33.44:1053.
Connection timed out
ERROR: Unexpected error in launching a slave. This is probably a bug in Jenkins.
java.lang.IllegalStateException: Connection is not established!
    at com.trilead.ssh2.Connection.getRemainingAuthMethods(Connection.java:1030)
    at com.cloudbees.jenkins.plugins.sshcredentials.impl.TrileadSSHPasswordAuthenticator.canAuthenticate(TrileadSSHPasswordAuthenticator.java:82)
    at com.cloudbees.jenkins.plugins.sshcredentials.SSHAuthenticator.newInstance(SSHAuthenticator.java:207)
    at com.cloudbees.jenkins.plugins.sshcredentials.SSHAuthenticator.newInstance(SSHAuthenticator.java:169)
    at hudson.plugins.sshslaves.SSHLauncher.openConnection(SSHLauncher.java:1212)
    at hudson.plugins.sshslaves.SSHLauncher$2.call(SSHLauncher.java:711)
    at hudson.plugins.sshslaves.SSHLauncher$2.call(SSHLauncher.java:706)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
[07/27/17 17:19:26] Launch failed - cleaning up connection
[07/27/17 17:19:26] [SSH] Connection closed.

1 ответ

Решение

ХОРОШО. Zeeesus!

В JENKINS_HOME (на сервере MASTER) я искал, какой файл конфигурации содержал информацию о OLD-порте # для этого / тех контейнерных узлов, которые теперь отображались как OFFLINE.

Изменил каталог на: каталог узлов в $JENKINS_HOME и обнаружил, что для каждого узла есть файлы config.xml.

Например:$JENKINS_HOME / node/<slave3_node_IP>-d4745b720a02 / config.xml

Шаги разрешения:

  1. Vim отредактировал файл, чтобы изменить старый с новым портом.
  2. Управление Jenkins> Перезагрузить конфигурацию с диска.
  3. Управление узлами> Выбрал конкретный узел, который был в автономном режиме.
  4. Перезапустите ведомое устройство, и на этот раз Jenkins выбрал новый PORT и запустил ведомое устройство контейнера, как и ожидалось (как SSH-соединение с новым портом, видимым после изменения конфигурации).

Я думаю, что эта страница: https://my.company.jenkins.instance.com/projectInstance/docker-plugin/server/<slave3_IP>/ веб-страница, где она показывает всю информацию о контейнерах (в табличной форме, запущенной на данном подчиненном компьютере), на этой странице есть кнопка (последний столбец), чтобы ОСТАНОВИТЬ данный контейнер подчиненного устройства, но не запускать или перезапускать.

Наличие кнопки START или RESTART должно сделать то, что я только что сделал выше.

Лучшее решение:

Происходило то, что все 4 долгоживущих контейнерных узла, работающих на slave3, боролись за получение всей доступной оперативной памяти (11-12 ГБ), и в течение времени процесс JVM (java -jar slave.jar, который запускается на шаге перезапуска на целевом контейнере). виртуальная машина (IP), работающая на подчиненном сервере slave3) для отдельного контейнера, пыталась занять как можно больше памяти (RAM). Это привело к нехватке свободной памяти и, следовательно, к использованию SWAP, а также к тому, что инструмент мониторинга начнет кричать на нас через отправку уведомлений и т. Д.

Чтобы исправить эту ситуацию, первое, что нужно сделать, это:

1) В разделе "Глобальная конфигурация Jenkins" ("Управление Jenkins"> "Конфигурировать системы"> "Плагин Docker") для шаблона Image / Docker этого подчиненного сервера в разделе " Дополнительные настройки " мы можем поместить параметры JVM, чтобы указать контейнеру НЕ конкурировать за всю оперативную память. помогли следующие параметры JVM: эти параметры JVM будут пытаться сохранить пространство кучи каждого контейнера в меньшем поле, чтобы не истощить остальную часть системы.

Вы можете начать с 3-4 ГБ в зависимости от того, сколько всего оперативной памяти у вас на ведомом / компьютере, где будут работать подчиненные узлы на основе контейнеров.

2) Найдите любую последнюю версию slave.jar (которая может иметь некоторые улучшения производительности / обслуживания, которые помогут.

3) Интеграция решения для мониторинга (у вас есть Incinga и т. Д.) Для автоматического запуска задания Jenkins (где задание Jenkins выполнит какое-то действие - один вкладыш BASH, Python shit или Groovy goodness, Ansible playbook и т. Д.) Для устранения проблемы, связанной с к любому такому предупреждению.

4) Автоматически перезапускать подчиненные узлы контейнера (т. Е. Этап перезапуска) - переведите подчиненное устройство в автономный режим, онлайн, перезапустите шаг, поскольку это вернет ведомое устройство к обновленному состоянию свежести. Все, что нам нужно сделать, - это найти незанятого ведомого (если он не выполняет какую-либо работу), затем перевести его в автономный режим> затем в онлайн>, затем перезапустить ведомое устройство с помощью Jenkins REST API с помощью небольшого скрипта Groovy и поместить все это в задание Jenkins. и пусть это сделает выше, если эти подчиненные узлы были долгоживущими.

5) ИЛИ можно вращать подчиненных контейнеров на лету - используйте и бросайте модель каждый раз, когда Дженкинс ставит в очередь задание на выполнение.

Другие вопросы по тегам