@mxelgin

Как запустить docker в Jenkins?

Требуется автоматизировать процесс сборки приложения. Имеются исходники на Git ресурсе. Необходимо собрать из них проект и положить в Docker контейнер. Никаких средств оркестрации на этом хосте нет и не будет. На хосте установлен только докер. Все приложения должны крутиться в контейнерах. Соответственно Jenkins тоже должен жит в контейнере.

Решил автоматизировать сборку. Пошел в сторону Jenkins in Docker. Почитал скупую информацию, обронил слезу и начал мучать ИИ. Что получилось.
Избыточный docker-compose.yml так как по документации указано что есть 2 способа работы Jenkins через Docker. На официальном сайте используем sshagent . На официальном ресурсе github используем Jenkins через dind. Интересные подход к документации разработчиков, подумал и решил пробовать сразу 2я способами.
services:
  jenkins:
    image: jenkins/jenkins:lts
    privileged: true  # Запуск с правами привилегированного контейнера
    ports:
      - "7070:8080"
      - "50000:50000"
    volumes:
      - jenkins_home:/var/jenkins_home
    environment:
      - DOCKER_HOST=tcp://docker:2376
      - DOCKER_TLS_CERTDIR=/certs
    networks:
      jenkins:    # Правильное определение сети
        aliases:
          - docker  # Установка псевдонима для сети


  docker-dind:
    image: docker:24.0.7-dind
    privileged: true  # Привилегированный доступ для DinD
    volumes:
      - jenkins_home:/var/jenkins_home   # Общий том с Jenkins для доступа к файлам
    networks:
      - jenkins
    entrypoint: ["dockerd-entrypoint.sh"]  # Установите точку входа
    command: ["--storage-driver=overlay2"]  # Передайте параметры в Docker Daemon
    ports:
      - "2376:2376"
      
networks:
  jenkins:   
  
volumes:
  jenkins_home:


Несколько часов попробовав завести Jenkins через dind плюнул и ушел мучать sshagent

pipeline {
    agent any  // Вы можете указать конкретный агент, если нужно

    stages {
        stage('Clone Repository') {
            steps {
                git 'https://github.com/traefik/whoami.git'
            
            }
        }
        stage('Build Repository') {
            steps {
                sshagent(['ssh-user-credential-id']) {
                        sh "ssh -o StrictHostKeyChecking=no user@host 'echo password | sudo -S docker build -t zaya /var/lib/docker/volumes/pipline_jenkins_home/_data/workspace/sborka'"

                }            
            }
        }  
    }
}


В итоге собрал костыльную автоматизированную сборку. Да, нужно вынести отдельного пользователя и дать права на докер чтоб не светить пароль. Но возник вопрос, как при сборке через ssh хост узнает по какому адресу был клонирован git проект (этот вопрос решен в комментарии)? Изначально я думал что проект будет лежать по наименованию который я сам назвал. Но зайдя по адресу где лежит проект я также увидел куча клонов созданных самим Jenkins без моего ведома.
sborka - основной
sborka@2
sborka@2@temp
sborka@temp

Опыта с CICD у меня 6 часов. Может я что-то упустил. Или технология эта все еще сырая. И стоит на что-то другое посмотреть? Или есть у Jenkins красивое и элегантное решение как делать сборку из контейнера?

P/S

Красивое решение как я понял из инструкции лежит здесь
Jenkins через dind

https://www.jenkins.io/doc/book/installing/docker/

FROM jenkins/jenkins:2.462.3-jdk17
USER root
RUN apt-get update && apt-get install -y lsb-release
RUN curl -fsSLo /usr/share/keyrings/docker-archive-keyring.asc \
  https://download.docker.com/linux/debian/gpg
RUN echo "deb [arch=$(dpkg --print-architecture) \
  signed-by=/usr/share/keyrings/docker-archive-keyring.asc] \
  https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list
RUN apt-get update && apt-get install -y docker-ce-cli
USER jenkins
RUN jenkins-plugin-cli --plugins "blueocean docker-workflow"

Проблема появляется на сборке докерфайла.
docker build -t myjenkins-blueocean:2.462.3-1 .
=> ERROR [2/2] RUN apt-get update && apt-get install                                                                                              1.0s 
------
 > [2/2] RUN apt-get update && apt-get install:
0.809 Ign:1 http://deb.debian.org/debian bookworm InRelease
0.824 Ign:2 http://deb.debian.org/debian bookworm-updates InRelease
0.837 Ign:3 http://deb.debian.org/debian-security bookworm-security InRelease
0.854 Err:4 http://deb.debian.org/debian bookworm Release
0.854   404  Not Found [IP: 146.75.118.132 80]
0.868 Err:5 http://deb.debian.org/debian bookworm-updates Release
0.868   404  Not Found [IP: 146.75.118.132 80]
0.878 Err:6 http://deb.debian.org/debian-security bookworm-security Release
0.878   404  Not Found [IP: 146.75.118.132 80]
0.902 Reading package lists...
0.946 E: The repository 'http://deb.debian.org/debian bookworm Release' does not have a Release file.
0.947 E: The repository 'http://deb.debian.org/debian bookworm-updates Release' does not have a Release file.
0.952 E: The repository 'http://deb.debian.org/debian-security bookworm-security Release' does not have a Release file.
  • Вопрос задан
  • 299 просмотров
Решения вопроса 1
@mxelgin Автор вопроса
Решение:

Собираем образ jenkins:2.462.3-jdk17 по инструкции
https://www.jenkins.io/doc/book/installing/docker/
FROM jenkins/jenkins:2.462.3-jdk17
USER root
RUN apt-get update && apt-get install -y lsb-release
RUN curl -fsSLo /usr/share/keyrings/docker-archive-keyring.asc \
  https://download.docker.com/linux/debian/gpg
RUN echo "deb [arch=$(dpkg --print-architecture) \
  signed-by=/usr/share/keyrings/docker-archive-keyring.asc] \
  https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list
RUN apt-get update && apt-get install -y docker-ce-cli
USER jenkins
RUN jenkins-plugin-cli --plugins "blueocean docker-workflow"


Далее собираем контейнер jenkins-blueocean из образа, в моем случае сборка идет из Docker Registry
services:
  jenkins:
    container_name: jenkins-blueocean
    image: 192.168.0.42:5000/jenkins:2.462.3-jdk17
    privileged: true  # Запуск с правами привилегированного контейнера
    ports:
      - "8080:8080"
      - "50000:50000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock  # Подключаем Docker сокет для доступа к хосту
    networks:
      jenkins_network:  # Используем пользовательскую сеть

networks:
  jenkins_network:  # Создание пользовательской сети
    driver: bridge


Теперь наша задача проверить что Jenkins видит образы
Заходим в контейнер, проверяем, соответственно ругается так как прав нет
jenkins@f2b6f83f5892:/$ docker images
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Head "http://%2Fvar%2Frun%2Fdocker.sock/_ping": dial unix /var/run/docker.sock: connect: permission denied


Так как у jenkins в сборе sudo нет все делаем под правами root
Устанавливаем пакет управления доступом (ACL)
root@f2b6f83f5892:/# apt-get install acl

даем пользователю jenkins доступ на чтение и запись
root@f2b6f83f5892:/# setfacl -m u:jenkins:rw /var/run/docker.sock


Перезаходим под пользователя jenkins
jenkins@f2b6f83f5892:/$ docker images

Появится список образов docker. Вопрос решен Jenkins находится в контейнере и видит Docker
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@vitaly_il1
DevOps Consulting
Или технология эта все еще сырая.

Jenkins не сырая, а седая - 15 лет назад контейнеры не использовали. Я не использовал jenkins последние 4-5 лет, sshagent действительно выглядит некрасиво тут.

И стоит на что-то другое посмотреть?

Если можно использовать, то Github Actions, или другое "облачное" решение - тогда не нужно поднимать/конфигурировать build environment.
Ответ написан
saboteur_kiev
@saboteur_kiev
software engineer
Все приложения должны крутиться в контейнерах. Соответственно Jenkins тоже должен жит в контейнере.


Почему?
Если дженкинс должен УПРАВЛЯТЬ контейнерами, то почему он сам должен крутиться внутри контейнера?
Или задача запускать контейнер в контейнере в контейнере?

Дженкинс в контейнере удобен, если вы запускаете его в кубере, чтобы он себе поднимал в нужный момент агенты и останавливал их. Просто так на хосте делать контейнер для дженкинса - ну можно конечно, но зачем..?
Запустить в контейнере мастер? или агент? Или у вас эксекуторы только на мастере?

Если у вас нет оркестратора, то нет смысла пихать дженкинс в контейнер, а потом изнутри искать выход наружу к папкам и ексекуторам. То есть у вас подход какой-то неправильный.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы