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:
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:
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:
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:
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:
¿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"]#############################################