Назад | Перейти на главную страницу

Путаница с плагином Jenkins Docker и подчиненными серверами Jenkins Docker

Поэтому я приятно удивлен в некоторых отношениях, увидев, что плагин Jenkins Docker «проталкивает» образы Docker на мой хост Docker, но это тоже сбивает с толку, потому что мои сборки выполняются в Docker Slave Containers, которые работают на хосте Docker. Даже мой мастер Jenkins работает в контейнере Docker, а не непосредственно на металле ...

После этого популярного Дженкинс ведущий / ведомый гид Я подошел к тому моменту, когда у меня работали сборки Дженкинса. эфемерные контейнеры Docker.

Это означает, что когда я делаю Jenkins сборку некоторого моего программного компонента / службы с исходным кодом, сборка запускается на ведомом устройстве Jenkins, которое оказывается контейнером Docker, созданным с помощью подключаемого модуля Jenkins Docker.

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

Некоторые важные моменты, которые нужно предпринять после того, как вы усвоите эту диаграмму:

Итак, в этом Docker Slave создается мой артефакт сборки программного компонента / службы, например, это может быть .dll или .war. Однако случается так, что моим артефактом сборки будет образ Docker. Чтобы быть ясным, я создаю образ Docker внутри работающего контейнера Docker (подчиненного устройства Jenkins).

Мое замешательство начинается с того, что я ожидал, что мне придется явно запустить cmd, чтобы протолкнуть артефакт сборки образа Docker моего программного компонента в реестр Docker. В противном случае, когда задание сборки Jenkins будет завершено, плагин Docker отключит подчиненный контейнер Docker, избавится от (rm) подчиненного контейнера, и тогда я потеряю артефакт сборки внутри этого подчиненного контейнера.

Что происходит на самом деле и почему я приятно удивлен, по крайней мере, в краткосрочной перспективе, пока я начинаю работу с DevOps, так это то, что образ Docker артефакта сборки появляется на металле хоста Docker, docker image ls.

Я удивлен, что плагин Docker перешел на этот уровень предположения / помощи ... Я знаю, что плагин Docker позволяет вам настраивать реестр Docker и что вы можете добавить этап сборки в Build / Publish to a Docker Cloud, что я предполагаю это облако рассматривается как реестр изображений и, возможно, место для их запуска:

Что особенно интересно, я не использую подключаемый модуль Docker для каких-либо шагов сборки, я просто использую подключаемый модуль Docker для настройки подчиненного контейнера для сборки Jenkins Item:

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

Плагин Docker запускает подчиненные контейнеры Docker, я настраиваю плагин Docker и говорю ему, что Docker Host (мой металл в моей ситуации), облако - это то, что плагин Docker называет хостом Docker, а также подчиненные образы Docker для использования на этом хосте Docker / Облако:

Я просто не понимаю, насколько изолированным оказывается рабочее пространство сборки Jenkins, когда оно находится внутри ведомого контейнера Docker?

Плагин Docker просто по умолчанию использует одно-единственное Docker Cloud (мой хост Docker). У меня есть настройки для всех любых команд докеров, которые я выполняю в подчиненном контейнере Jenkins Docker? (кстати, подчиненный контейнер, на котором установлен Docker-CE)

Мой Дженкинс Мастер Dockerfile:

#reference
#https://engineering.riotgames.com/news/putting-jenkins-docker-container

FROM jenkins:2.60.1
MAINTAINER Brian Ogden

USER root

#Timezone
ENV TZ=America/Los_Angeles
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# Prep Jenkins Directories
RUN mkdir /var/log/jenkins
RUN mkdir /var/cache/jenkins
RUN chown -R jenkins:jenkins /var/log/jenkins
RUN chown -R jenkins:jenkins /var/cache/jenkins

# Copy in local config filesfiles
COPY plugins.sh /usr/local/bin/plugins.sh
RUN chmod +x /usr/local/bin/plugins.sh

# Install default plugins
# Set list of plugins to download / update in plugins.txt like this
# pluginID:version
# credentials:1.18
# maven-plugin:2.7.1
# ...
# NOTE : Just set pluginID to download latest version of plugin.
# NOTE : All plugins need to be listed as there is no transitive dependency resolution.
COPY plugins.txt /tmp/plugins.txt
RUN /usr/local/bin/plugins.sh /tmp/plugins.txt

