Jenkins: Как настроить Jenkins для обратного прокси-сервера Nginx для подключения подчиненных JNLP

Я пытаюсь настроить мастер Jenkins и подчиненный узел Jenkins, где мастер Jenkins находится за обратным прокси-сервером Nginx на другом сервере с завершением SSL. Конфигурация nginx выглядит следующим образом:

upstream jenkins {
  server <server ip>:8080 fail_timeout=0;
}

server {
  listen 443 ssl;
  server_name jenkins.mydomain.com;
  ssl_certificate /etc/nginx/certs/mydomain.crt;
  ssl_certificate_key /etc/nginx/certs/mydomain.key;

  location / {
    proxy_set_header        Host $host:$server_port;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto $scheme;
    proxy_redirect          http:// https://;
    proxy_pass              http://jenkins;
  }
}

server {
  listen 80;
  server_name jenkins.mydomain.com;
  return 301 https://$server_name$request_uri;
}

Порт TCP для агентов JNLP установлен как 50000 в основной конфигурации Jenkins Global Security. Порт 50000 должен быть доступен из любой точки на хост-компьютере.

Подчиненный JNLP запускается с помощью следующей команды:

java -jar slave.jar -jnlpUrl https://jenkins.mydomain.com/computer/slave-1/slave-agent.jnlp -secret <secret>

Слэйв JNLP не может соединиться с настроенным портом JNLP на ведущем устройстве:

INFO: Connecting to jenkins.mydomain.com:50000 (retrying:4)
java.net.ConnectException: Connection timed out
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
        at java.net.Socket.connect(Socket.java:589)
        at java.net.Socket.connect(Socket.java:538)
        at hudson.remoting.Engine.connect(Engine.java:400)
        at hudson.remoting.Engine.run(Engine.java:298)

Какая конфигурация требуется для подключения подчиненного устройства JNLP к мастеру Jenkins?

1 ответ

Решение

Кажется, что порт JNLP использует двоичный протокол, а не текстовый протокол HTTP, поэтому, к сожалению, он не может быть реверсирован через NGINX, как обычные страницы Jenkins.

Вместо этого вы должны:

  1. Настройте Global Security > Установите флажок "Включить защиту" и установите фиксированный "TCP-порт для подчиненных агентов JNLP". Это приведет к тому, что все страницы Jenkins будут излучать дополнительные заголовки HTTP, указывающие этот порт: X-Hudson-CLI-Port, X-Jenkins-CLI-Port, X-Jenkins-CLI2-Port.

  2. Разрешите фиксированный порт TCP JNLP через любой брандмауэр (-ы), чтобы клиенты CLI и агенты JNLP могли напрямую обращаться к серверу Jenkins на бэкэнде.

  3. Установите системное свойство hudson.TcpSlaveAgentListener.hostName на имя хоста или IP-адрес вашего сервера Jenkins на серверной части. Это приведет к тому, что все страницы будут выдавать дополнительный заголовок HTTP (X-Jenkins-CLI-Host), содержащий указанное имя хоста. Это говорит клиентам CLI, где соединяться, но предположительно не агентам JNLP.

  4. Для каждого из ваших подчиненных компьютеров сборки в списке узлов наjenkins.mydomain.com/computer/ который использует метод запуска "Запуск подчиненных агентов через Java Web Start", щелкните компьютер, нажмите "Настроить", нажмите кнопку "Дополнительно" с правой стороны в разделе "Метод запуска" и установите соответствующее поле "Туннельное соединение через". Прочитайте вопросительный знак справки. Возможно, вам просто нужен синтаксис "HOST:", где HOST - это имя хоста или IP-адрес вашего сервера Jenkins на бэкэнде.

Отказ от ответственности: я еще не тестировал шаг 4, но он упоминается в первой ссылке ниже.

Рекомендации:

Прошло почти 4 года с тех пор, как OP задал этот вопрос, тем не менее, если вы зашли на эту страницу и ищете подходящее решение, что ж, теперь это возможно.

Я использую Traefik в качестве обратного прокси для Jenkins. Входящий TCP-порт теперь полностью отключен.

Единственное, что вам нужно убедиться, это то, что ваш агент / ведомое устройство доверяет сертификату сервера Jenkins (поскольку webSocket не может использоваться с -disableHttpsCertValidation или -noCertificateCheck

Если это агент Windows, используйте:

C:\Program Files (x86)\Java\jre1.8.0_251\bin\keytool.exe -import -storepass "changeit" -keystore "C:\Program Files (x86)\Java\jre1.8.0_251\lib\security\cacerts" -alias <cert_alias> -file "<path_to_cert>"

(Измените путь в соответствии с вашей версией Java)

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