Jenkins والتكامل المستمر المؤسسي

معمارية Jenkins والإعداد

18 دقيقة الدرس 1 من 28

معمارية Jenkins والإعداد

Jenkins هو أكثر خوادم الأتمتة انتشاراً في الصناعة. مبني على Java، يُشغّل pipelines CI/CD في شركات من كل الأحجام منذ 2011 — وبالرغم من ظهور بدائل مستضافة، يظل الحل الأول حين تحتاج الفرق إلى تخصيص عميق، أو تشغيل معزول عن الإنترنت، أو تنسيق العمل عبر مئات الأجهزة غير المتجانسة. قبل أن تكتب سطراً واحداً في Jenkinsfile، تحتاج إلى نموذج ذهني دقيق عن بنية Jenkins والسبب وراء هذه البنية.

معمارية Controller / Agent

Jenkins مبني على نموذج طبقتين واضح. Controller (كان يُسمى تاريخياً "master") هو الدماغ: يستضيف واجهة الويب، يحتفظ بالتهيئة وسجل البناء، يقرأ تعريفات الـ pipeline، يجدول الوظائف، ويوزّع العمل على agents (كانت تُسمى تاريخياً "slaves"). الـ agents هم العضلات: عمال بسيطون يُنفّذون أوامر البناء الفعلية ويُعيدون النتائج إلى الـ controller.

يوجد هذا الفصل لثلاثة أسباب بالغة الأهمية في الإنتاج:

  • العزل: عمليات البناء تُنفّذ كوداً غير موثوق، وتستهلك CPU/ذاكرة كبيرة، وقد تُخلّف ملفات على القرص. إبقاء ذلك بعيداً عن الـ controller يحمي محرك الجدولة من عمليات بناء جامحة وهجمات سلسلة التوريد.
  • القابلية للتوسع: يمكن لـ controller واحد إدارة مئات الـ agents. التوسع الأفقي للـ agents مستقل عن سعة الـ controller — إضافة إنتاجية البناء لا تستلزم لمس الـ controller أبداً.
  • التنوع: وظائف مختلفة تحتاج بيئات مختلفة. بناء iOS يحتاج macOS؛ وظيفة .NET على Windows تحتاج Visual Studio؛ وظيفة GPU تحتاج مشغّلات CUDA. كل agent يمكنه حمل نظام تشغيل مختلف أو سلسلة أدوات أو أجهزة مختلفة.
Jenkins Controller / Agent Architecture Controller Web UI | Job Config Build Queue | Scheduler Pipeline Engine | Credentials :8080 (JNLP :50000) Agent: Linux Ubuntu 24.04 Docker / Node / JDK label: linux Agent: macOS macOS 14 (Sonoma) Xcode / Swift label: macos Agent: K8s Pod Ephemeral container Auto-provisioned label: k8s dispatch dispatch dispatch dispatch (controller → agent) results / logs (agent → controller)
طوبولوجيا controller / agent في Jenkins. الـ controller يجدول ويوزّع؛ الـ agents تُنفّذ. كل نوع agent يحمل تسمية (label) تستهدفها مراحل الـ pipeline.

كيف يتصل الـ Agents

يتصل الـ agents بالـ controller بأحد نمطين:

  • SSH (صادر من الـ controller): يتصل الـ controller بـ SSH بالـ agent، ينسخ agent.jar (مكتبة الاتصال عن بُعد)، ويبدأ تشغيله. تحتاج آلة الـ agent إلى خادم SSH وعنوان قابل للوصول. هذا هو النمط التقليدي للـ VMs الدائمة.
  • JNLP / WebSocket (صادر من الـ agent): الـ agent هو من يبدأ الاتصال بالـ controller على البورت 50000 (أو عبر WebSocket على البورت 8080). هذا ضروري حين يكون الـ agents خلف NAT، داخل pods في Kubernetes، أو على VMs سحابية مؤقتة. يستخدم إضافة Kubernetes هذا النمط حصرياً — الـ pods تتصل للخارج، والـ controller لا يتصل للداخل أبداً.
الفكرة الأساسية: فضّل نقل WebSocket في التثبيتات الجديدة. يتعدد البروتوكول على نفس بورت HTTPS (8080 أو 443 خلف reverse proxy)، مما يُلغي الحاجة إلى فتح البورت 50000 عبر جدران الحماية. فعّله من Manage Jenkins ← Security ← Agents ← WebSocket.

تثبيت Jenkins (مستوى الإنتاج)

أسرع طريق إلى controller دائم على Ubuntu هو مستودع APT الرسمي، الذي يمنحك حزماً موقّعة ومسارات ترقية نظيفة. فيما يلي تسلسل التثبيت القياسي لعام 2025.

