cloud-devops

helm upgrade --install: عمليات نشر

١ يوليو ٢٠٢٦

helm upgrade --install: Idempotent Deploys (2026)

helm upgrade --install هو أمر واحد يقوم بتثبيت الإصدار (release) إذا لم يكن موجوداً بالفعل، ويقوم بترقيته إذا كان موجوداً. علم (flag) الـ --install (أو -i) يجعل عملية النشر آمنة لإعادة التشغيل، ولهذا السبب هو الأمر القياسي المتكرر (idempotent) لخطوط أنابيب CI/CD.12

ملخص

بدلاً من التفريع بين helm install (لأول عملية نشر) و helm upgrade (لكل عملية نشر بعدها)، يمكنك تشغيل أمر واحد helm upgrade --install NAME CHART في كل مكان. يتحقق Helm مما إذا كان هناك إصدار بهذا الاسم موجوداً: إذا لم يكن موجوداً، يقوم بالتثبيت؛ وإذا كان موجوداً، يقوم بالترقية.1 إنه أمر متكرر (idempotent) في الحالة العادية، مع استثناء واحد مهم — وهو أن فشل التثبيت الأول يترك إصداراً عالقاً، وتفشل المحاولة التالية مع ظهور خطأ has no deployed releases.34 تمت كتابة هذا الدليل لـ Helm 4 (الإصدار العام 12 نوفمبر 2025؛ أحدث تصحيح 4.2.2 وقت كتابة هذا التقرير)، والذي أعاد تسمية العديد من الأعلام التي لا تزال الدروس القديمة تخطئ فيها — --atomic أصبح الآن --rollback-on-failure، و --wait و --dry-run يأخذان قيماً، وأصبح --force هو --force-replace.516

ما ستتعلمه

  • ماذا يفعل helm upgrade --install فعلياً ولماذا هو متكرر (idempotent)
  • متى تستخدم helm install مقابل helm upgrade
  • السبب الدقيق وراء فشل helm upgrade --install أحياناً مع خطأ has no deployed releases، وكيفية إصلاحه
  • كيف يعمل --create-namespace مع --install
  • ما الذي تغير لهذه الأعلام في Helm 4
  • الفرق بين --reuse-values و --reset-values و --reset-then-reuse-values وفخ "اختفاء قيمي"
  • كيفية معاينة عملية النشر والتراجع التلقائي عنها باستخدام --dry-run و --wait و --rollback-on-failure
  • نمط CI/CD جاهز للنسخ واللصق لـ GitHub Actions

ماذا يفعل helm upgrade --install؟

يقوم بتشغيل تثبيت (install) عندما يكون الإصدار غائباً وترقية (upgrade) عندما يكون موجوداً — في أمر واحد. يأتي هذا السلوك بالكامل من علم -i, --install، والذي يعرفه المرجع الرسمي بأنه "إذا لم يكن هناك إصدار بهذا الاسم موجوداً بالفعل، فقم بتشغيل التثبيت".1

أولاً، تأكد من أنك تستخدم Helm 4:

helm version
# version.BuildInfo{Version:"v4.2.2", ...}

ثم قم بالنشر بنفس الطريقة سواء كانت المرة الأولى أو الخمسين:

helm upgrade --install myapp ./charts/myapp \
  --namespace prod --create-namespace

في التشغيل الأول، يقوم Helm بإنشاء الإصدار myapp في المراجعة (revision) رقم 1. في عمليات التشغيل اللاحقة، يقوم بحساب الفرق (diff) ويرفع رقم المراجعة.7 كل عملية تثبيت أو ترقية أو تراجع تزيد المراجعة بمقدار 1، ويحتفظ Helm بآخر 10 مراجعات لكل إصدار افتراضياً (--history-max، القيمة 0 تعني غير محدود).1 يمكنك فحص السجل في أي وقت:

helm history myapp -n prod
helm status myapp -n prod

helm install مقابل helm upgrade: متى تستخدم كل منهما؟

