GitOps والتسليم المستمر

ArgoCD لفرق المنصة

4 دقيقة للقراءة

ArgoCD هو أداة GitOps الأكثر شعبية لـ Kubernetes. لفرق المنصة، يوفر الأساس للنشر المؤتمت والقابل للتدقيق عبر مجموعات وبيئات متعددة.

تثبيت ArgoCD

نشر ArgoCD لمجموعتك:

# إنشاء مساحة الاسم
kubectl create namespace argocd

# تثبيت ArgoCD (وضع HA للإنتاج)
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/ha/install.yaml

# أو باستخدام Helm لمزيد من التحكم
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update

helm install argocd argo/argo-cd \
  --namespace argocd \
  --create-namespace \
  --set server.service.type=LoadBalancer \
  --set configs.params."server\.insecure"=true

# انتظار pods
kubectl wait --for=condition=Ready pods --all -n argocd --timeout=300s

# الحصول على كلمة مرور المشرف الأولية
kubectl -n argocd get secret argocd-initial-admin-secret \
  -o jsonpath="{.data.password}" | base64 -d

# الوصول للواجهة
kubectl port-forward svc/argocd-server -n argocd 8080:443
# افتح https://localhost:8080

بنية ArgoCD

┌─────────────────────────────────────────────────────────┐
│                    مكونات ARGOCD                         │
├─────────────────────────────────────────────────────────┤
│                                                          │
│  ┌──────────────────┐     ┌──────────────────┐          │
│  │   خادم API       │────│    واجهة الويب   │          │
│  │  (argocd-server) │     │  (تطبيق React)   │          │
│  └────────┬─────────┘     └──────────────────┘          │
│           │                                              │
│  ┌────────┴─────────┐     ┌──────────────────┐          │
│  │   خادم المستودع  │────│    وحدة تحكم     │          │
│  │ (argocd-repo-    │     │    التطبيق       │          │
│  │  server)         │     │  (المصالحة)      │          │
│  └──────────────────┘     └────────┬─────────┘          │
│           │                        │                     │
│           ▼                        ▼                     │
│  ┌──────────────────┐     ┌──────────────────┐          │
│  │   مستودعات Git   │     │    المجموعات     │          │
│  │  (مصدر الحقيقة)  │     │  (أهداف النشر)   │          │
│  └──────────────────┘     └──────────────────┘          │
│                                                          │
└─────────────────────────────────────────────────────────┘

إنشاء التطبيقات

نشر أول تطبيق مع ArgoCD:

# application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: user-service
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: default

  source:
    repoURL: https://github.com/acme/gitops-repo.git
    targetRevision: main
    path: apps/overlays/production/user-service

  destination:
    server: https://kubernetes.default.svc
    namespace: production

  syncPolicy:
    automated:
      prune: true        # حذف الموارد المُزالة من Git
      selfHeal: true     # إصلاح الانحراف تلقائيًا
      allowEmpty: false  # لا تزامن إذا كان المصدر فارغًا
    syncOptions:
      - CreateNamespace=true
      - PrunePropagationPolicy=foreground
      - PruneLast=true
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m
# تطبيق التطبيق
kubectl apply -f application.yaml

# فحص الحالة
argocd app get user-service

# المزامنة يدويًا إذا لزم الأمر
argocd app sync user-service

# العرض في الواجهة
argocd app list

ApplicationSets للحجم

ApplicationSets تولد تطبيقات متعددة من قالب واحد:

# applicationset-all-apps.yaml
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: all-applications
  namespace: argocd