USER jenkins

#give Jenkins a nice 8 GB memory pool and room to handle garbage collection
#ENV JAVA_OPTS="-Xmx8192m"
#give Jenkins a nice base pool of handlers and a cap
#ENV JENKINS_OPTS="--handlerCountStartup=100 --handlerCountMax=300"

ENV JENKINS_OPTS="--logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war"

Я использую docker-compose и Docker volume с моим Jenkins Master, моим docker-compose.yml:

version: '2'
services:
  data:
    build: data
    image: tsl.devops.jenkins.data.image
    container_name: tsl.devops.jenkins.data.container
  master:
    build: master
    image: tsl.devops.jenkins.master.image
    container_name: tsl.devops.jenkins.master.container
    volumes_from:
      - data
    ports:
      - "50000:50000"
    #network_mode: "host"
  nginx:
    build: nginx
    image: tsl.devops.jenkins.nginx.image
    container_name: tsl.devops.jenkins.nginx.container
    ports:
      - "80:80"
    links:
      - master:jenkins-master
  slavebasic:
    build:
      context: ./slaves
      dockerfile: basic/Dockerfile
    image: tsl.devops.jenkins.slave.basic.image
    container_name: tsl.devops.jenkins.slave.basic.container
  slavedotnetcore:
    build:
      context: ./slaves
      dockerfile: dotnetcore/Dockerfile
    image: tsl.devops.jenkins.slave.dotnetcore.image
    container_name: tsl.devops.jenkins.slave.dotnetcore.container

Мой Объем Jenkins Master/ диск Dockerfile:

#reference
#https://engineering.riotgames.com/news/docker-jenkins-data-persists
FROM centos:7
MAINTAINER Brian Ogden

#create the Jenkins user in this container
RUN useradd -d "/var/jenkins_home" -u 1000 -m -s /bin/bash jenkins
#NOTE: we set the UID here to the same one the Cloudbees Jenkins image uses 
#so we can match UIDs across containers, which is essential if you want 
#to preserve file permissions between the containers. We also use the same home directory and bash settings.

#Jenkins log directory
RUN mkdir -p /var/log/jenkins
RUN chown -R jenkins:jenkins /var/log/jenkins

#Docker volume magic
VOLUME ["/var/log/jenkins", "/var/jenkins_home"]
USER jenkins

#just a little output reminder of the container's purpose
CMD ["echo", "Data container for Jenkins"]

Мой Раб Dockerfile:

FROM centos:7
MAINTAINER Brian Ogden

#the USER will be root by default just explicitly 
#expressing it for better documentation
USER root

# Install Essentials
RUN yum update -y && \
         yum clean all

#############################################
# Jenkins Slave setup
#############################################
RUN yum install -y \
    git \
    wget \
    openssh-server \
    java-1.8.0-openjdk \
    sudo \
    make && \
    yum clean all

# gen dummy keys, centos doesn't autogen them like ubuntu does
RUN /usr/bin/ssh-keygen -A

# Set SSH Configuration to allow remote logins without /proc write access
RUN sed -ri 's/^session\s+required\s+pam_loginuid.so$/session optional pam_loginuid.so/' /etc/pam.d/sshd

# Create Jenkins User
RUN useradd jenkins -m -s /bin/bash

# Add public key for Jenkins login
RUN mkdir /home/jenkins/.ssh
COPY /files/id_rsa.pub /home/jenkins/.ssh/authorized_keys

#setup permissions for the new folders and files
RUN chown -R jenkins /home/jenkins
RUN chgrp -R jenkins /home/jenkins
RUN chmod 600 /home/jenkins/.ssh/authorized_keys
RUN chmod 700 /home/jenkins/.ssh

# Add the jenkins user to sudoers
RUN echo "jenkins  ALL=(ALL)  ALL" >> etc/sudoers
#############################################

#############################################
# Docker and Docker Compose Install
#############################################
#install required packages
RUN yum install -y \
    yum-utils \
    device-mapper-persistent-data \
    lvm2 \
    curl && \
    yum clean all

