تطوير الويب

Bootstrap GitOps مع Argo CD على Kubernetes خطوة بخطوة

4 min de lecture

مقال مرتبط · هذا الدليل جزء من سلسلة Kubernetes منزلي على Proxmox VE. الدليل السابق: Rook-Ceph storage. الدليل التالي: kube-prometheus-stack الرصد.

النشر اليدوي بـ kubectl apply يعمل لاثنين أو ثلاثة أحمال. ما فوق ذلك، حالة العنقود تنحرف خفية عمّا نظنّ أنّنا أعلنّاه، الرجوع للخلف يصير محفوفًا بالمخاطر، ونفقد تاريخ التغييرات. نمط GitOps يحلّ هذه المشاكل الثلاث بوضع مستودع Git مصدرًا وحيدًا للحقيقة: العنقود لا يفعل سوى مزامنة ما هو مُلتزَم. Argo CD هو التطبيق المرجعي لهذا النمط. النسخة 3.4، المُسَلَّمة في مايو 2026، تُضيف Application Controller متعدّد المسارات أسرع وإدارة محسَّنة لـ ApplicationSet. يُثَبِّت هذا الدليل Argo CD 3.4، يُهَيكِل مستودع Git، يُنشئ أوّل Application تنشر حِملًا من Git، ثم يُهَيِّئ ApplicationSet يُكرِّر نفس الحمل على عدّة namespaces.

الخطوة 1 — تحضير مستودع Git مصدر الحقيقة

مستودع Git هو القطعة المركزية. يمكن استضافته على GitHub أو GitLab أو Gitea أو Forgejo أو أيّ خادم SSH.

mkdir homelab-gitops && cd homelab-gitops
git init
mkdir -p apps clusters/homelab/bootstrap clusters/homelab/infra clusters/homelab/apps

echo "# Homelab GitOps" > README.md
git add . && git commit -m "Initial structure"

git remote add origin git@github.com:moncompte/homelab-gitops.git
git branch -M main
git push -u origin main

البنية تُنشئ ثلاثة مستويات: apps/ للمنفستات القابلة للاستعمال، clusters/homelab/ للإعداد الخاصّ بالعنقود، وثلاثة مجلّدات فرعية bootstrap/، infra/، apps/. هذه التنظيمة تصمد للتوسيع، لأنّها تُتيح إضافة عنقود آخر دون إعادة هيكلة المستودع.

الخطوة 2 — تثبيت Argo CD 3.4 عبر Helm

helm repo add argo https://argoproj.github.io/argo-helm
helm repo update

kubectl create namespace argocd

helm install argocd argo/argo-cd \
  --version 9.5.12 \
  --namespace argocd \
  --set server.service.type=ClusterIP \
  --set server.extraArgs[0]=--insecure \
  --set configs.params.server.insecure=true \
  --set redis-ha.enabled=false \
  --set controller.replicas=1 \
  --set server.replicas=2 \
  --set repoServer.replicas=2 \
  --set applicationSet.enabled=true \
  --set notifications.enabled=true

الـ chart 9.5.12 يُسَلِّم Argo CD 3.4.x. الخيار --insecure يتفادى ازدواج TLS حين نكشفه خلف Ingress. احسب 3 دقائق قبل أن تكون الـ pods في Running.

الخطوة 3 — استرداد كلمة سرّ admin والوصول للواجهة

kubectl -n argocd get secret argocd-initial-admin-secret \
  -o jsonpath="{.data.password}" | base64 -d ; echo

kubectl -n argocd port-forward svc/argocd-server 8080:80 &
# افتح http://localhost:8080، login admin، كلمة السرّ أعلاه

الواجهة تعرض شاشة « No Applications ». غيِّر كلمة سرّ admin عبر User Info ← Update Password، أو الأفضل، عطِّل التوثيق الداخلي واستعمل SSO (Keycloak أو Authentik).

الخطوة 4 — ربط Argo CD بمستودع Git

apiVersion: v1
kind: Secret
metadata:
  name: homelab-gitops-repo
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: git
  url: git@github.com:moncompte/homelab-gitops.git
  sshPrivateKey: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    [محتوى المفتاح الخاصّ المنشور بقراءة فقط على GitHub]
    -----END OPENSSH PRIVATE KEY-----