استخدم helm install لإصدار جديد تماماً و helm upgrade لتغيير إصدار موجود — ولكن في الأتمتة نادراً ما ترغب في الاختيار. يفشل helm install إذا كان اسم الإصدار مأخوذاً بالفعل، ويفشل helm upgrade العادي إذا لم يكن الإصدار موجوداً بعد.7 يدمج helm upgrade --install كليهما في أمر واحد لا يهتم بالحالة التي هو فيها، وهو بالضبط ما تريده في سكربت قد يعمل ضد عنقود (cluster) جديد أو موجود.2

لا يزال هناك مكان للأوامر المستقلة. الجأ إلى helm install عندما تريد صراحةً أن يفشل التشغيل بصوت عالٍ إذا كان الإصدار موجوداً بالفعل (على سبيل المثال، للحماية من الكتابة فوق شيء ما)، وإلى helm upgrade بدون --install عندما تريد أن تفشل عملية النشر بدلاً من إنشاء إصدار بصمت كان من المفترض أن يكون موجوداً بالفعل.

هل helm upgrade --install متكرر (idempotent)؟

نعم في الغالب — تشغيله بشكل متكرر بنفس المدخلات يؤدي إلى نفس الحالة — ولكن هناك حافة حادة واحدة. علم الـ -i يفعل التثبيت فقط عندما لا يوجد إصدار على الإطلاق. إذا فشل أول أمر helm upgrade --install لك في منتصف الطريق، فسيظل Helm يسجل الإصدار، ولكن بحالة failed أو pending-install بدلاً من deployed.3

في التشغيل التالي، يرى --install أن إصداراً باسم myapp موجود بالفعل، لذا يسلك مسار الترقية. تحتاج الترقية إلى مراجعة في حالة deployed لاستخدامها كأساس للمقارنة، فلا تجد شيئاً، وتتوقف:

Error: UPGRADE FAILED: "myapp" has no deployed releases

لذا فإن الأمر متكرر (idempotent) بمجرد حصولك على أول عملية نشر سليمة، ولكن التثبيت الأول المعطل يمكن أن يعيقه. يغطي القسم التالي كيفية الإصلاح.

لماذا يفشل helm upgrade --install مع خطأ "has no deployed releases"؟

لأن helm upgrade يتطلب مراجعة سابقة حالتها deployed للمقارنة معها، وبعد فشل التثبيت الأول لا توجد مراجعة كهذه.4 عندما تكون كل مراجعة مخزنة هي failed أو pending-install أو pending-upgrade، لا يملك Helm أساساً للمقارنة ويرفض الاستمرار. تمت إضافة هذا القيد في Helm 2.7.1 ولا يزال موجوداً في Helm 3 و Helm 4.4

لديك ثلاث طرق للخروج، من الأنظف إلى الأكثر ارتجالاً:

# 1. الطريقة الأنظف: إزالة الإصدار العالق، ثم ترك --install يقوم بتثبيت جديد
helm uninstall myapp -n prod
helm upgrade --install myapp ./charts/myapp -n prod

# 2. منع حدوث ذلك في المرة القادمة: التراجع تلقائيًا عند الفشل (انظر أدناه)
helm upgrade --install myapp ./charts/myapp -n prod --rollback-on-failure

# 3. الملاذ الأخير: تعديل ملصق الـ status الخاص بـ Secret الإصدار ليعود إلى deployed
kubectl -n prod get secret -l owner=helm,name=myapp
# ثم قم بتحرير ملصق الحالة (status label) لأحدث secret باسم sh.helm.release.v1.myapp.v<N>

الخيار الثاني هو الوقاية الحقيقية: إذا فشل التثبيت الأول وتم ضبط --rollback-on-failure، يقوم Helm بإلغاء تثبيت الإصدار الفاشل، مما لا يترك شيئًا عالقًا ليعيق التشغيل التالي.1 هذا الخطأ شائع بشكل خاص مع كائنات Flux HelmRelease، حيث تؤدي عملية مصالحة (reconcile) أولى سيئة واحدة إلى جعل الإصدار محشورًا حتى تقوم بإلغاء تثبيته.4 إذا كنت تستخدم GitOps، فإن دليلنا حول أنماط سير عمل GitOps من الالتزام (commit) إلى العنقود (cluster) يغطي مكان ملائمة ذلك في حلقة المصالحة.

