Как перейти к контейнерам (4 части серии)
В прошлый раз мы создали простые трубопровод Jenkins CI с опросом, поэтому наши изображения всегда в курсе, когда мы нажимаем изменения в нашу кодовую базу.
Я не люблю использовать опрос для этого, и вы не должны либо. Подход опроса либо ненадежен, если время слишком медленно, и слишком много комбинируют в одном изображении, либо производит ненужную нагрузку, если вы позволите ему опросить каждую секунду.
Представьте себе, что ваш босс собирается «Эй, это сделана функция? Как насчет сейчас? Прошло 5 секунд, что-то новое? ». A) Это раздражает и б) вы не получите ничего, что делают так, верно?
Скорее, вы бы предпочли сообщить своему боссу «Эй, функция сделана, посмотрите!» И продолжай делать что-то новое, верно?
Итак, давайте реализуем это и уведомим наш CI-сервер всякий раз, когда коммит нажата. Не чувствую себя влево, если вы не используете Gitlab или Jenkins в своих проектах, большинство инструментов Git/Ci предлагают функцию такого рода.
Настраивать
Это наш список до ведений:
- Сделайте DNS-имена для контейнерных коммуникаций, потому что поиск IPS контейнеров раздражает
- Загрузите экземпляр Дженкинса и создайте работу, которую мы можем вызвать через веб-вики
- Загрузите экземпляр GitLab и создайте репо с демонстрацией DockerFile и WebHook
Итак, давайте будем трещины!
DNS-разрешение
Я мог бы пойти на тангенту и рассказать вам грандиозную историю, но, короче говоря, сеть мостов по умолчанию не имеет разрешения DNS из-за причин. Если вы хотите DNS-разрешение для контейнеров по их имени, вам нужно создать пользовательскую мостовую сеть. Что к счастью, очень легко сделать!
$ docker network create dns-bridge $ docker network ls NETWORK ID NAME DRIVER SCOPE 9508cfea746d bridge bridge local 67aa52615190 dns-bridge bridge local ae9791d28429 host host local d2c62d84bc06 none null local
Вот и все, теперь у вас есть пользовательский мост, который автоматически делает разрешение DNS. Давайте проверим это:
docker run -d --name busybox1 --network dns-bridge busybox:1.28 sleep 3600 docker run -d --name busybox2 --network dns-bridge busybox:1.28 sleep 3600 $ docker exec -ti busybox1 ping busybox2 PING busybox2 (172.20.1.2): 56 data bytes 64 bytes from 172.20.1.2: seq=0 ttl=64 time=0.071 ms 64 bytes from 172.20.1.2: seq=1 ttl=64 time=0.057 ms And the reverse: $ docker exec -ti busybox1 ping busybox2 PING busybox2 (172.20.1.2): 56 data bytes 64 bytes from 172.20.1.2: seq=0 ttl=64 time=0.071 ms 64 bytes from 172.20.1.2: seq=1 ttl=64 time=0.057 ms
Это выглядит довольно хорошо!
Если вы хотите подключить/отключить уже запущенный контейнер к сети:
$ docker run -d --name busybox-ext busybox:1.28 sleep 3600
2efe297352a6ff1e9876a46c853b786a415480235d05df9451672689d580ad6e
$ docker network connect dns-bridge busybox-ext
$ docker network inspect dns-bridge -f "{{range .Containers}}{{println .Name}}{{end}}"
busybox-ext
busybox2
busybox1
$ docker network disconnect dns-bridge busybox-ext
$ docker network inspect dns-bridge -f "{{range .Containers}}{{println .Name}}{{end}}"
busybox2
busybox1
Хорошо, давайте продолжим настроить наш экземпляр Дженкинса
Jenkins.
Для этого поста я построил пользовательский Docker-In-Docker Jenkins на основе Alpine, который я вам скажу, был ужасным опытом. Я не доволен этим Dockerfile, так что не распятите меня, пожалуйста. Хотя я мог бы поставить его на Github или что-то, я не хочу, чтобы вы клонировали случайное репо, и просто запустили его, не по крайней мере, посмотрели на него. Поэтому я буду одним плохим учителем, никто не любит и не позволю тебе копировать два файла, которые вам нужно отсюда:)
FROM alpine
USER root
RUN apk add --no-cache \
bash \
coreutils \
curl \
git \
git-lfs \
openssh-client \
tini \
ttf-dejavu \
tzdata \
unzip \
openjdk11-jdk \
shadow \
docker
# Install Gosu
ENV GOSU_VERSION 1.12
RUN set -eux; \
\
apk add --no-cache --virtual .gosu-deps \
ca-certificates \
dpkg \
gnupg \
; \
\
dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
\
# verify the signature
export GNUPGHOME="$(mktemp -d)"; \
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
command -v gpgconf && gpgconf --kill all || :; \
rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
\
# clean up fetch dependencies
apk del --no-network .gosu-deps; \
\
chmod +x /usr/local/bin/gosu; \
# verify that the binary works
gosu --version; \
gosu nobody true
ARG user=jenkins
ARG group=jenkins
ARG uid=1001
ARG gid=1001
ARG http_port=8080
ARG agent_port=50000
ARG JENKINS_HOME=/var/jenkins_home
ARG REF=/usr/share/jenkins/ref
ENV JENKINS_HOME $JENKINS_HOME
ENV JENKINS_SLAVE_AGENT_PORT ${agent_port}
ENV REF $REF
# Jenkins is run with user `jenkins`, uid = 1000
# If you bind mount a volume from the host or a data container,
# ensure you use the same uid
RUN mkdir -p $JENKINS_HOME \
&& chown ${uid}:${gid} $JENKINS_HOME \
&& addgroup -g ${gid} ${group} \
&& adduser -h "$JENKINS_HOME" -u ${uid} -G ${group} -s /bin/bash -D ${user}
# Jenkins home directory is a volume, so configuration and build history
# can be persisted and survive image upgrades
VOLUME $JENKINS_HOME
# $REF (defaults to `/usr/share/jenkins/ref/`) contains all reference configuration we want
# to set on a fresh new installation. Use it to bundle additional plugins
# or config file with your custom jenkins Docker image.
RUN mkdir -p ${REF}/init.groovy.d
# jenkins version being bundled in this docker image
ARG JENKINS_VERSION
ENV JENKINS_VERSION ${JENKINS_VERSION:-2.222.4}
# jenkins.war checksum, download will be validated using it
ARG JENKINS_SHA=6c95721b90272949ed8802cab8a84d7429306f72b180c5babc33f5b073e1c47c
# Can be used to customize where jenkins.war gets downloaded from
ARG JENKINS_URL=https://repo.jenkins-ci.org/public/org/jenkins-ci/main/jenkins-war/${JENKINS_VERSION}/jenkins-war-${JENKINS_VERSION}.war
# Could use ADD but this one does not check Last-Modified header neither does it allow to control checksum
# See https://github.com/docker/docker/issues/8331
RUN curl -fsSL ${JENKINS_URL} -o /usr/share/jenkins/jenkins.war \
&& echo "${JENKINS_SHA} /usr/share/jenkins/jenkins.war" | sha256sum -c -
ENV JENKINS_UC https://updates.jenkins.io
ENV JENKINS_UC_EXPERIMENTAL=https://updates.jenkins.io/experimental
ENV JENKINS_INCREMENTALS_REPO_MIRROR=https://repo.jenkins-ci.org/incrementals
RUN chown -R ${user} "$JENKINS_HOME" "$REF"
# For main web interface:
EXPOSE ${http_port}
# Will be used by attached agents:
EXPOSE ${agent_port}
ENV COPY_REFERENCE_FILE_LOG $JENKINS_HOME/copy_reference_file.log
# Download and place scripts needed to run
RUN curl https://raw.githubusercontent.com/jenkinsci/docker/master/jenkins-support -o /usr/local/bin/jenkins-support && \
curl https://raw.githubusercontent.com/jenkinsci/docker/master/jenkins.sh -o /usr/local/bin/jenkins.sh && \
curl https://raw.githubusercontent.com/jenkinsci/docker/master/tini-shim.sh -o /bin/tini && \
curl https://raw.githubusercontent.com/jenkinsci/docker/master/plugins.sh -o /usr/local/bin/plugins.sh && \
curl https://raw.githubusercontent.com/jenkinsci/docker/master/install-plugins.sh -o /usr/local/bin/install-plugins.sh
COPY --chown=${user} entrypoint.sh /entrypoint.sh
RUN chmod +x /usr/local/bin/install-plugins.sh /usr/local/bin/plugins.sh /usr/local/bin/jenkins.sh /bin/tini /usr/local/bin/jenkins-support
RUN chmod +x /entrypoint.sh
# Stay root, the entrypoint drops down to User jenkins via gosu
ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh
#!/bin/sh # By: Brandon Mitchell# License: MIT # Source Repo: https://github.com/sudo-bmitch/jenkins-docker set -x # configure script to call original entrypoint set -- tini -- /usr/local/bin/jenkins.sh "$@" # In Prod, this may be configured with a GID already matching the container # allowing the container to be run directly as Jenkins. In Dev, or on unknown # environments, run the container as root to automatically correct docker # group in container to match the docker.sock GID mounted from the host. if [ "$(id -u)" = "0" ]; then # get gid of docker socket file SOCK_DOCKER_GID=`ls -ng /var/run/docker.sock | cut -f3 -d' '` # get group of docker inside container CUR_DOCKER_GID=`getent group docker | cut -f3 -d: || true` # if they don't match, adjust if [ ! -z "$SOCK_DOCKER_GID" -a "$SOCK_DOCKER_GID" != "$CUR_DOCKER_GID" ]; then groupmod -g ${SOCK_DOCKER_GID} -o docker fi if ! groups jenkins | grep -q docker; then usermod -aG docker jenkins fi #If you run on MacOS if ! groups jenkins | grep -q staff; then usermod -aG staff jenkins fi # Add call to gosu to drop from root user to jenkins user # when running original entrypoint set -- gosu jenkins "$@" fi # replace the current pid 1 with original entrypoint exec "$@"
Построить и запустить наши Jenkins Image:
# We need to create a directory for Jenkins to save his data to
# Since to container runs with UID:GID 1001:1001, the folder also needs to get correct permissions
mkdir $HOME/jenkins && chown 1001:1001 $HOME/jenkins
docker build -t myjenkins .
docker run -d \
-v $HOME/jenkins:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 8080:8080 \
--name jenkins \
--network dns-bridge \
--restart unless-stopped \
myjenkins
Что это делает?
- Mount To Home/Jenkins гарантирует, что вы не должны перенастроить Jenkins каждый раз, когда вы убиваете/остановите контейнер Дженкинса. Это просто удобство.
- Мы устанавливаем Docker.sock в jenkins, поэтому Дженкинс может построить наши изображения докера, не имея собственного функционирования Docker-Runtime. Эта концепция называется Docker в Docker.
- Остальные должны быть самоизначения, мы публикуем порт Дженкинса, чтобы мы могли получить доступ к нему от хоста, прикрепить его к сетевому мосту, которую мы создали и убедитесь, что контейнер перезагружается в неудачу, если мы не остановимся
Gitlab.
#Where you want to store data export GITLAB_HOME=$HOME/gitlab docker run -d \ -p 443:443 -p 80:80 -p 22:22 \ --name gitlab \ --network dns-bridge \ --restart unless-stopped \ -v $GITLAB_HOME/config:/etc/gitlab \ -v $GITLAB_HOME/logs:/var/log/gitlab \ -v $GITLAB_HOME/data:/var/opt/gitlab \ gitlab/gitlab-ce:latest
И да, я знаю, что это ломает правило «построить его самостоятельно», но я не могу за жизнь меня получить Gitlab, бегая на Alpine, поэтому для этой демонстрации я прошу вас нести с собой это один раз. Конечно, я буду обновлять этот пост соответственно, как только я получил Gitlab, чтобы работать плавно на альпий:)
Если вы не хотите, чтобы контейнеры могли воспроизводить в вашей файловой системе, просто удалите крепления. ПРИМЕЧАНИЕ. Опять же, вам придется снова настроить все, если перезагрузите контейнеры без их данных где-то сохраняются
Изображение Gitlab Omnibus занимает некоторое время для загрузки, вы можете отслеживать его через Docker Logs -f Gitlab чтобы увидеть, когда он готов к использованию. После того, как он загружается, вы можете открыть Gitlab ui В вашем любимом браузере и установите пароль для пользователя корень . Тогда вы готовы создать несколько REPOS:)
Дополнительная информация о изображений GitLab Docker можно найти здесь
Демо-репозиторий
Теперь, когда наш блестящий новый Gitlab работает, давайте создадим демо-репозиторий здесь и совершить следующую демонстрацию Dockerfile к нему:
FROM alpine:latest
RUN echo '#!/bin/sh' > /tmp/hello.sh && \
echo 'echo "Hello $1"' >> /tmp/hello.sh && \
chmod +x /tmp/hello.sh && \
chown nobody. /tmp/hello.sh
USER nobody
ENTRYPOINT ["/bin/sh"]
CMD ["/tmp/hello.sh", "Me!"]
Это очень простой контейнер, который просто эхо приветствие, которое будет достаточно, чтобы продемонстрировать наш GIT-крючок.
Добавьте, совершайте и нажимайте файл на данный момент.
Демонстрация
Сейчас самое время возвращаться к нашим демонстрации Дженкинса, мы хотели настроить ранее.
Теперь, когда у нас есть источник, чтобы построить, мы можем использовать его в нашей работе. Создайте трубопровод с любимым именем здесь Со следующим контентом:
node {
stage("Git Checkout") {
git credentialsId: 'gitlab', url: 'http://gitlab/root/demo'
}
stage("Docker Build") {
app = docker.build('awesome-image')
}
stage("Docker Push") {
docker.withRegistry("http://registry.local:5000") {
app.push("awesome-tag-${env.BUILD_NUMBER}")
app.push("latest")
}
}
}
Как вы, вероятно, видели, мы пропускаем две вещи:
- учетные данные для gitlab.
- Реестр «Реестр.local: 5000»
Учетные данные Дженкинса Gitlab
Идти здесь И добавьте учетные данные, которые вы установлены для GitLab ранее:
Имя пользователя и пароль очевидны. Идентификатор — это «Shortname», которое вы будете использовать в своих трубопроводах. В этом примере это «GitLab». Описание просто так, читаемое человеческое описание для легкого различия различных учетных данных, которые вы можете иметь.
Что касается остальной части конфигурации, например, плагины и докер выполнения, вы можете взглянуть на предыдущий пост в качестве руководства.
Реестр
Чтобы выстрелить и подключить наш реестр на наш DNS-мост:
docker run -d -p 5000:5000 --name registry.local --network dns-bridge registry:2
Так как мы бегаем Docker-In-Docker, Push работает с нашего хозяина. Поэтому наш хост должен знать реестр DNS-Name.local. Убедитесь, что это на наших хозяевах с
cat /etc/hosts
Если это не так, просто добавьте его через
echo '127.0.0.1 registry.local' | sudo tee -a /etc/hosts
Это должно исправить это. Теперь вы можете вызвать сборку и насладиться шоу!
Это должно быть успешным, и вы можете докер потянуть его в любое время из нашего реестра:)
Хорошо, на дому домой! Мы сделаем со всей подготовкой, поэтому давайте доберемся до того, что мы действительно хотели достичь.
Установите конечную точку для Дженкинса
Чтобы включить Jenkins-Jobs, которые будут запускаться через HTTP-запрос, вам нужно сделать несколько вещей.
Во-первых, проверьте следующую коробку на работе и определите секретный токен.
Теперь нам нужен API-токен для аутентификации с Jenkins в HTTP-запросах, без необходимости использовать фактический пароль нашего пользователя администратора. Вы можете создать токен здесь Сохраните его где-нибудь, что вы можете скопировать его с позже, потому что этот маленький Bugger ушел, как только вы перейдуте с текущей страницы.
В качестве хорошей выгоды вы можете отслеживать позже, сколько раз был использован токен. Аккуратный!
Настройте веб -ook в GitLab
Это все, конец дороги, мы находимся рядом с финишной чертой!
GitLab — это умный, они не хотят разрешать веб-капли, чтобы спам локальную сеть экземпляра GitLab, чтобы предотвратить повреждение. Но мы хотим позволить это сделать это с Дженкинсом, потому что иначе, что сделает этот целый механик для нас. Так что иди к Панель администратора И в разделе «Исходящие запросы» добавьте «Jenkins» в «Whitelist, чтобы разрешить запросы локальной сети с крюков и услуг». Не проверяйте коробку, которая позволяет всем адресам в локальной сети! Просто добавьте женкинс в белый список
Теперь, чтобы создать веб -ook, откройте свой проект и с левой стороны перейдите к настройкам -> WebHook и настроить ваш веб -ook, как это:
Для простого копирования и вставки, возьмите этот шаблон и заполните свои значения: http://: @: <8080>/Работа//Создание? токен =
Финальный тест
Теперь наша взаимосвязь между Gitlab и Jenkins автоматизированы для этой работы и репозитория. Так что давайте проверим это!
Измените свой DockerFile, совершите и выталкивайте его, а через несколько секунд вы должны иметь документ Docker в вашем локальном реестре, который отражает ваши изменения!
Outro.
Я должен признать, что это было немного работой, чтобы бежать на местном уровне, особенно изображение Дженкинса-дина для Макоса .. Но я думаю, что это сделало тебя и мне немного умнее, поэтому я надеюсь, что это поможет вам в вашем путешествии к переходу к контейнерам.
Если нет, застрелить мне сообщение, оставьте комментарий или задавайте вопросы. Если есть одно, что у меня есть, пришло время, терпение и талант для «создания вещей» или сломать их: D
В следующий раз, когда я, наверное, напишу о том, как мы можем отсканировать наши изображения для CEND, что черновик почти закончен:)
Как перейти к контейнерам (4 части серии)
Оригинал: «https://dev.to/habereder/how-to-setup-gitlab-to-trigger-jenkins-on-push-3b9d»