kubectl apply -f homelab-gitops-repo.yaml
# Settings ← Repositories: يجب أن يظهر CONNECTION SUCCESSFUL

الخطوة 5 — إنشاء أوّل Application

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: podinfo-demo
  namespace: argocd
spec:
  project: default
  source:
    repoURL: git@github.com:moncompte/homelab-gitops.git
    targetRevision: main
    path: apps/podinfo-demo
  destination:
    server: https://kubernetes.default.svc
    namespace: demo
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
    - CreateNamespace=true
kubectl apply -f podinfo-app.yaml
kubectl get pods -n demo

pod podinfo الذي يظهر في namespace demo أُنشئ دون kubectl apply يدوي: Argo CD زامنه من Git. إن التزمنا تغييرًا على فرع main، Argo CD يكتشف الانحراف في أقلّ من 3 دقائق ويُطبّق التغيير. الرجوع بـ git revert يُزامَن عكسيًّا.

الخطوة 6 — وضع app-of-apps

نمط app-of-apps يقوم بإنشاء Application جذرية تنشر بنفسها كلّ Applications الأخرى. تكراري ومكتفٍ ذاتيًّا: kubectl apply أوّلي واحد يكفي، ثم كلّ شيء يعيش في Git.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: bootstrap-homelab
  namespace: argocd
spec:
  project: default
  source:
    repoURL: git@github.com:moncompte/homelab-gitops.git
    targetRevision: main
    path: clusters/homelab/bootstrap
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

المجلّد clusters/homelab/bootstrap/ يحوي بعدها منفستات Application تُشير إلى infra/ وapps/. هذه البنية تُتيح إعادة بناء عنقود كامل في أمرين: helm install argocd ثم kubectl apply -f bootstrap-homelab.yaml.

الخطوة 7 — التكرار على عدّة بيئات بـ ApplicationSet

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: monitoring-everywhere
  namespace: argocd
spec:
  generators:
  - list:
      elements:
      - cluster: homelab
        url: https://kubernetes.default.svc
      - cluster: labo
        url: https://10.0.1.10:6443
  template:
    metadata:
      name: '{{cluster}}-kube-prometheus-stack'
    spec:
      project: default
      source:
        repoURL: git@github.com:moncompte/homelab-gitops.git
        targetRevision: main
        path: clusters/{{cluster}}/infra/kube-prometheus-stack
      destination:
        server: '{{url}}'
        namespace: monitoring
      syncPolicy:
        automated:
          prune: true

بـ ApplicationSet واحد، يُنشَأ تطبيقان: homelab-kube-prometheus-stack وlabo-kube-prometheus-stack. إضافة عنقود ثالث تأخذ ثلاثة أسطر بدل نسخ ثلاثين سطرًا YAML.

الخطوة 8 — التحقّق من السلسلة الكاملة بعد commit

cd homelab-gitops
yq -i '.spec.replicas = 3' apps/podinfo-demo/deployment.yaml
git add apps/podinfo-demo/deployment.yaml
git commit -m "Scale podinfo to 3 replicas"
git push origin main

kubectl get pods -n demo -l app=podinfo -w
# يجب الانتقال من 1 pod Running إلى 3 pods Running

رؤية الـ 3 pods تظهر دون تشغيل أمر kubectl scale يُؤكِّد أنّ حلقة GitOps كاملة: Git ← Argo CD ← العنقود. من الآن، كلّ تعديل يمرّ عبر commit، لا عبر أمر مباشر.

أخطاء شائعة وحلولها

العَرَض السبب الحلّ
Application تبقى OutOfSync انحراف، sync تلقائي مُعَطَّل انقر Sync أو فعِّل syncPolicy.automated
Connection Failed على المستودع مفتاح SSH خاطئ أعِد توليد المفتاح وأضفه في Deploy keys
sync يفشل بـ « namespace not found » CreateNamespace=true غير مُفَعَّل أضف syncOptions: [CreateNamespace=true]
Argo CD ينقل الموارد لكن لا يحذفها prune: false افتراضيًّا فعِّل prune: true
واجهة بطيئة على عنقود كبير Application Controller مُشبَع زد controller.replicas وفعِّل sharding

لاستكمال المسار

النشر مُقاد بـ Git. الطبقة المفقودة هي المراقبة. دليل مراقبة Kubernetes مع kube-prometheus-stack يُفَصِّل تثبيت chart 84.5.0. للنظرة العامّة، عُد إلى الدليل الرئيسي.