كيف يمكنني إنشاء مساحة الاسم (namespace) باستخدام helm upgrade --install؟

أضف --create-namespace، والتي تعرفها الوثائق بأنها "إذا تم ضبط --install، فسيتم إنشاء مساحة اسم الإصدار إذا لم تكن موجودة."1 لا تقوم هذه الخاصية بأي شيء إلا بجانب --install، لذا فهي تقترن بشكل طبيعي مع هذا الأمر:

helm upgrade --install myapp ./charts/myapp \
  --namespace prod --create-namespace

بدونها، سيفشل النشر في مساحة اسم غير موجودة بعد. هذا تعثر شائع في التشغيل الأول، لأن أمر helm install العادي في Helm 2 كان ينشئ مساحات الأسماء ضمنيًا، بينما يقوم Helm 3 و 4 بإرجاع خطأ لمطابقة سلوك أدوات Kubernetes الأخرى.8

ما الذي تغير لهذه الأعلام (flags) في Helm 4؟

قام Helm 4 بإعادة تسمية أو إعادة هيكلة العديد من الأعلام التي تقترن دائمًا بـ helm upgrade --install، ولا تزال الأدلة القديمة تعرض تسميات Helm 3.51 إليك التخطيط (mapping) المهم:

Helm 3Helm 4ملاحظات
--atomic--rollback-on-failureلا يزال العلم القديم --atomic يعمل في upgrade ولكنه مهجور لصالح --rollback-on-failure. تم إصلاح تراجع (regression) أدى إلى تعطل العلم المهجور --atomic في helm install (خطأ "unknown flag") في الإصدار 4.1.3.6
--wait (boolean)--wait WaitStrategyالقيم: watcher، hookOnly، legacy. استخدام --wait بمفرده = watcher؛ وحذف العلم يؤدي افتراضيًا إلى hookOnly.1
--dry-run (boolean)--dry-run stringالقيم: none (افتراضي)، client، server.1
--force--force-replaceبالإضافة إلى علم جديد --force-conflicts لتعارضات التطبيق من جانب الخادم (server-side apply).1

اثنان من هذه الأعلام يسهل الوقوع في خطأ بسيط معهما. أولاً، --wait لم يعد يعني "انتظر حتى يصبح الـ Deployment الخاص بي جاهزًا" بشكل افتراضي — إذا حذفته، يستخدم Helm 4 استراتيجية hookOnly و لا ينتظر وحدات الـ pods الخاصة بحمل العمل.1 مرر --wait صراحةً للحصول على سلوك watcher القائم على kstatus والذي ينتظر حتى تصبح الموارد جاهزة.5 ثانيًا، أضاف Helm 4 ميزة التطبيق من جانب الخادم (server-side apply): يجعل helm install قيمة --server-side افتراضيًا true، بينما يجعلها helm upgrade افتراضيًا auto (يرث طريقة الإصدار السابق).91

--reuse-values مقابل --reset-values مقابل --reset-then-reuse-values

تتحكم هذه الأعلام الثلاثة في القيم التي يبدأ منها الترقية، والسلوك الافتراضي يفاجئ الناس. إليك ما يفعله كل منها، وفقًا للمرجع:1

  • --reset-values: إعادة التعيين إلى القيم المضمنة في الـ chart، مع تجاهل ما استخدمه الإصدار الأخير.
  • --reuse-values: إعادة استخدام قيم الإصدار الأخير ودمج أي تجاوزات (overrides) من --set / -f من هذا الأمر.
  • --reset-then-reuse-values: إعادة التعيين إلى قيم الـ chart، ثم إعادة تطبيق قيم الإصدار الأخير، ثم دمج تجاوزات هذا الأمر. تمت إضافته في Helm 3.14.0.

الفخ هو السلوك الافتراضي عندما لا تمرر أيًا منها. إذا تضمن أمر الترقية الخاص بك أي علم للقيم (--set، --set-string، --set-file، --values/-f)، يستخدم Helm ضمنيًا استراتيجية reset — لذا فإن أي قيم مخصصة قمت بضبطها في عملية نشر سابقة ولم تكررها هذه المرة سيتم مسحها.10 إذا لم تمرر أي أعلام للقيم على الإطلاق، فإن Helm يعيد استخدام القيم السابقة ضمنيًا.10

