Então estou agradavelmente surpreso em alguns aspectos por ver o plugin do Jenkins Docker "empurrando" imagens do Docker para o meu host do Docker, mas é confuso também porque minhas construções estão ocorrendo no Docker Slave Containers em execução no host do Docker . Mesmo meu mestre Jenkins é executado em um contêiner Docker, não diretamente no metal ...
Seguindo este popular Guia mestre / escravo de Jenkins , cheguei ao ponto em que tive Jenkins trabalhando em contêineres Docker efêmeros .
Isso significa que quando eu faço Jenkins uma compilação de algum componente / serviço de software de código-fonte, a compilação é iniciada em um escravo Jenkins que é um Docker Container criado pelo Jenkins Docker Plugin.
O espaço de trabalho do Jenkins está neste contêiner de escravos, o mestre Jenkins com o Docker Plugin instalado, descartará esse contêiner de escravos assim que a construção estiver concluída. Veja um diagrama que fiz para ajudar a explicar:
Algunspontosdeacompanhamentoimportantesdepoisdeterdigeridoestediagrama:
- OJenkinsMastereoJenkinsSlaveestãorodandonomesmoDockerHostMetalnestemomento,jáqueestouapenasnosestágiosiniciaisdeexecuçãodestesistema
- Estouusandooplug-inDockereoplug-inSSHSlavespararealizaressaconfiguração
Assim,dentrodesteDockerSlave,meuartefatodecomponentedeserviço/construçãodeserviçoécriado,porexemplo,umarquivo.dllou.war.Acontece,noentanto,queomeuartefatodeconstruçãoseráumaimagemdoDocker.Paradeixarclaro,estouconstruindoumaimagemdoDockerdentrodeumcontêinerdoDockeremexecução(oJenkinsSlave).
MinhaconfusãocomeçacomaminhaexpectativadequedevoexecutarexplicitamenteumcmdparaenviarmeuartefatodecompilaçãodeimagemdoDockerdocomponentedesoftwareparaumregistrodoDocker.Casocontrário,quandootrabalhodeconstruçãodoJenkinsestiverconcluído,oplug-indoDockerdesligaráoescravodocontêinerdoDocker,descartará(rm)ocontêinerdoescravoeentãoperderáoartefatodeconstruçãodentrodessecontêinersecundário.
Oquerealmenteacontece,eporqueestouagradavelmentesurpreso,pelomenosacurtoprazoenquantoeuestouusandoodevops,équeaimagemdoDockerdoartefatodecompilaçãoaparecenometaldoDocker,dockerimagels
.
Estousurpresoqueoplug-indoDockerváparaesseníveldesuposição/ajuda...Euseiqueoplug-indoDockerpermiteconfigurarumregistrodoDockerequevocêpodeadicionarumaetapadecompilaçãoparacriar/publicaremumDockerCloudqueeuassumoqueanuvemétratadacomoumregistroparaimagensetalvezumlugarparatambémexecutaressasimagenstambém:
OqueéparticularmenteinteressanteéqueeunãoestouusandooDockerPluginparanenhumaetapadecompilação,apenasusooDockerPluginparaconfigurarumSlaveContainerparacompilaroJenkinsItem:
AúnicaetapadecriaçãoquetenhoéqueeuexecutoumscriptShell,sim,estescriptacabaporconstruirumaimagemdoDocker,masoDockerPluginnãosaberiadisso:
ODockerPluginfazoDockerSlaveContainers,euconfigurooDockerPluginedigoaeleumDockerHost(meumetalnaminhasituação)éumanuvemqueoDockerPluginchamadeDockerHostetambémimagensescravasdoDockerparausaresseDockerHost/Cloud:
Eusótenhomal-entendidossobrecomoumlocaldetrabalhodeconstruçãoJenkinsficaisoladoquandodentrodeumcontêinerdeescravodoDocker?
OPlug-indoDockeréopadrãoparausarapenasoDockerCloud(meumetalhostdoDocker)?EuconfigureitodososcomandosdodockerqueeuexecutedentrodeumcontêinerdeescravodoJenkinsDocker?(umcontêinerdeescravospelamaneiraqueoDocker-CEestáinstalado)
MeumestredoJenkinsDockerfile:
#reference#https://engineering.riotgames.com/news/putting-jenkins-docker-containerFROMjenkins:2.60.1MAINTAINERBrianOgdenUSERroot#TimezoneENVTZ=America/Los_AngelesRUNln-snf/usr/share/zoneinfo/$TZ/etc/localtime&&echo$TZ>/etc/timezone#PrepJenkinsDirectoriesRUNmkdir/var/log/jenkinsRUNmkdir/var/cache/jenkinsRUNchown-Rjenkins:jenkins/var/log/jenkinsRUNchown-Rjenkins:jenkins/var/cache/jenkins#CopyinlocalconfigfilesfilesCOPYplugins.sh/usr/local/bin/plugins.shRUNchmod+x/usr/local/bin/plugins.sh#Installdefaultplugins#Setlistofpluginstodownload/updateinplugins.txtlikethis#pluginID:version#credentials:1.18#maven-plugin:2.7.1#...#NOTE:JustsetpluginIDtodownloadlatestversionofplugin.#NOTE:Allpluginsneedtobelistedasthereisnotransitivedependencyresolution.COPYplugins.txt/tmp/plugins.txtRUN/usr/local/bin/plugins.sh/tmp/plugins.txtUSERjenkins#giveJenkinsanice8GBmemorypoolandroomtohandlegarbagecollection#ENVJAVA_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"
Eu uso o volume docker-compose e Docker com meu Jenkins Master, meu 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
Meu volume principal do Jenkins / drive 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"]
Meu Slave 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"]
Um exemplo de software / component Dockerfile que criará um artefato de construção de imagem do Docker dentro de um contêiner Jenkins Slave Docker:
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"]
#############################################