# --- 1. المتطلبات الأساسية --- sudo apt-get update sudo apt-get install -y fontconfig openjdk-21-jdk # التحقق من Java java -version # openjdk version "21.0.x" 2024-... # --- 2. إضافة مستودع Jenkins APT --- sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \ https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \ https://pkg.jenkins.io/debian-stable binary/" \ | sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null # --- 3. التثبيت --- sudo apt-get update sudo apt-get install -y jenkins # --- 4. التشغيل والتفعيل التلقائي --- sudo systemctl enable --now jenkins # --- 5. التحقق من الحالة --- sudo systemctl status jenkins # استرجاع كلمة مرور المسؤول الأولية sudo cat /var/lib/jenkins/secrets/initialAdminPassword

يستمع Jenkins الآن على http://<server-ip>:8080. افتحه في المتصفح والصق كلمة مرور المسؤول الأولية لبدء معالج الإعداد. اختر Install suggested plugins للحصول على قاعدة تشمل إضافات Git وPipeline وBlue Ocean وCredentials.

تقوية الأمان الأولية

Jenkins حديث التثبيت بالإعدادات الافتراضية ليس آمناً للإنتاج. الخطوات التالية غير قابلة للتفاوض قبل كشف الـ controller للشبكة.

# --- 6. Reverse proxy مع TLS (مثال nginx) --- # تثبيت nginx و certbot sudo apt-get install -y nginx certbot python3-certbot-nginx # /etc/nginx/sites-available/jenkins server { listen 80; server_name jenkins.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name jenkins.example.com; ssl_certificate /etc/letsencrypt/live/jenkins.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/jenkins.example.com/privkey.pem; # ترويسات الأمان add_header Strict-Transport-Security "max-age=63072000" always; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; # مطلوب لنقل WebSocket للـ agent proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } # الحصول على الشهادة وإعادة تحميل nginx sudo certbot --nginx -d jenkins.example.com sudo systemctl reload nginx

نموذج الأمان: ما يجب تهيئته فوراً

بعد معالج الإعداد، انتقل إلى Manage Jenkins → Security وقفّل المجالات التالية:

  1. المصادقة: انتقل من "قاعدة بيانات مستخدمي Jenkins" إلى SSO المؤسسي في أقرب وقت. يدعم Jenkins LDAP وSAML 2.0 (عبر إضافة) وGitHub OAuth. تسجيل الدخول الموحّد يعني لا عبء تدوير كلمات مرور Jenkins منفصلة وإلغاء تفعيل فوري عند مغادرة الموظفين.
  2. التفويض: اضبط الاستراتيجية على Role-Based Access Control (RBAC) باستخدام إضافة Role Strategy. عرّف على الأقل ثلاثة أدوار: admin (وصول كامل)، developer (قراءة + بناء + إلغاء بناءاته الخاصة)، وread-only (عرض السجلات، لا تشغيل). لا تُشغّل أبداً في وضع "أي شخص يمكنه فعل أي شيء" على controller حقيقي.
  3. أمان الـ Agent: فعّل Agent → Controller Security (Manage Jenkins → Security → Agent Protocols). يمنع هذا agent مخترقاً من قراءة ملفات الـ controller الاعتباطية أو التلاعب في قائمة الوظائف. هو معطّل افتراضياً في بعض التثبيتات القديمة.
  4. أمان السكريبت: إضافة Script Security تقيّد ما يمكن لكود Groovy في الـ pipelines تنفيذه. وضع Groovy sandbox إلزامي — عطّله فقط للمكتبات المشتركة الموثوقة وبمراجعة كود فقط.
ممارسة احترافية: فور التثبيت، انتقل إلى Manage Jenkins → Plugins → Available وثبّت إضافات OWASP Dependency-Check وWarnings Next Generation وJob DSL. هذه الثلاثة تمنحك فحص الثغرات وتحليل ستاتيكي مجمّع وتعريف وظائف pipeline-as-code — وهي القدرات الثلاث التي ستحتاجها في أسبوعك الأول من الاستخدام الحقيقي.

مجلد Jenkins الرئيسي

كل ما يملكه Jenkins يعيش تحت JENKINS_HOME — افتراضياً /var/lib/jenkins. فهم تخطيطه ضروري للنسخ الاحتياطي والتعافي من الكوارث:

  • config.xml — التهيئة العامة: إعدادات الأمان، أدوات SCM، تعريفات أدوات JDK/Maven/Node.
  • credentials.xml — مخزن الاعتمادات المشفّر. احرص على هذا الملف؛ فقدانه يعني فقدان القدرة على فك تشفير الأسرار المخزّنة.
  • jobs/ — مجلد فرعي لكل وظيفة يحتوي config.xml (تعريف الوظيفة) وbuilds/ (سجل البناء، السجلات، الحزم).
  • nodes/ — ملفات تهيئة عقد الـ agent.
  • plugins/ — ملفات JARs للإضافات المثبّتة وبياناتها.
  • secrets/ — مفتاح التشفير الرئيسي وملفات الأسرار. الوضع 0700؛ لا تنسخه احتياطياً في مكان عام.
  • workspace/ — مساحات عمل البناء. لا تنسخها احتياطياً؛ هي مؤقتة وغالباً كبيرة.