# النشر 1: تحديد عدد النسخ المتماثلة (replica count)
helm upgrade --install myapp ./charts/myapp -n prod --set replicaCount=4

# النشر 2: تغيير وسم الصورة فقط، بدون تكرار replicaCount
helm upgrade --install myapp ./charts/myapp -n prod --set image.tag=1.5.0
# هنا يعود replicaCount بصمت إلى القيمة الافتراضية للـ chart (استراتيجية reset)

يتجنب --reuse-values ذلك التراجع، ولكن له عيبه الخاص: فهو يتجاهل أيضًا أي مفاتيح جديدة تمت إضافتها إلى ملف values.yaml الخاص بالـ chart في الإصدار الذي تقوم بالترقية إليه. عادةً ما يكون --reset-then-reuse-values هو ما يريده الناس فعليًا — فهو يحافظ على تجاوزاتك السابقة مع استيعاب القيم الافتراضية الجديدة للـ chart.10 ومع ذلك، فإن الحل الأكثر قوة هو التوقف عن الاعتماد على --set والاحتفاظ بكل تجاوز في ملف قيم خاضع للتحكم في الإصدارات تمرره باستخدام -f في كل عملية نشر.

كيف يمكنني معاينة الترقية قبل حدوثها؟

استخدم --dry-run=client لعرض الإصدار دون لمس العنقود، واختياريًا مع --debug لرؤية البيان (manifest) الكامل. في Helm 4، يأخذ --dry-run وضعًا: client "يحاكي العملية من جانب العميل فقط ويتجنب الاتصال بالعنقود،" بينما يقوم server بتشغيل المحاكاة مقابل خادم Kubernetes.1

# العرض من جانب العميل، لا يلزم الاتصال بالعنقود
helm upgrade --install myapp ./charts/myapp -n prod \
  --dry-run=client --debug

# إخفاء الـ Secrets المعروضة في المخرجات
helm upgrade --install myapp ./charts/myapp -n prod \
  --dry-run=client --hide-secret

للحصول على عرض قالب نقي بدون أي منطق إصدار على الإطلاق، يعمل helm template ./charts/myapp أيضًا بالكامل دون اتصال بالإنترنت.7

كيف يمكنني جعل عملية النشر الفاشلة تتراجع تلقائياً؟

اجمع بين --wait مع --rollback-on-failure و --timeout. عند تعيين --rollback-on-failure، "سيقوم Helm بالتراجع عن الترقية إلى الإصدار الناجح السابق عند الفشل،" ويقوم تلقائياً بتعيين --wait إلى استراتيجية watcher بحيث يراقب Helm مواردك فعلياً حتى تصبح جاهزة قبل إعلان النجاح.1

helm upgrade --install myapp ./charts/myapp \
  --namespace prod --create-namespace \
  --wait --rollback-on-failure --timeout 5m

إذا لم تصل الـ pods إلى حالة الجاهزية خلال --timeout (الافتراضي هو 5m0s)، فسيقوم Helm بتمييز الإصدار كفاشل ويتراجع إلى آخر مراجعة جيدة.1 بالنسبة لعمليات النشر التي تقوم أيضاً بتشغيل Jobs، أضف --wait-for-jobs حتى ينتظر Helm اكتمال تلك الـ Jobs أيضاً.1 يتناسب هذا بشكل جيد مع ممارسات الجاهزية في دليلنا حول عمليات نشر Kubernetes بدون وقت توقف.

كيف أستخدم helm upgrade --install في CI/CD؟

قم بتشغيل نفس الأمر تماماً في خط الأنابيب (pipeline) الخاص بك الذي قد تقوم بتشغيله يدوياً — فخاصية التكرار (idempotency) هي ما يجعله آمناً للاستخدام في CI.2 ولأن الأمر يتصرف بشكل متطابق سواء كان الإصدار موجوداً أم لا، فلن تحتاج أبداً إلى منطق شرطي في سير عملك.

name: deploy
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: Install Helm 4
        run: curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-4 | bash
      - name: Deploy (idempotent)
        run: |
          helm upgrade --install myapp ./charts/myapp \
            --namespace prod --create-namespace \
            --wait --rollback-on-failure --timeout 5m

هناك مشكلة شائعة في CI تستحق المعرفة: إجراء azure/setup-helm الشهير يقوم بتثبيت Helm على المشغل، لكن ملف README الخاص به ينص على أن "الإصدار v2+ من هذا الإجراء يدعم فقط Helm3،" ويعود إلى افتراضي ثابت هو v3.18.4 إذا فشل اكتشاف الإصدار.11 إذا كنت تحتاج تحديداً إلى Helm 4 على المشغل، فقم بتثبيته باستخدام نص get-helm-4 الرسمي كما هو موضح أعلاه بدلاً من الاعتماد على الافتراضي الخاص بالإجراء.12 لهيكلة خط الأنابيب المحيط، راجع مقارنتنا بين سير العمل القابل لإعادة الاستخدام مقابل الإجراءات المركبة في GitHub Actions.

الخلاصة

يعد helm upgrade --install هو الخيار الافتراضي الصحيح لكل عملية نشر تقريباً: أمر واحد تكراري يقوم بالتثبيت أو الترقية دون أن تضطر للتفرع بناءً على الحالة الحالية للإصدار.2 في Helm 4، اجمعه مع --create-namespace للتشغيل الأول، و --wait --rollback-on-failure --timeout لعمليات النشر الآلية الآمنة، وملف -f values.yaml خاضع للتحكم في الإصدارات لتجنب مفاجآت دمج القيم. الأمرين اللذين يسببان مشاكل للناس — حالة has no deployed releases بعد فشل التثبيت الأول، وأعلام Helm 4 التي تم تغيير اسمها — كلاهما يمكن تجنبهما بمجرد معرفة وجودهما.

بعد ذلك، قم بتقوية عملية النشر نفسها باستخدام استراتيجيات نشر Kubernetes بدون وقت توقف، أو اربطها بخط أنابيب باستخدام سير عمل GitHub Actions القابل لإعادة الاستخدام، أو أدرها بشكل تصريحي باستخدام أنماط GitOps من الالتزام إلى المجموعة.

Footnotes

  1. Helm، مرجع أمر "helm upgrade" (الإصدار v4.2.2). https://helm.sh/docs/helm/helm_upgrade/ 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

  2. Coder Society، "13 أفضل الممارسات لاستخدام Helm." https://codersociety.com/blog/articles/helm-best-practices 2 3 4

  3. helm/helm issue #3353، "helm upgrade --install لا يقوم بالتثبيت/التحديث إذا فشل أول تثبيت على الإطلاق." https://GitHub.com/helm/helm/issues/3353 2 3

  4. phoenixNAP، "إصلاح خطأ 'helm has no deployed releases'." https://phoenixnap.com/kb/helm-has-no-deployed-releases 2 3 4 5 6

  5. Helm، "إطلاق Helm 4" (17 نوفمبر 2025). https://helm.sh/blog/helm-4-released/ 2 3

  6. helm/helm issue #31900، "helm install مع --atomic لم يعد يعمل في Helm 4." https://GitHub.com/helm/helm/issues/31900 2 3

  7. Helm، "استخدام Helm." https://helm.sh/docs/intro/using_helm/ 2 3

  8. Helm، "التغييرات منذ Helm 2" (إنشاء namespace). https://helm.sh/docs/v3/faq/changes_since_helm2/

  9. Helm، مرجع أمر "helm install" (الإصدار v4). https://helm.sh/docs/helm/helm_install/

  • H. Cao، "فهم أعلام ترقية Helm — reset-values و reuse-values." https://medium.com/@kcatstack/understand-helm-upgrade-flags-reset-values-reuse-values-6e58ac8f127e 2 3 4

  • Azure/setup-helm، ملف README الخاص بـ GitHub Action. https://GitHub.com/Azure/setup-helm

  • Helm، "تثبيت Helm." https://helm.sh/docs/intro/install/

  • الأسئلة الشائعة

    نعم. يقوم علم -i, --install بتشغيل عملية تثبيت عندما لا يوجد إصدار بهذا الاسم، وعملية ترقية عندما يوجد واحد. 1