#maven #jenkins #docker-compose
#maven #дженкинс #docker-compose
Вопрос:
У меня есть следующая настройка для моей среды DevOps, организованная с помощью Docker Compose:
(упрощенный) docker-compose.yml
:
version: '3.7'
services:
nexus:
build: ./nexus/.
expose:
- 8081
networks:
- devops-network
jenkins:
build: ./jenkins/.
expose:
- 8080
depends_on:
- nexus
networks:
- devops-network
nginx:
image: nginx:1.19.5
ports:
- 80:80
depends_on:
- nexus
- jenkins
networks:
- devops-network
networks:
devops-network:
(упрощенный) nginx.conf
:
http {
upstream docker-jenkins {
server jenkins:8080;
}
upstream docker-nexus {
server nexus:8081;
}
server {
server_name jenkins.homenetwork.dns;
location / {
proxy_pass http://docker-jenkins;
}
}
server {
server_name nexus.homenetwork.dns;
location / {
proxy_pass http://docker-nexus;
}
}
}
Дженкинс может взаимодействовать с Nexus через сеть Docker. Если я войду в контейнер Jenkins, тогда ping nexus
и curl http://nexus:8081
дайте мне положительные ответы (я получаю отзывы от Nexus).
Но когда я запускаю конвейер Jenkins с вложенным агентом Docker для Maven:
pipeline {
agent {
docker { // successfully pulls image
image 'maven:3.6.3-openjdk-11'
args '-v /root/.m2:/root/.m2'
}
}
stages {
stage('Maven build') {
steps {
mavenBuildStep()
}
}
stage('Upload'){
steps {
withMaven(mavenSettingsConfig: 'cdb64ca9-d8e1-4d19-b486-e86c0ee75f50')
{
echo 'uploading Maven artifacts'
sh 'mvn deploy -DskipTests' // fails because it can't find nexus
}
}
}
}
}
и maven settings.xml
с указанным выше идентификатором:
<servers>
<server>
<id>nexus-snapshots</id>
<username>jenkins</username>
<password>${JENKINS_NEXUS_PASSWORD}</password>
</server>
</servers>
and this in my pom.xml
:
<distributionManagement>
<snapshotRepository>
<id>nexus-snapshots</id>
<url>http://nexus:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
then it says:
[ОШИБКА] Не удалось выполнить цель org.apache.maven.plugins:maven-deploy-plugin: 2.8.2: развертывание (по умолчанию-развертывание) в родительском проекте: не удалось получить удаленные метаданные … из / в nexus-snapshots (http://nexus:8081/repository/maven-snapshots /): Передача не удалась для http://nexus:8081/repository/maven-snapshots/…/1.0.0-SNAPSHOT/maven-metadata.xml : Неизвестный узел связи: Нетадрес, связанный с именем хоста
Когда я меняю URL-адрес репозитория в pom.xml
на сетевой IP-адрес контейнера Nexus:
<distributionManagement>
<snapshotRepository>
<id>nexus-snapshots</id>
<url>http://172.26.0.2:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
затем истекает время ожидания:
[ОШИБКА] Не удалось выполнить цель org.apache.maven.plugins:maven-deploy-plugin:2.8.2: развертывание (по умолчанию-развертывание) в родительском проекте : … Не удалось подключиться к 172.26.0.2: 8081 [/ 172.26.0.2]: время ожидания соединения истекло
Что происходит? Я сопоставил демон Docker хоста с контейнером Jenkins setfacl -m user:jenkins:rw /var/run/docker.sock
, поэтому он должен иметь возможность доступа к контейнеру Nexus? Когда я извлекаю изображение Docker в конвейере, изображение добавляется в мою хост-систему и его не нужно загружать снова в следующий раз, так что, похоже, все в рабочем состоянии. Это потому, что «Docker внутри Docker» не имеет доступа к devop-network
?
В идеале я мог бы вместо этого указать http://nexus.homenetwork.dns/repository/maven-snapshots/
URL-адрес в своем pom, но это кажется невозможным. У кого-нибудь есть опыт работы с такого рода настройками?
Обновить
Чтобы подтвердить свои подозрения, я использовал agent any
вместо агента Docker в конвейере Jenkins и установил maven в контейнер Jenkins. При такой настройке запуск конвейера Jenkins корректно загружает снимки с URL http://nexus:8081/repository/maven-snapshots/
.
Это неплохое решение, но мне остается только гадать, как заставить его работать с агентом Docker из чистого любопытства.
Комментарии:
1. Мой первый вопрос: почему у вас есть прокси перед вашим менеджером репозитория nexus? Какой цели служит nginx?
2. @khmarbaise Является ли красивый URL-адрес правильным ответом на ваш вопрос? Я впервые пытаюсь настроить среду devops, поэтому я могу делать избыточные / странные вещи. Эти контейнеры размещены на моем ноутбуке, пока я разрабатываю на своем настольном ПК. Я хотел бы перейти к удобочитаемому URL-адресу и получить доступ к приложениям с моего ноутбука. Если я не использую прокси, мне нужно будет размещать приложения на разных портах с локального хоста моего ноутбука. С nginx все находится под localhost: 80.
Ответ №1:
Эй, у меня была такая же проблема, и я уже довольно давно искал решение. Сначала я тоже этого не понял. Однако в конце я понял, что это довольно простая вещь для докеров. Агент docker в основном запускает новый контейнер docker. Если вы хотите, чтобы он получил доступ к другому, уже существующему, используя только «nexus», вы должны добавить его в ту же мостовую сеть. В вашем случае вам необходимо добавить
pipeline { agent { docker {
...
args '--net="devops-network"'
}
}
По крайней мере, это решило проблему для меня.