Portanto, estou agradavelmente surpreso em alguns aspectos ao ver o plug-in Jenkins Docker "empurrando" imagens Docker para o meu Docker host metal, mas também é confuso porque minhas compilações estão ocorrendo em contêineres Docker Slave que estão sendo executados no Docker host metal. Mesmo meu Mestre Jenkins corre em um contêiner Docker, não diretamente no metal...
Seguindo este popular Jenkins mestre / escravo guia Cheguei ao ponto em que eu tinha compilações Jenkins trabalhando em contentores 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 Meu, a compilação é iniciada em um escravo Jenkins que passa a ser um contêiner Docker girado pelo plug-in Jenkins Docker.
O espaço de trabalho Jenkins está neste contêiner escravo, O Mestre Jenkins com o plug-in Docker instalado, descartará esse contêiner escravo assim que a compilação for concluída. Veja um diagrama que fiz para ajudar a explicar:
Alguns pontos de acompanhamento importantes depois de ter digerido este diagrama:
- O Jenkins Master e o Jenkins Slave estão rodando no mesmo Docker Host Metal neste momento, já que estou apenas nos estágios iniciais de fazer esse sistema funcionar
- Estou usando o plug-in Docker e o plug-in SSH Slaves para realizar esta configuração
Portanto, dentro deste Docker Slave, meu artefato de compilação de componente/serviço de software é criado, pode ser, por exemplo, um .dll ou um .guerra. Acontece que é o caso, porém, que meu artefato de compilação será uma imagem do Docker. Para ser claro, estou construindo uma imagem Docker dentro de um contêiner Docker em execução (o escravo Jenkins).
Minha confusão começa com minha expectativa de que eu deveria ter que executar explicitamente um cmd para enviar meu artefato de construção de imagem Docker de componente de software para um registro Docker. Caso contrário, quando o trabalho de construção do Jenkins estiver concluído, o plug-in do Docker desligará o escravo do contêiner do Docker, descartará (rm) o contêiner escravo e, em seguida, perderei o artefato de construção dentro desse contêiner escravo.
O que realmente acontece, e por que estou agradavelmente surpreso, pelo menos no curto prazo enquanto estou colocando devops em funcionamento, é que a imagem do Docker do artefato de construção aparece no metal do host do Docker, docker image ls
.
Estou surpreso que o plugin Docker iria para este nível de suposição / ajuda... Eu sei que o plugin Docker permite que você configure um registro Docker e que você pode adicionar uma etapa de compilação para construir / publicar em uma nuvem Docker que presumo que a nuvem seja tratada como um registro para imagens e talvez um lugar para também executar essas imagens também:
O que é particularmente interessante é que não estou usando o plug-in Docker para nenhuma etapa de compilação, apenas Uso o plug-in Docker para configurar um contêiner escravo para o item build Jenkins:
A única etapa de compilação que tenho é que executo um Script de Shell, sim, esse script acaba criando uma imagem do Docker, mas o plug-in do Docker não saberia disso:
O plug-in Docker gira os contêineres Docker Slave, configuro o plug-in Docker e digo a ele um Host Docker (meu metal na minha situação) uma nuvem é o que o plug-in Docker chama de Host Docker e também imagens Docker slave para usar nesse Host/nuvem Docker:
Eu só tenho mal-entendidos sobre o quão isolado um espaço de trabalho de construção Jenkins acontece quando dentro de um contêiner escravo Docker?
O plug-in Docker está apenas padronizando o uso da única nuvem Docker (meu Docker host metal) que tenho configurado para todos os comandos docker que executo dentro de um contêiner Jenkins Docker slave? (um contêiner escravo, a propósito, que tem Docker-CE instalado nele)
As Jenkins Master 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"
Eu uso o volume docker-compose e Docker com meu Mestre Jenkins, 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
As Jenkins Master volume/ drive 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"]
As Escravo 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"]
Exemplo software / componente Dockerfile que criará um artefato de construção de imagem Docker dentro de um contêiner Docker escravo 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"]#############################################