#add Docker CE stable repository
RUN yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

#Update the yum package index.
RUN yum makecache fast

#install Docker CE
RUN yum install -y docker-ce-17.06.0.ce-1.el7.centos

#install Docker Compose 1.14.0
#download Docker Compose binary from github repo
RUN curl -L https://github.com/docker/compose/releases/download/1.14.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
#Apply executable permissions to the binary
RUN chmod +x /usr/local/bin/docker-compose
#############################################

#############################################
# .NET Core SDK
#############################################
RUN yum install -y \
    libunwind \
    libicu

RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?linkid=848821
RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet
RUN ln -s /opt/dotnet/dotnet /usr/local/bin

#add Trade Service Nuget Server
RUN mkdir -p /home/jenkins/.nuget/NuGet
COPY /files/NuGet.Config /home/jenkins/.nuget/NuGet/NuGet.Config

RUN chown -R jenkins /home/jenkins/.nuget
RUN chgrp -R jenkins /home/jenkins/.nuget

RUN chmod 600 /home/jenkins/.nuget/NuGet/NuGet.Config
RUN chmod 700 /home/jenkins/.nuget/NuGet

#speed up dotnet core builds
ENV NUGET_XMLDOC_MODE skip
ENV DOTNET_SKIP_FIRST_TIME_EXPERIENCE true
#############################################

# Expose SSH port and run SSHD
EXPOSE 22
#Technically, the Docker Plugin enforces this call when it starts containers by overriding the entry command. 
#I place this here because I want this build slave to run locally as it would if it was started in the build farm.
CMD ["/usr/sbin/sshd","-D"]

Пример программное обеспечение / компонент Dockerfile, который создаст артефакт сборки образа Docker внутри контейнера Docker Slave Jenkins:

FROM centos:7
MAINTAINER Brian Ogden

#Timezone
ENV TZ=America/Los_Angeles
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN yum update -y && \
         yum clean all

#############################################
# .NET Core SDK
#############################################
RUN yum install -y \
    libunwind \
    libicu

RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?linkid=848821
RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet
RUN ln -s /opt/dotnet/dotnet /usr/local/bin

#speed up dotnet core builds
ENV NUGET_XMLDOC_MODE skip
ENV DOTNET_SKIP_FIRST_TIME_EXPERIENCE true
#############################################

#############################################
# .NET Sevrice setup
#############################################
ARG ASPNETCORE_ENVIRONMENT

# Copy our code from the "/src/MyWebApi/bin/Debug/netcoreapp1.1/publish" folder to the "/app" folder in our container
WORKDIR /app
COPY ./src/TSL.Security.Service/bin/Debug/netcoreapp1.1/publish .

# Expose port 5000 for the Web API traffic
ENV ASPNETCORE_URLS http://+:5000
ENV ASPNETCORE_ENVIRONMENT $ASPNETCORE_ENVIRONMENT 

EXPOSE 5000

# Run the dotnet application against a DLL from within the container
# Don't forget to publish your application or this won't work
ENTRYPOINT ["dotnet", "TSL.Security.Service.dll"]
#############################################

Согласно конфигурации вашего подключаемого модуля Docker, вы используете 172.17.0.1 в качестве хоста Docker. Из ведомого или главного контейнера это будет демон Docker, запущенный на хосте (здесь не происходит Docker в Docker). Когда ваше ведомое устройство Jenkins создает изображение (независимо от того, работает ли ведомое устройство как контейнер или на хосте), оно использует Docker на хосте, и именно поэтому ваше изображение появляется на хосте.

Стоит отметить, что данные, скорее всего, сначала поступают в том Docker, используемый ведомым устройством (согласно Jenkins Dockefile в https://github.com/jenkinsci/docker/blob/9f29488b77c2005bbbc5c936d47e697689f8ef6e/Dockerfile по умолчанию /var/jenkins_home). В вашем случае это просто том из data service (хотя в формате Compose v2 вы можете просто определить именованный том, вам не нужно создавать контейнер данных). Отсюда ваш код и Dockerfile отправляются в контекст сборки Docker на хосте через API по адресу tcp://172.17.0.1:4243.