Confusión con el Complemento de Jenkins Docker y los Esclavos de Jenkins Docker

Por lo tanto, me sorprende gratamente en algunos aspectos ver que el complemento Jenkins Docker "empuja" imágenes de Docker a mi Docker host metal, pero también es confuso porque mis compilaciones se llevan a cabo en Contenedores Docker Slave que se ejecutan en el Docker host metal. Incluso mi maestro de Jenkins se ejecuta en un contenedor Docker, no directamente en metal...

Siguiendo este popular Guía maestro / esclavo de Jenkins Llegué al punto en el que tenía compilaciones de Jenkins trabajando contenedores Docker efímeros.

Esto significa que cuando hago Jenkins una compilación de algún componente/servicio de software de código fuente mío, la compilación se inicia en un esclavo de Jenkins que resulta ser un contenedor Docker creado por el complemento Jenkins Docker.

El espacio de trabajo de Jenkins está en este contenedor esclavo, el maestro de Jenkins con el complemento de Docker instalado, se deshará de este contenedor esclavo una vez que se complete la compilación. Vea un diagrama que hice para ayudar a explicar:

enter image description here

Algunos puntos de seguimiento importantes después de haber digerido este diagrama:

  • El Maestro de Jenkins y el Esclavo de Jenkins se ejecutan en el mismo host de Docker, en este momento, ya que estoy en las etapas iniciales de ejecutar este sistema
  • Estoy usando el complemento Docker y el complemento SSH Slaves para realizar esta configuración

Entonces, dentro de este esclavo de Docker, se crea mi artefacto de compilación de componentes/servicios de software, podría ser, por ejemplo, a .dll o a .guerra. Sin embargo, sucede que mi artefacto de compilación será una imagen de Docker. Para ser claros, estoy construyendo una imagen de Docker dentro de un Contenedor de Docker en ejecución (el Esclavo de Jenkins).

Mi confusión comienza con mi expectativa de que debería tener que ejecutar explícitamente un cmd para enviar mi componente de software Docker image build artifact a un registro de Docker. De lo contrario, cuando se complete el trabajo de compilación de Jenkins, el complemento de Docker cerrará el contenedor esclavo de Docker, eliminará (rm) el contenedor esclavo y luego perderé el artefacto de compilación dentro de ese contenedor esclavo.

Lo que realmente sucede, y por qué me sorprende gratamente, al menos a corto plazo mientras estoy poniendo en marcha devops, es que la imagen de la ventana acoplable build Artifact aparece en el host de la ventana acoplable., docker image ls.

Me sorprende que el complemento Docker vaya a este nivel de suposición/ayuda... Sé que el complemento de Docker le permite configurar un registro de Docker y que puede agregar un paso de compilación para Compilar/Publicar en una nube de Docker, lo que supongo que la nube se trata como un registro de imágenes y tal vez un lugar para ejecutar esas imágenes también:

enter image description here

Lo que es particularmente interesante es que no estoy usando el Complemento Docker para ningún paso de compilación, solo uso el Complemento Docker para configurar un Contenedor Esclavo para el Elemento build Jenkins:

enter image description here

El único paso de compilación que tengo es que ejecuto un Script de Shell, sí, este script finalmente crea una imagen de Docker, pero el complemento de Docker no lo sabría:

enter image description here

El Complemento de Docker hace girar los Contenedores Esclavos de Docker, configuro el Complemento de Docker y le digo un Host de Docker (mi metal en mi situación) una Nube es lo que el Complemento de Docker llama Host de Docker y también imágenes de esclavos de Docker para usar en ese Host/Nube de Docker:

enter image description here¿Tengo malentendidos sobre cuán aislado está un espacio de trabajo de compilación de Jenkins cuando está dentro de un contenedor esclavo de Docker?

¿El complemento de Docker simplemente usa de forma predeterminada la única Nube de Docker (mi host de Docker metal) que he configurado para todos los comandos de docker que ejecuto dentro de un contenedor esclavo de Jenkins Docker? (un contenedor esclavo por cierto que tiene Docker-CE instalado en él)

Mi Maestro de Jenkins Dockerfile:

#reference#https://engineering.riotgames.com/news/putting-jenkins-docker-containerFROM jenkins:2.60.1MAINTAINER Brian OgdenUSER root#TimezoneENV TZ=America/Los_AngelesRUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone# Prep Jenkins DirectoriesRUN mkdir /var/log/jenkinsRUN mkdir /var/cache/jenkinsRUN chown -R jenkins:jenkins /var/log/jenkinsRUN chown -R jenkins:jenkins /var/cache/jenkins# Copy in local config filesfilesCOPY plugins.sh /usr/local/bin/plugins.shRUN 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.txtRUN /usr/local/bin/plugins.sh /tmp/plugins.txtUSER 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"

Uso docker-compose y Docker volume con mi maestro de Jenkins, mi 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

Mi Volumen maestro de Jenkins/unidad Dockerfile:

#reference#https://engineering.riotgames.com/news/docker-jenkins-data-persistsFROM centos:7MAINTAINER Brian Ogden#create the Jenkins user in this containerRUN 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 directoryRUN mkdir -p /var/log/jenkinsRUN chown -R jenkins:jenkins /var/log/jenkins#Docker volume magicVOLUME ["/var/log/jenkins", "/var/jenkins_home"]USER jenkins#just a little output reminder of the container's purposeCMD ["echo", "Data container for Jenkins"]

Mi Esclavo Dockerfile:

FROM centos:7MAINTAINER Brian Ogden#the USER will be root by default just explicitly #expressing it for better documentationUSER root# Install EssentialsRUN 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 doesRUN /usr/bin/ssh-keygen -A# Set SSH Configuration to allow remote logins without /proc write accessRUN sed -ri 's/^session\s+required\s+pam_loginuid.so$/session optional pam_loginuid.so/' /etc/pam.d/sshd# Create Jenkins UserRUN useradd jenkins -m -s /bin/bash# Add public key for Jenkins loginRUN mkdir /home/jenkins/.sshCOPY /files/id_rsa.pub /home/jenkins/.ssh/authorized_keys#setup permissions for the new folders and filesRUN chown -R jenkins /home/jenkinsRUN chgrp -R jenkins /home/jenkinsRUN chmod 600 /home/jenkins/.ssh/authorized_keysRUN chmod 700 /home/jenkins/.ssh# Add the jenkins user to sudoersRUN echo "jenkins  ALL=(ALL)  ALL" >> etc/sudoers########################################################################################### Docker and Docker Compose Install##############################################install required packagesRUN yum install -y \    yum-utils \    device-mapper-persistent-data \    lvm2 \    curl && \    yum clean all#add Docker CE stable repositoryRUN 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 CERUN yum install -y docker-ce-17.06.0.ce-1.el7.centos#install Docker Compose 1.14.0#download Docker Compose binary from github repoRUN 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 binaryRUN chmod +x /usr/local/bin/docker-compose########################################################################################### .NET Core SDK#############################################RUN yum install -y \    libunwind \    libicuRUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?linkid=848821RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnetRUN ln -s /opt/dotnet/dotnet /usr/local/bin#add Trade Service Nuget ServerRUN mkdir -p /home/jenkins/.nuget/NuGetCOPY /files/NuGet.Config /home/jenkins/.nuget/NuGet/NuGet.ConfigRUN chown -R jenkins /home/jenkins/.nugetRUN chgrp -R jenkins /home/jenkins/.nugetRUN chmod 600 /home/jenkins/.nuget/NuGet/NuGet.ConfigRUN chmod 700 /home/jenkins/.nuget/NuGet#speed up dotnet core buildsENV NUGET_XMLDOC_MODE skipENV DOTNET_SKIP_FIRST_TIME_EXPERIENCE true############################################## Expose SSH port and run SSHDEXPOSE 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"]

Ejemplo software/componente Dockerfile que creará un artefacto de compilación de imágenes de Docker dentro de un contenedor Docker esclavo de Jenkins:

FROM centos:7MAINTAINER Brian Ogden#TimezoneENV TZ=America/Los_AngelesRUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezoneRUN yum update -y && \         yum clean all############################################## .NET Core SDK#############################################RUN yum install -y \    libunwind \    libicuRUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?linkid=848821RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnetRUN ln -s /opt/dotnet/dotnet /usr/local/bin#speed up dotnet core buildsENV NUGET_XMLDOC_MODE skipENV 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 containerWORKDIR /appCOPY ./src/TSL.Security.Service/bin/Debug/netcoreapp1.1/publish .# Expose port 5000 for the Web API trafficENV ASPNETCORE_URLS http://+:5000ENV 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 workENTRYPOINT ["dotnet", "TSL.Security.Service.dll"]#############################################

De acuerdo con la configuración de su complemento de Docker, está utilizando 172.17.0.1 como el host de Docker. Desde el contenedor esclavo o maestro, este será el demonio de Docker que se ejecuta en el host (aquí no hay Docker en Docker). Cuando su esclavo Jenkins crea una imagen (independientemente de si el esclavo se ejecuta como un contenedor o en el host), está utilizando la ventana acoplable en el host y es por eso que su imagen aparece en el host.

Vale la pena señalar que los datos probablemente vayan primero al volumen de la ventana acoplable que está utilizando el esclavo (de acuerdo con Jenkins Dockefile en https://github.com/jenkinsci/docker/blob/9f29488b77c2005bbbc5c936d47e697689f8ef6e/Dockerfile el valor predeterminado es /var/jenkins_home). En su caso, este es solo un volumen de la data servicio (aunque, en formato Compose v2, solo puede definir un volumen con nombre, no necesita crear un contenedor de datos). A partir de aquí, su código y Dockerfile se envía al contexto de compilación de Docker en el host a través de la API en tcp://172.17.0.1:4243.

¿Puede confirmar el diseño del host? ¿El maestro y el esclavo de Jenkins están en diferentes hosts físicos? Además, ¿qué complementos de Docker está utilizando? Me doy cuenta de que hay al menos dos para Jenkins (Complemento de Docker y Complemento de Esclavos de Docker, no estoy seguro de si está utilizando uno o ambos u otro).

Tengo una explicación que puedo dar. Pero estoy confundido en un par de partes más que tal vez puedas aclarar. 1) ¿Cómo sabe el complemento Docker slaves iniciar Jenkins como la imagen de la ventana acoplable esclava? No me queda claro cómo el esclavo de Jenkins realmente lanza la imagen desde elDockerfile ' que proporciona. 2) ¿Puede confirmar el comandodocker run` que utilizó para iniciar el maestro? Me pregunto si pasa al socket de control de la ventana acoplable, en cuyo caso cualquier compilación en el contenedor simplemente usaría la ventana acoplable del host (por lo tanto, por qué está viendo que la imagen se está compilando en el host). Describiré esto como una respuesta.

@AndyShinn ok, actualicé mi pregunta con la información que solicitaste. He agregado mi Dockerfile para mi Maestro de Jenkins, que tiene un volumen de Docker, así que también agregué mi Dockerfile para el volumen de datos maestro de Jenkins. También expliqué, incluida la captura de pantalla de configuración de Jenkins, cómo configura el “Complemento de Docker”, NO el complemento de esclavos de Docker como lo llamó, para usar una imagen de Docker definida como Esclavo, mi Dockerfile para mi esclavo se incluyó en mi pregunta original