مصادر وتوثيق رسمي

  • توثيق Argo CD: argo-cd.readthedocs.io
  • ملاحظات إصدار Argo CD 3.4: github.com/argoproj/argo-cd/releases
  • نمط app-of-apps: argo-cd.readthedocs.io/cluster-bootstrapping
  • مواصفات ApplicationSet: argo-cd.readthedocs.io/applicationset
  • Charts Helm Argo: artifacthub.io/argo-cd

الخطوة 9 — تأمين الأسرار في Git بـ Sealed Secrets

نمط GitOps له عيب واضح: لا يمكن التزام Secrets Kubernetes في الواضح. sealed-secrets من Bitnami حلّ بسيط: متحكّم في العنقود يملك مفتاحًا خاصًّا يفكّ تشفير SealedSecret مُلتَزَم في Git.

# تثبيت sealed-secrets
helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets
helm install sealed-secrets sealed-secrets/sealed-secrets \
  --namespace kube-system

# تثبيت kubeseal CLI على المحطّة
KUBESEAL_VERSION=0.36.6
curl -OL https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz
tar xfz kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz
sudo install kubeseal /usr/local/bin/

# شَفِّر secret قائمًا
kubectl create secret generic db-password \
  --from-literal=password=monsecret \
  --dry-run=client -o yaml | \
  kubeseal --format yaml > apps/myapp/db-password.sealed.yaml

الملفّ sealed يمكن التزامه في الواضح في Git، غير قابل للاستعمال خارج العنقود. حين يُزامن Argo CD، يُنشئ SealedSecret، يُحوِّله المتحكّم إلى Secret Kubernetes. مفتاح المتحكّم الخاصّ يجب حفظه احتياطيًّا خارج العنقود.

الخطوة 10 — تفعيل تنبيهات المزامنة

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
  namespace: argocd
data:
  service.webhook.discord: |
    url: https://discord.com/api/webhooks/...
    headers:
    - name: Content-Type
      value: application/json
  template.app-sync-failed: |
    webhook:
      discord:
        method: POST
        body: |
          {"content": "🔴 {{.app.metadata.name}} sync failed: {{.app.status.operationState.message}}"}
  trigger.on-sync-failed: |
    - description: Application sync failed
      send: [app-sync-failed]
      when: app.status.operationState.phase in ['Error', 'Failed']

كلّ إخفاق مزامنة يُشغّل رسالة Discord. للمستخدمين بلا Discord، webhook يعمل مع أيّ خدمة (Mattermost، Matrix، Pushover).

الخطوة 11 — فهم فخاخ selfHeal

selfHeal: true قوي لكن له أثر جانبي: إن طبّق مُشَغِّل patch طارئ يدويًّا (مثلًا kubectl scale)، Argo CD سيُلغيه عند المزامنة التالية لأنّه لا يطابق Git. التفافان: وَسم المورد بـ argocd.argoproj.io/sync-options: IgnoreExtraneous=true أو التزام patch في Git. عمليًّا، نتعلّم ألّا نستعمل kubectl apply أبدًا على موارد مُدارة بـ Argo CD. هذا الانضباط يُحوِّل تشغيل العنقود: تاريخ كلّ تغيير، إعادة تشغيل تكوين قبل 3 أشهر، نشر تصحيح على 10 عناقيد عبر ApplicationSet واحد.

الخطوة 12 — التحقّق من إدارة Argo CD لنفسه

الخطوة النهائية لـ GitOps جعل Argo CD يُدير نفسه. chart Helm يُضاف للمستودع، Application تُشير إليه، وكلّ تحديث لـ Argo CD يمرّ عبر commit. بمجرّد مزامنة هذه Application، تحديث Argo CD يصير تعديل targetRevision: 9.5.12 إلى 8.5.0 والتزام. المتحكّم يُرَقِّي بنفسه نشره معاملاتيًّا. هذا إكمال سلسلة GitOps: كلّ العنقود، حتى الأداة التي تُزامنه، يعيش في Git.

مقالات ذات صلة

Sponsoriser ce contenu

Cet emplacement est à vous

Position premium en fin d'article — c'est l'instant où les lecteurs sont le plus engagés. Réservez cet espace pour votre marque, votre formation ou votre offre.

Recevoir nos tarifs
Publicité