spec:
  generators:
    # التوليد من هيكل المجلدات
    - git:
        repoURL: https://github.com/acme/gitops-repo.git
        revision: main
        directories:
          - path: apps/overlays/production/*

  template:
    metadata:
      name: '{{path.basename}}'
      namespace: argocd
    spec:
      project: default
      source:
        repoURL: https://github.com/acme/gitops-repo.git
        targetRevision: main
        path: '{{path}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: production
      syncPolicy:
        automated:
          prune: true
          selfHeal: true

ApplicationSets متعددة المجموعات

النشر لمجموعات متعددة:

# applicationset-multi-cluster.yaml
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: multi-cluster-apps
  namespace: argocd
spec:
  generators:
    - matrix:
        generators:
          # المجموعات
          - clusters:
              selector:
                matchLabels:
                  environment: production
          # التطبيقات
          - git:
              repoURL: https://github.com/acme/gitops-repo.git
              revision: main
              directories:
                - path: apps/base/*

  template:
    metadata:
      name: '{{name}}-{{path.basename}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/acme/gitops-repo.git
        targetRevision: main
        path: 'apps/overlays/{{metadata.labels.environment}}/{{path.basename}}'
      destination:
        server: '{{server}}'
        namespace: '{{path.basename}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
        syncOptions:
          - CreateNamespace=true

إضافة المجموعات

تسجيل المجموعات الخارجية مع ArgoCD:

# إضافة مجموعة باستخدام سياق kubeconfig
argocd cluster add production-cluster --name production

# أو عبر Secret تصريحي
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: production-cluster
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: cluster
    environment: production
type: Opaque
stringData:
  name: production
  server: https://production.k8s.acme.com
  config: |
    {
      "bearerToken": "...",
      "tlsClientConfig": {
        "insecure": false,
        "caData": "..."
      }
    }
EOF

# قائمة المجموعات
argocd cluster list

المشاريع للإيجار المتعدد

مشاريع ArgoCD توفر حدود RBAC:

# project-team-orders.yaml
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: team-orders
  namespace: argocd
spec:
  description: "تطبيقات فريق الطلبات"

  # مستودعات المصدر المسموحة
  sourceRepos:
    - https://github.com/acme/orders-*
    - https://github.com/acme/gitops-repo.git

  # الوجهات المسموحة
  destinations:
    - namespace: 'orders-*'
      server: https://kubernetes.default.svc
    - namespace: team-orders
      server: '*'

  # موارد المجموعة المسموحة
  clusterResourceWhitelist:
    - group: ''
      kind: Namespace

  # موارد مساحة الاسم المسموحة
  namespaceResourceWhitelist:
    - group: '*'
      kind: '*'

  # الموارد المرفوضة
  namespaceResourceBlacklist:
    - group: ''
      kind: ResourceQuota
    - group: ''
      kind: LimitRange

  # تعريفات الأدوار
  roles:
    - name: developer
      description: "يمكنه المزامنة والعرض للتطبيقات"
      policies:
        - p, proj:team-orders:developer, applications, get, team-orders/*, allow
        - p, proj:team-orders:developer, applications, sync, team-orders/*, allow
      groups:
        - team-orders-developers

    - name: admin
      description: "وصول كامل لتطبيقات الفريق"
      policies:
        - p, proj:team-orders:admin, applications, *, team-orders/*, allow
      groups:
        - team-orders-admins

الإشعارات

تكوين إشعارات ArgoCD لأحداث النشر:

# argocd-notifications-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
  namespace: argocd
data:
  service.slack: |
    token: $slack-token

  template.app-deployed: |
    message: |
      التطبيق {{.app.metadata.name}} الآن {{.app.status.sync.status}}.
      {{if eq .app.status.sync.status "Synced"}}
      :white_check_mark: النشر ناجح!
      {{end}}
    slack:
      attachments: |
        [{
          "title": "{{.app.metadata.name}}",
          "color": "{{if eq .app.status.sync.status \"Synced\"}}good{{else}}warning{{end}}",
          "fields": [
            {"title": "حالة المزامنة", "value": "{{.app.status.sync.status}}", "short": true},
            {"title": "المستودع", "value": "{{.app.spec.source.repoURL}}", "short": true}
          ]
        }]

  trigger.on-deployed: |
    - when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy'
      send: [app-deployed]
# إضافة التعليق التوضيحي للتطبيق
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: user-service
  annotations:
    notifications.argoproj.io/subscribe.on-deployed.slack: deployments-channel

في الدرس التالي، سنستكشف أنماط التسليم التدريجي مع Argo Rollouts لنشر أكثر أمانًا. :::

اختبار

الوحدة 4: GitOps والتسليم المستمر

خذ الاختبار