Existem muitos artigos no Habré sobre Jenkins, mas poucos descrevem exemplos de como Jenkins e agentes docker funcionam. Todas as ferramentas populares de construção de projetos, como
Hoje existe uma solução para o problema: Jenkins 2 é ótimo para trabalhar com
Por que comecei a resolver esse problema?
Já que estamos em companhia
- uma grande quantidade de tempo de execução que os desenvolvedores esquecem de limpar;
- existem conflitos entre diferentes versões dos mesmos tempos de execução;
- Cada desenvolvedor precisa de um conjunto diferente de componentes.
Existem outros problemas, mas deixe-me falar sobre a solução.
Jenkins no Docker
Como o Docker agora está bem estabelecido no mundo do desenvolvimento, quase tudo pode ser executado usando o Docker. Minha solução é ter o Jenkins no Docker e poder executar outros contêineres do Docker. Essa pergunta começou a ser feita em 2013 no artigo “
Resumindo, você só precisa instalar o próprio Docker em um contêiner funcional e montar o arquivo /var/run/docker.sock
.
Aqui está um exemplo de Dockerfile criado para Jenkins.
FROM jenkins/jenkins:lts
USER root
RUN apt-get update &&
apt-get -y install apt-transport-https
ca-certificates
curl
gnupg2
git
software-properties-common &&
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey &&
add-apt-repository
"deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")
$(lsb_release -cs)
stable" &&
apt-get update &&
apt-get -y install docker-ce &&
usermod -aG docker jenkins
RUN curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose
RUN apt-get clean autoclean && apt-get autoremove —yes && rm -rf /var/lib/{apt,dpkg,cache,log}/
USER jenkins
Assim, obtivemos um contêiner Docker que pode executar comandos Docker na máquina host.
Configuração de compilação
Não muito tempo atrás, Jenkins teve a oportunidade de descrever suas regras usando
Então vamos colocar um Dockerfile especial no próprio repositório, que conterá todas as bibliotecas necessárias para a construção. Dessa forma, o próprio desenvolvedor poderá preparar um ambiente repetível e não precisará solicitar ao OPS a instalação de uma versão específica do Node.JS no host.
FROM node:12.10.0-alpine
RUN npm install yarn -g
Esta imagem de construção é adequada para a maioria dos aplicativos Node.JS. E se, por exemplo, você precisar de uma imagem para um projeto JVM com um scanner Sonar incluído? Você é livre para escolher os componentes necessários para a montagem.
FROM adoptopenjdk/openjdk12:latest
RUN apt update
&& apt install -y
bash unzip wget
RUN mkdir -p /usr/local/sonarscanner
&& cd /usr/local/sonarscanner
&& wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-3.3.0.1492-linux.zip
&& unzip sonar-scanner-cli-3.3.0.1492-linux.zip
&& mv sonar-scanner-3.3.0.1492-linux/* ./
&& rm sonar-scanner-cli-3.3.0.1492-linux.zip
&& rm -rf sonar-scanner-3.3.0.1492-linux
&& ln -s /usr/local/sonarscanner/bin/sonar-scanner /usr/local/bin/sonar-scanner
ENV PATH $PATH:/usr/local/sonarscanner/bin/
ENV SONAR_RUNNER_HOME /usr/local/sonarscanner/bin/
Descrevemos o ambiente de montagem, mas o que Jenkins tem a ver com isso? E os agentes Jenkins podem trabalhar com essas imagens Docker e construí-las internamente.
stage("Build project") {
agent {
docker {
image "project-build:${DOCKER_IMAGE_BRANCH}"
args "-v ${PWD}:/usr/src/app -w /usr/src/app"
reuseNode true
label "build-image"
}
}
steps {
sh "yarn"
sh "yarn build"
}
}
Directiva agent
usa propriedade docker
onde você pode especificar:
- o nome do contêiner de montagem de acordo com sua política de nomenclatura;
- argumentos necessários para executar o contêiner de construção, onde em nosso caso montamos o diretório atual como um diretório dentro do contêiner.
E já nas etapas de build indicamos quais comandos executar dentro do agente de build Docker. Isso pode ser qualquer coisa, então também inicio a implantação de aplicativos usando ansible.
Abaixo, quero mostrar um Jenkinsfile genérico que um aplicativo Node.JS simples pode construir.
def DOCKER_IMAGE_BRANCH = ""
def GIT_COMMIT_HASH = ""
pipeline {
options {
buildDiscarder(
logRotator(
artifactDaysToKeepStr: "",
artifactNumToKeepStr: "",
daysToKeepStr: "",
numToKeepStr: "10"
)
)
disableConcurrentBuilds()
}
agent any
stages {
stage("Prepare build image") {
steps {
sh "docker build -f Dockerfile.build . -t project-build:${DOCKER_IMAGE_BRANCH}"
}
}
stage("Build project") {
agent {
docker {
image "project-build:${DOCKER_IMAGE_BRANCH}"
args "-v ${PWD}:/usr/src/app -w /usr/src/app"
reuseNode true
label "build-image"
}
}
steps {
sh "yarn"
sh "yarn build"
}
}
post {
always {
step([$class: "WsCleanup"])
cleanWs()
}
}
}
O que aconteceu?
Graças a este método, resolvemos os seguintes problemas:
- o tempo de configuração da montagem do ambiente é reduzido para 10 a 15 minutos por projeto;
- um ambiente de construção de aplicativos totalmente repetível, já que você pode construí-lo dessa forma em seu computador local;
- não há problemas com conflitos entre diferentes versões de ferramentas de montagem;
- sempre um espaço de trabalho limpo que não fica obstruído.
A solução em si é simples e óbvia e permite obter algumas vantagens. Sim, o limite de entrada aumentou um pouco em relação aos comandos simples para montagens, mas agora há a garantia de que sempre será construído e o próprio desenvolvedor poderá escolher tudo o que for necessário para seu processo de construção.
Você também pode usar a imagem que coletei
Ao escrever este artigo, surgiu uma discussão sobre o uso de agentes em servidores remotos para não carregar o nó mestre usando um plugin
Fonte: habr.com