
مقالات زیادی در مورد جنکینز در Habr وجود دارد، اما تعداد کمی از آنها مثالی از نحوه کار Jenkins و Docker agent ها را شرح میدهند. همه ابزارهای ساخت پروژه محبوب مانند , , , و دیگران میتوانند همه چیز را در کانتینرها بسازند. اما جنکینز چطور؟
امروز یک راه حل برای این مشکل وجود دارد: جنکینز ۲ در کار با ... عالی است. در این مقاله، میخواهم تجربهام را با شما به اشتراک بگذارم و به شما نشان دهم که چگونه میتوانید خودتان این کار را انجام دهید.
چرا شروع به حل این مشکل کردم؟
از آنجایی که ما در شرکت هستیم از آنجایی که ما از فناوریهای متنوعی استفاده میکنیم، باید نسخههای مختلفی از Node.JS، Gradle، Ruby، JDK و سایر موارد را در دستگاه ساخت نگهداری کنیم. اما تداخل نسخهها اغلب اجتنابناپذیر است. اگرچه ممکن است درست بگویید که مدیران نسخه مختلفی مانند nvm و rvm وجود دارند، اما آنها همیشه آسان نیستند و این راهحلها مشکلات خاص خود را دارند:
- حجم زیادی از زمانهای اجرا که توسعهدهندگان فراموش میکنند آنها را پاکسازی کنند؛
- بین نسخههای مختلف از زمانهای اجرای یکسان، تداخل وجود دارد؛
- هر توسعهدهنده به مجموعهی متفاوتی از اجزا نیاز دارد.
مشکلات دیگه ای هم هست، اما بذارید در مورد راه حل بهتون بگم.
جنکینز در داکر
از آنجایی که داکر اکنون در دنیای توسعه به خوبی جا افتاده است، تقریباً همه چیز را میتوان با استفاده از داکر اجرا کرد. راه حل من این است که جنکینز را در داکر داشته باشیم و بتوانیم سایر کانتینرهای داکر را اجرا کنیم. این سوال اولین بار در سال ۲۰۱۳ در مقاله "".
به طور خلاصه، شما فقط باید خود Docker را در کانتینر کاری نصب کنید و فایل را mount کنید. /var/run/docker.sock.
در اینجا مثالی از Dockerfile که برای 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بنابراین، ما یک کانتینر داکر داریم که میتواند دستورات داکر را روی دستگاه میزبان اجرا کند.
تنظیمات ساخت
چندی پیش، جنکینز توانایی توصیف قوانین خود را با استفاده از سینتکس، که تغییر اسکریپت ساخت و ذخیره آن در مخزن را آسان میکند.
بنابراین بیایید یک Dockerfile ویژه در خود مخزن قرار دهیم که شامل تمام کتابخانههای مورد نیاز برای ساخت است. به این ترتیب، توسعهدهنده میتواند بدون نیاز به درخواست از OPS برای نصب نسخه خاصی از Node.JS روی میزبان، یک محیط تکرارپذیر آماده کند.
FROM node:12.10.0-alpine
RUN npm install yarn -gاین تصویر ساخت برای اکثر برنامههای Node.JS مناسب است. اما اگر مثلاً برای پروژهای با اسکنر Sonar یکپارچه به یک تصویر JVM نیاز داشته باشید، چه؟ شما میتوانید اجزای مورد نیاز برای ساخت را انتخاب کنید.
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/
ما محیط ساخت را شرح دادیم، اما جنکینز چه ارتباطی با آن دارد؟ عاملهای جنکینز میتوانند با این تصاویر داکر کار کنند و درون آنها ساخت انجام دهند.
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"
}
}دستورالعمل agent از ملک استفاده میکند docker، که در آن میتوانید مشخص کنید:
- نام ظرف مونتاژ طبق سیاست نامگذاری شما؛
- آرگومانهای مورد نیاز برای اجرای کانتینر ساخت، که در این مورد ما دایرکتوری فعلی را به عنوان یک دایرکتوری درون کانتینر مانت میکنیم.
و در مراحل ساخت، ما مشخص میکنیم که کدام دستورات باید درون عامل ساخت Docker اجرا شوند. این میتواند هر چیزی باشد، بنابراین من همچنین استقرار برنامهها را با استفاده از Ansible اجرا میکنم.
در زیر میخواهم یک Jenkinsfile عمومی را نشان دهم که میتواند یک برنامه ساده Node.JS بسازد.
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()
}
}
}خب، چه اتفاقی افتاد؟
با استفاده از این روش، مسائل زیر را حل کردیم:
- زمان پیکربندی محیط ساخت به 10 تا 15 دقیقه در هر پروژه کاهش مییابد؛
- یک محیط ساخت برنامه کاملاً تکرارپذیر، زیرا میتوان آن را روی یک کامپیوتر محلی نیز ساخت؛
- هیچ مشکلی در مورد تداخل بین نسخههای مختلف ابزارهای ساخت وجود ندارد؛
- همیشه یک فضای کاری تمیز که بهم ریخته نباشد.
خودِ این راهکار ساده و بدیهی است و فقط مزایایی ارائه میدهد. بله، مانع ورود کمی بیشتر از دستورات ساخت ساده است، اما اکنون تضمینی وجود دارد که ساخت همیشه کار خواهد کرد و توسعهدهنده میتواند هر آنچه را که برای فرآیند ساخت خود نیاز دارد انتخاب کند.
همچنین میتوانید از تصویری که من آماده کردهام استفاده کنید. همه منابع باز و در دسترس هستند .
هنگام نوشتن این مقاله، بحثی در مورد استفاده از عاملها روی سرورهای راه دور برای جلوگیری از بارگذاری گره اصلی با افزونه وجود داشت. اما در آینده در این مورد به شما خواهم گفت.
منبع: www.habr.com