مصيدة إنتاجية: الكارثة الأكثر شيوعاً هي امتلاء القرص بسبب JENKINS_HOME/jobs/<job>/builds/ ينمو بلا حدود. كل Declarative Pipeline يجب أن يتضمن خيار buildDiscarder: options { buildDiscarder(logRotator(numToKeepStr: '30', artifactNumToKeepStr: '5')) }. اضبطه عالمياً في Manage Jenkins → System ومحلياً في كل Jenkinsfile. الـ controllers التي ينفد قرصها تتعطل بشدة ويمكنها إتلاف قاعدة بيانات الوظائف.

ربط أول Agent

مع تشغيل الـ controller وتأمينه، أضف agent Linux دائماً عبر SSH لنقل أعباء البناء فوراً.

# على آلة الـ AGENT — إنشاء مستخدم jenkins مخصص sudo useradd -m -s /bin/bash jenkins-agent sudo mkdir -p /home/jenkins-agent/.ssh sudo chmod 700 /home/jenkins-agent/.ssh # على آلة الـ CONTROLLER — إنشاء زوج مفاتيح SSH ssh-keygen -t ed25519 -C "jenkins-controller" -f ~/.ssh/jenkins_agent_ed25519 -N "" # نسخ المفتاح العام إلى الـ agent ssh-copy-id -i ~/.ssh/jenkins_agent_ed25519.pub jenkins-agent@<AGENT_IP> # في واجهة Jenkins: # Manage Jenkins > Nodes > New Node # الاسم: linux-agent-01 # النوع: Permanent Agent # عدد المنفّذين: (عدد أنوية CPU - 1) # المجلد الجذر البعيد: /home/jenkins-agent # التسميات: linux docker # طريقة التشغيل: Launch agents via SSH # المضيف: <AGENT_IP> # الاعتمادات: (أضف المفتاح الخاص من ~/.ssh/jenkins_agent_ed25519) # التحقق من مفتاح المضيف: Known hosts file # (أضف الـ agent إلى ~/.ssh/known_hosts أولاً) # على آلة الـ AGENT — تثبيت Docker لتمكين الـ pipelines من تشغيل الحاويات sudo apt-get install -y docker.io sudo usermod -aG docker jenkins-agent

ما يجب ألا يفعله الـ Controller أبداً

يجب أن يكون لدى controller المُقوّى صفر منفّذين (executors) — انتقل إلى Manage Jenkins → Nodes → Built-In Node → Configure واضبط عدد المنفّذين على 0. هذه واحدة من أهم خطوات تقوية الإنتاج وتُتجاهل باستمرار من الفرق الجديدة على Jenkins.

تشغيل بناءات على الـ controller يكشف JENKINS_HOME بأكمله — بما فيه الاعتمادات وأسرار الوظائف ومفتاح التشفير — لكود البناء الاعتباطي. إذا أخذ pipeline مستودعاً يحتوي Jenkinsfile خبيثاً أو سكريبت بناء ضار، يمكنه قراءة secrets/master.key مباشرة. نقل كل التنفيذ إلى الـ agents يُحصر نطاق تأثير agent مخترق في مساحة عمل agent واحد فقط.

المعمارية على نطاق واسع: كيف يبدو Jenkins على مستوى Google

المؤسسات الكبيرة (Netflix وLinkedIn وWalmart Labs) تُشغّل Jenkins في طوبولوجيا controller لكل فريق أو controller لكل نطاق بدلاً من controller مشترك واحد. للـ controller الواحد سقف عملي حول 200-300 بناء متزامن قبل أن تصبح ذاكرة JVM وI/O نظام الملفات عوائق. إضافة Kubernetes هي الحل القياسي للتجهيز المرن للـ agents: كل مرحلة بناء تُشغّل pod جديداً، تُنفّذ، ثم تُدمَّر — مما يُلغي انجراف الـ agent ويُتيح عزل سلسلة أدوات خاصة بكل وظيفة دون الحفاظ على أسطول من الـ VMs الدائمة.

الدرس التالي يستكشف الفرق بين وظائف Freestyle والـ Pipelines — نوعا الوظائف اللذان يوفرهما Jenkins ولماذا حلّت Declarative Pipelines محل Freestyle في كل حالة استخدام CI/CD جادة.