Доступ к родительскому демону из контейнера в Jenkins - PullRequest
0 голосов
/ 16 января 2019

У нас есть несколько узлов, выполняющих наши задания в Дженкинсе.Мне нужно создать два изображения из работы Дженкинса.Для этого я прочитал, что вы должны использовать сокет unix, используя монтирование, и я сделал это следующим образом:

agent {
    docker {
        image 'custom-alpine-with-docker'
        args '-v /var/run/docker.sock:/var/run/docker.sock'
    }
}

Затем я хочу использовать его следующим образом:

stage('Build and push image(s)') {
    steps {
        dir("${WORKING_DIRECTORY}") {
            script {
                echo 'Building amd64 image'
                amd64image = docker.build("${IMAGE_NAME}:${BUILD_NUMBER}-amd64", "-f ./Dockerfile.amd64 .")
                echo 'Building arm32v7 image'
                arm32v7image = docker.build("${IMAGE_NAME}:${BUILD_NUMBER}-arm32v7", "-f ./Dockerfile.arm32v7 .")
            }
            script {
                docker.withRegistry("${DOCKER_REGISTRY_URL}", "${REPOSITORY_CREDENTIALS}") {
                    amd64image.push()
                    arm32v7image.push()
                }
            }
        }
    }
}

Однако, как только в задании jenkins введена команда построения, я получаю следующую ошибку:

time = "2019-01-16T16: 55: 33Z" level =ошибка msg = "не удалось набрать gRPC: не удается подключиться к демону Docker. На этом хосте запущен" демон docker "?: dial unix /var/run/docker.sock: connect: разрешение запрещено" 17:56:59 Получено разрешениеотказано при попытке подключиться к сокету демона Docker в unix: ///var/run/docker.sock:

Таким образом, простой поиск показывает, что источником этой ошибки является то, что пользователь пытается получить доступдемон не входит в группу Docker, но я не понимаю, как работают эти членства в группах, когда делятся таким демоном.

Если я иду на узел, который не смог выполнить сборку, и проверяю пользователей вДокер группы, я получаю следующее:

$ getent group docker
docker:x:126:inst,jenkins

Так как мне всеw пользователь, работающий в контейнере на этом хосте для доступа к тому же демону?

Небольшое обновление

Просто сделал это локально, используя docker run -v /var/run/docker.sock:/var/run/docker.sock -ti docker, и когда я пишу docker ps в контейнере и на моем хосте я вижу, что работают те же контейнеры.

Получение всех пользователей на моей машине для разработки выглядит следующим образом:

docker:x:999:overlord

Так что я угадываюМне нужно специальное решение Дженкинса, чтобы это работало ..

1 Ответ

0 голосов
/ 18 января 2019

Я думаю, что решил это удовлетворительным образом. Вот пошаговое руководство:

  1. Убедитесь, что докер установлен в контейнере, который должен его запустить
  2. Создание группы докеров и пользователя jenkins:
CMD DOCKER_GID=$(stat -c '%g' /var/run/docker.sock) && \
    groupmod --gid ${DOCKER_GID} ${DOCKER_GROUP} && \
    usermod -a -G ${DOCKER_GROUP} ${JENKINS_USER} && \
    gosu jenkins sh

Важно отметить, что здесь я выбираю идентификатор группы базовой системы, которая запускает Docker. Поскольку я уже установил докер в свой контейнер и группа уже существует, я изменяю существующую группу, чтобы она соответствовала идентификатору группы системы. Наконец, я добавляю пользователя jenkins в группу Docker. Ваша / etc / group должна выглядеть примерно так в контейнере после запуска:

Докер: X: 999: Дженкинс

  1. В вашем конвейере запустите агент следующим образом:
agent {
    docker {
        image 'storemanager-build'
        args '-u root -v /var/run/docker.sock:/var/run/docker.sock'
    }
}

Предоставляя флаг -u root, вы переопределяете пользователя jenkins, который навязывает вам jenkins при использовании декларативного конвейера. Для работы команды CMD и возможности создания группы необходимо использовать root.

Когда образ работает, команда переключится на пользователя jenkins, которому разрешен доступ к базовому сокету unix.

Вот выдержка из моего Jenkinsfile:

pipeline {

    agent {
        docker {
            image 'build-image'
            args '-u root -v /var/run/docker.sock:/var/run/docker.sock'
        }
    }

    stages {

        stage('Build jar') {
            steps {
                dir("${WORKING_DIRECTORY}") {
                    script {
                        if (isUnix()) {
                            sh './mvnw --batch-mode clean install'
                        } else {
                            bat 'mvnw.cmd --batch-mode clean install'
                        }
                    }
                }
            }
        }

        stage('Build and push image(s)') {
            steps {
                dir("${WORKING_DIRECTORY}") {
                    script {
                        amd64image = docker.build("${IMAGE_NAME}", "-f ./Dockerfile.amd64 .")
                        arm32v7image = docker.build("${IMAGE_NAME}", "-f ./Dockerfile.arm32v7 .")
                    }
                    script {
                        docker.withRegistry("${DOCKER_REGISTRY_URL}", "${STOREMANAGER_REPOSITORY_CREDENTIALS}") {
                            amd64image.push("${BUILD_NUMBER}-amd64")
                            arm32v7image.push("${BUILD_NUMBER}-arm32v7")
                        }
                    }
                }
            }
        }
    }

    post {
        always {
            sh "chmod -R 777 ." // Jenkins can't clean built resources without this as we run the container as root
            cleanWs()
        }
    }
}

И ресурсы, которые мне помогли:

https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/ https://github.com/jenkinsci/docker/issues/196

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...