Эта инструкция описывает шаги, необходимые для смены редакции Deckhouse Platform в работающем кластере. Выполняйте их последовательно по разделам.

В зависимости от способа работы с хранилищем образов процесс переключения отличается. Выбираете подходящий для вашего кластера способ и следуйте инструкциям.

При переключении на DP BE/SE/SE+/EE/CSE необходим действующий лицензионный ключ. При переключении на DP CE он не требуется.

Инструкция не подходит для переключения с DP CSE на другие редакции, но подходит для переключения на DP CSE с DP EE.

Инструкция подразумевает использование публичного хранилища образов контейнеров (registry-cse.deckhouse.ru для DP CSE, и registry.deckhouse.ru в остальных случаях). При использовании другого адреса хранилища образов измените команды или воспользуйтесь инструкцией по переключению Deckhouse на использование стороннего хранилища образов контейнеров.

Выполняйте все команды на master-узле существующего кластера под пользователем root.

Подготовка к переключению

Перед переключением между редакциями выполните следующие действия:

  1. Убедитесь, что очереди DP пусты.
  2. Определите текущую редакцию и версию DP.
  3. Убедитесь в возможности переключения с текущей редакции на желаемую.

Проверка очереди

Убедитесь, что очереди DP пусты, и в них нет выполняющихся задач, которые могут помешать переключению:

d8 system queue list

Пример вывода (очереди пусты)...

Summary:
- 'main' queue: empty.
- 88 other queues (0 active, 88 empty): 0 tasks.
- no tasks to handle.

Определение текущей редакции и версии

Чтобы быть уверенным в корректности дальнейших действий, определите текущую редакцию DP, используемую в кластере. Это поможет избежать ошибок при переключении и убедиться в поддержке необходимых модулей и функциональных возможностей в новой редакции.

Узнать используемые в кластере редакцию и версию DP можно на главной странице веб-интерфейса DP, либо с помощью CLI-команд:

  • получение текущей редакции DP:

    d8 k -n d8-system exec -it svc/deckhouse-leader -c deckhouse -- deckhouse-controller global values -o yaml | yq '.deckhouseEdition'
    
  • получение текущей версии DP:

    d8 k -n d8-system get deploy deckhouse -ojson | jq -r '.spec.template.spec.containers[] | select(.name == "deckhouse") | .image' | awk -F: '{print $NF}'
    

Определение возможности переключения на желаемую редакцию

Редакции DP различаются набором модулей, поддерживаемых версий Kubernetes и функциональными возможностями. Важно понимать, какие изменения в функциональности произойдут при переключении, какие возможности станут недоступными. Это поможет вам подготовиться к процессу переключения.

Сравнение редакций DP по составу модулей представлено странице «Сравнение редакций».

Что необходимо учесть перед переключением:

  • На DP CE
  • На DP BE
  • На DP SE
  • На DP SE+
  • На DP EE
  • На DP CSE
  1. Определите список внутренних модулей, которые используются в кластере и не поддерживаются в DP новой редакции. Для этого выполните следующие шаги:

    1. Получите список внутренних модулей, которые не поддерживаются в DP ce:

      (set -e
      trap 'echo "Ошибка выполнения"' ERR
      
      echo
      echo "Запуск пода deckhouse новой редакции с командой 'sleep -- infinity'"
      
      DECKHOUSE_VERSION=$(d8 k -n d8-system get deploy deckhouse -ojson | jq -r '.spec.template.spec.containers[] | select(.name == "deckhouse") | .image' | awk -F: '{print $NF}')
      d8 k run ce-image --image=registry.deckhouse.ru/deckhouse/ce/install:$DECKHOUSE_VERSION \
      --command sleep -- infinity
      d8 k wait --for=condition=ready pod/ce-image --timeout=300s
      
      echo
      echo "Получение информации по внутренним модулям из текущей и новой редакции"
      echo "Сравнение внутренних модулей текущей и новой редакции"
      NEW_MODULES=$(d8 k exec ce-image -- ls -l deckhouse/modules/ |   grep -oE "\d.*-\w*" | awk {'print $9'} | cut -c5-)
      USED_MODULES=$(d8 k get modules -o custom-columns=NAME:.metadata.name,SOURCE:.properties.source,STATE:.properties.state,ENABLED:.status.phase | grep Embedded | grep -E 'Enabled|Ready' | awk {'print $1'})
      MODULES_TO_DISABLE=$(echo "$USED_MODULES" | tr ' ' '\n' | grep -Fxv -f <(echo "$NEW_MODULES" | tr ' ' '\n') 2>&1) || { status=$?; [ $status -eq 1 ] && MODULES_TO_DISABLE="" || exit $status; }
      
      echo
      echo "Модули, которые не поддерживаются в желаемой редакции (код редакции - ce, версия - $DECKHOUSE_VERSION):"
      echo MODULES_TO_DISABLE=\"$MODULES_TO_DISABLE\"
      )
      
      echo
      echo "Удаление пода deckhouse новой редакции"
      d8 k delete pod/ce-image secret/ce-image-pull-secret --wait=true --ignore-not-found=true
      
    2. Отключите модули из полученного списка, если это допустимо (функциональность модулей не используется, или вы готовы от нее отказаться). Иначе, прервите процесс переключения.

      Отключить модули из полученного списка можно в веб-интерфейсе DP в разделе «Система» → «Управление системой» → «Deckhouse» → «Модули», либо выполнив следующую команду:

      echo $MODULES_TO_DISABLE | tr ' ' '\n' | awk {'print "d8 platform module disable",$1'} | bash
      
  2. Определите список внешних модулей, запущенных из moduleSource/deckhouse, которые не поддерживаются в DP новой редакции. Для этого выполните следующие шаги:

    1. Получите список внешних модулей запущенных из moduleSource/deckhouse с результатом проверки их наличия в DP новой редакции:

      (set -e
      trap 'echo "Ошибка выполнения"' ERR
      d8-crane() {
         if command -v d8 &>/dev/null && d8 cr &>/dev/null 2>&1; then
            d8 cr "$@"
         else
            crane "$@"
         fi
      }
      
      
      check_external_modules() {
         local repo="$1"
      
         local modules=$(d8 k get modulerelease -o json | jq -r '.items[] | select(.metadata.ownerReferences[] | select(.kind=="ModuleSource" and .name=="deckhouse")) | "\(.spec.moduleName) \(.spec.version)"')
         [[ -z "$modules" ]] && return 0
         local registry_modules=$(d8-crane ls "$repo" 2>/dev/null)
      
         echo "Модуль | Наличие модуля"
         echo "-------|---------------"
      
         echo "$modules" | while read module version; do
            grep -qx "$module" <<< "$registry_modules" && list="✅" || list="❌"
            echo "$module | $list"
         done
      }
      
      d8-crane --help > /dev/null 2>&1 || { echo "ERROR: crane not found"; exit 1; }
      check_external_modules "registry.deckhouse.ru/deckhouse/ce/modules"
      )
      
    2. Отключите модули которые не были найдены в новой редакции, если это допустимо. Иначе, прервите процесс переключения.

  3. Убедитесь в выполнении всех задач в очередях DP, прежде чем продолжить процесс переключения:

    d8 system queue list
    

    Пример вывода (очереди пусты)...

    Summary:
    - 'main' queue: empty.
    - 88 other queues (0 active, 88 empty): 0 tasks.
    - no tasks to handle.
    
  1. Определите список внутренних модулей, которые используются в кластере и не поддерживаются в DP новой редакции. Для этого выполните следующие шаги:

    1. Подготовьте переменную окружения, указав лицензионный ключ для редакции, на которую вы планируете переключиться:

      LICENSE_TOKEN=<ЛИЦЕНЗИОННЫЙ_КЛЮЧ>
      
    2. Получите список внутренних модулей, которые не поддерживаются в DP be:

      (set -e
      trap 'echo "Ошибка выполнения"' ERR
      
      echo
      echo "Запуск пода deckhouse новой редакции с командой 'sleep -- infinity'"
      
      DECKHOUSE_VERSION=$(d8 k -n d8-system get deploy deckhouse -ojson | jq -r '.spec.template.spec.containers[] | select(.name == "deckhouse") | .image' | awk -F: '{print $NF}')
      d8 k create secret docker-registry be-image-pull-secret --docker-server=registry.deckhouse.ru --docker-username=license-token --docker-password=${LICENSE_TOKEN}
      d8 k run be-image --image=registry.deckhouse.ru/deckhouse/be/install:$DECKHOUSE_VERSION \
      --overrides="{\"spec\": {\"imagePullSecrets\":[{\"name\": \"be-image-pull-secret\"}]}}" \
      --command sleep -- infinity
      d8 k wait --for=condition=ready pod/be-image --timeout=300s
      
      echo
      echo "Получение информации по внутренним модулям из текущей и новой редакции"
      echo "Сравнение внутренних модулей текущей и новой редакции"
      NEW_MODULES=$(d8 k exec be-image -- ls -l deckhouse/modules/ |   grep -oE "\d.*-\w*" | awk {'print $9'} | cut -c5-)
      USED_MODULES=$(d8 k get modules -o custom-columns=NAME:.metadata.name,SOURCE:.properties.source,STATE:.properties.state,ENABLED:.status.phase | grep Embedded | grep -E 'Enabled|Ready' | awk {'print $1'})
      MODULES_TO_DISABLE=$(echo "$USED_MODULES" | tr ' ' '\n' | grep -Fxv -f <(echo "$NEW_MODULES" | tr ' ' '\n') 2>&1) || { status=$?; [ $status -eq 1 ] && MODULES_TO_DISABLE="" || exit $status; }
      
      echo
      echo "Модули, которые не поддерживаются в желаемой редакции (код редакции - be, версия - $DECKHOUSE_VERSION):"
      echo MODULES_TO_DISABLE=\"$MODULES_TO_DISABLE\"
      )
      
      echo
      echo "Удаление пода deckhouse новой редакции"
      d8 k delete pod/be-image secret/be-image-pull-secret --wait=true --ignore-not-found=true
      
    3. Отключите модули из полученного списка, если это допустимо (функциональность модулей не используется, или вы готовы от нее отказаться). Иначе, прервите процесс переключения.

      Отключить модули из полученного списка можно в веб-интерфейсе DP в разделе «Система» → «Управление системой» → «Deckhouse» → «Модули», либо выполнив следующую команду:

      echo $MODULES_TO_DISABLE | tr ' ' '\n' | awk {'print "d8 platform module disable",$1'} | bash
      
  2. Определите список внешних модулей, запущенных из moduleSource/deckhouse, которые не поддерживаются в DP новой редакции. Для этого выполните следующие шаги:

    1. Подготовьте переменную окружения, указав лицензионный ключ для редакции, на которую вы планируете переключиться:

      LICENSE_TOKEN=<ЛИЦЕНЗИОННЫЙ_КЛЮЧ>
      
    2. Получите список внешних модулей запущенных из moduleSource/deckhouse с результатом проверки их наличия в DP новой редакции:

      (set -e
      trap 'echo "Ошибка выполнения"' ERR
      d8-crane() {
         if command -v d8 &>/dev/null && d8 cr &>/dev/null 2>&1; then
            d8 cr "$@"
         else
            crane "$@"
         fi
      }
      
      d8-crane-login() {
         if command -v d8 &>/dev/null && d8 cr &>/dev/null 2>&1; then
            d8 cr login "$1" -u "license-token" -p "$2"
         else
            crane auth login "$1" -u "license-token" -p "$2"
         fi
      }
      
      check_external_modules() {
         local repo="$1"
      
         local modules=$(d8 k get modulerelease -o json | jq -r '.items[] | select(.metadata.ownerReferences[] | select(.kind=="ModuleSource" and .name=="deckhouse")) | "\(.spec.moduleName) \(.spec.version)"')
         [[ -z "$modules" ]] && return 0
         local registry_modules=$(d8-crane ls "$repo" 2>/dev/null)
      
         echo "Модуль | Наличие модуля"
         echo "-------|---------------"
      
         echo "$modules" | while read module version; do
            grep -qx "$module" <<< "$registry_modules" && list="✅" || list="❌"
            echo "$module | $list"
         done
      }
      
      d8-crane --help > /dev/null 2>&1 || { echo "ERROR: crane not found"; exit 1; }
      d8-crane-login "registry.deckhouse.ru" "$LICENSE_TOKEN"
      check_external_modules "registry.deckhouse.ru/deckhouse/be/modules"
      )
      
    3. Отключите модули которые не были найдены в новой редакции, если это допустимо. Иначе, прервите процесс переключения.

  3. Убедитесь в выполнении всех задач в очередях DP, прежде чем продолжить процесс переключения:

    d8 system queue list
    

    Пример вывода (очереди пусты)...

    Summary:
    - 'main' queue: empty.
    - 88 other queues (0 active, 88 empty): 0 tasks.
    - no tasks to handle.
    
  1. Определите список внутренних модулей, которые используются в кластере и не поддерживаются в DP новой редакции. Для этого выполните следующие шаги:

    1. Подготовьте переменную окружения, указав лицензионный ключ для редакции, на которую вы планируете переключиться:

      LICENSE_TOKEN=<ЛИЦЕНЗИОННЫЙ_КЛЮЧ>
      
    2. Получите список внутренних модулей, которые не поддерживаются в DP se:

      (set -e
      trap 'echo "Ошибка выполнения"' ERR
      
      echo
      echo "Запуск пода deckhouse новой редакции с командой 'sleep -- infinity'"
      
      DECKHOUSE_VERSION=$(d8 k -n d8-system get deploy deckhouse -ojson | jq -r '.spec.template.spec.containers[] | select(.name == "deckhouse") | .image' | awk -F: '{print $NF}')
      d8 k create secret docker-registry se-image-pull-secret --docker-server=registry.deckhouse.ru --docker-username=license-token --docker-password=${LICENSE_TOKEN}
      d8 k run se-image --image=registry.deckhouse.ru/deckhouse/se/install:$DECKHOUSE_VERSION \
      --overrides="{\"spec\": {\"imagePullSecrets\":[{\"name\": \"se-image-pull-secret\"}]}}" \
      --command sleep -- infinity
      d8 k wait --for=condition=ready pod/se-image --timeout=300s
      
      echo
      echo "Получение информации по внутренним модулям из текущей и новой редакции"
      echo "Сравнение внутренних модулей текущей и новой редакции"
      NEW_MODULES=$(d8 k exec se-image -- ls -l deckhouse/modules/ |   grep -oE "\d.*-\w*" | awk {'print $9'} | cut -c5-)
      USED_MODULES=$(d8 k get modules -o custom-columns=NAME:.metadata.name,SOURCE:.properties.source,STATE:.properties.state,ENABLED:.status.phase | grep Embedded | grep -E 'Enabled|Ready' | awk {'print $1'})
      MODULES_TO_DISABLE=$(echo "$USED_MODULES" | tr ' ' '\n' | grep -Fxv -f <(echo "$NEW_MODULES" | tr ' ' '\n') 2>&1) || { status=$?; [ $status -eq 1 ] && MODULES_TO_DISABLE="" || exit $status; }
      
      echo
      echo "Модули, которые не поддерживаются в желаемой редакции (код редакции - se, версия - $DECKHOUSE_VERSION):"
      echo MODULES_TO_DISABLE=\"$MODULES_TO_DISABLE\"
      )
      
      echo
      echo "Удаление пода deckhouse новой редакции"
      d8 k delete pod/se-image secret/se-image-pull-secret --wait=true --ignore-not-found=true
      
    3. Отключите модули из полученного списка, если это допустимо (функциональность модулей не используется, или вы готовы от нее отказаться). Иначе, прервите процесс переключения.

      Отключить модули из полученного списка можно в веб-интерфейсе DP в разделе «Система» → «Управление системой» → «Deckhouse» → «Модули», либо выполнив следующую команду:

      echo $MODULES_TO_DISABLE | tr ' ' '\n' | awk {'print "d8 platform module disable",$1'} | bash
      
  2. Определите список внешних модулей, запущенных из moduleSource/deckhouse, которые не поддерживаются в DP новой редакции. Для этого выполните следующие шаги:

    1. Подготовьте переменную окружения, указав лицензионный ключ для редакции, на которую вы планируете переключиться:

      LICENSE_TOKEN=<ЛИЦЕНЗИОННЫЙ_КЛЮЧ>
      
    2. Получите список внешних модулей запущенных из moduleSource/deckhouse с результатом проверки их наличия в DP новой редакции:

      (set -e
      trap 'echo "Ошибка выполнения"' ERR
      d8-crane() {
         if command -v d8 &>/dev/null && d8 cr &>/dev/null 2>&1; then
            d8 cr "$@"
         else
            crane "$@"
         fi
      }
      
      d8-crane-login() {
         if command -v d8 &>/dev/null && d8 cr &>/dev/null 2>&1; then
            d8 cr login "$1" -u "license-token" -p "$2"
         else
            crane auth login "$1" -u "license-token" -p "$2"
         fi
      }
      
      check_external_modules() {
         local repo="$1"
      
         local modules=$(d8 k get modulerelease -o json | jq -r '.items[] | select(.metadata.ownerReferences[] | select(.kind=="ModuleSource" and .name=="deckhouse")) | "\(.spec.moduleName) \(.spec.version)"')
         [[ -z "$modules" ]] && return 0
         local registry_modules=$(d8-crane ls "$repo" 2>/dev/null)
      
         echo "Модуль | Наличие модуля"
         echo "-------|---------------"
      
         echo "$modules" | while read module version; do
            grep -qx "$module" <<< "$registry_modules" && list="✅" || list="❌"
            echo "$module | $list"
         done
      }
      
      d8-crane --help > /dev/null 2>&1 || { echo "ERROR: crane not found"; exit 1; }
      d8-crane-login "registry.deckhouse.ru" "$LICENSE_TOKEN"
      check_external_modules "registry.deckhouse.ru/deckhouse/se/modules"
      )
      
    3. Отключите модули которые не были найдены в новой редакции, если это допустимо. Иначе, прервите процесс переключения.

  3. Убедитесь в выполнении всех задач в очередях DP, прежде чем продолжить процесс переключения:

    d8 system queue list
    

    Пример вывода (очереди пусты)...

    Summary:
    - 'main' queue: empty.
    - 88 other queues (0 active, 88 empty): 0 tasks.
    - no tasks to handle.
    
  1. Определите список внутренних модулей, которые используются в кластере и не поддерживаются в DP новой редакции. Для этого выполните следующие шаги:

    1. Подготовьте переменную окружения, указав лицензионный ключ для редакции, на которую вы планируете переключиться:

      LICENSE_TOKEN=<ЛИЦЕНЗИОННЫЙ_КЛЮЧ>
      
    2. Получите список внутренних модулей, которые не поддерживаются в DP se-plus:

      (set -e
      trap 'echo "Ошибка выполнения"' ERR
      
      echo
      echo "Запуск пода deckhouse новой редакции с командой 'sleep -- infinity'"
      
      DECKHOUSE_VERSION=$(d8 k -n d8-system get deploy deckhouse -ojson | jq -r '.spec.template.spec.containers[] | select(.name == "deckhouse") | .image' | awk -F: '{print $NF}')
      d8 k create secret docker-registry se-plus-image-pull-secret --docker-server=registry.deckhouse.ru --docker-username=license-token --docker-password=${LICENSE_TOKEN}
      d8 k run se-plus-image --image=registry.deckhouse.ru/deckhouse/se-plus/install:$DECKHOUSE_VERSION \
      --overrides="{\"spec\": {\"imagePullSecrets\":[{\"name\": \"se-plus-image-pull-secret\"}]}}" \
      --command sleep -- infinity
      d8 k wait --for=condition=ready pod/se-plus-image --timeout=300s
      
      echo
      echo "Получение информации по внутренним модулям из текущей и новой редакции"
      echo "Сравнение внутренних модулей текущей и новой редакции"
      NEW_MODULES=$(d8 k exec se-plus-image -- ls -l deckhouse/modules/ |   grep -oE "\d.*-\w*" | awk {'print $9'} | cut -c5-)
      USED_MODULES=$(d8 k get modules -o custom-columns=NAME:.metadata.name,SOURCE:.properties.source,STATE:.properties.state,ENABLED:.status.phase | grep Embedded | grep -E 'Enabled|Ready' | awk {'print $1'})
      MODULES_TO_DISABLE=$(echo "$USED_MODULES" | tr ' ' '\n' | grep -Fxv -f <(echo "$NEW_MODULES" | tr ' ' '\n') 2>&1) || { status=$?; [ $status -eq 1 ] && MODULES_TO_DISABLE="" || exit $status; }
      
      echo
      echo "Модули, которые не поддерживаются в желаемой редакции (код редакции - se-plus, версия - $DECKHOUSE_VERSION):"
      echo MODULES_TO_DISABLE=\"$MODULES_TO_DISABLE\"
      )
      
      echo
      echo "Удаление пода deckhouse новой редакции"
      d8 k delete pod/se-plus-image secret/se-plus-image-pull-secret --wait=true --ignore-not-found=true
      
    3. Отключите модули из полученного списка, если это допустимо (функциональность модулей не используется, или вы готовы от нее отказаться). Иначе, прервите процесс переключения.

      Отключить модули из полученного списка можно в веб-интерфейсе DP в разделе «Система» → «Управление системой» → «Deckhouse» → «Модули», либо выполнив следующую команду:

      echo $MODULES_TO_DISABLE | tr ' ' '\n' | awk {'print "d8 platform module disable",$1'} | bash
      
  2. Определите список внешних модулей, запущенных из moduleSource/deckhouse, которые не поддерживаются в DP новой редакции. Для этого выполните следующие шаги:

    1. Подготовьте переменную окружения, указав лицензионный ключ для редакции, на которую вы планируете переключиться:

      LICENSE_TOKEN=<ЛИЦЕНЗИОННЫЙ_КЛЮЧ>
      
    2. Получите список внешних модулей запущенных из moduleSource/deckhouse с результатом проверки их наличия в DP новой редакции:

      (set -e
      trap 'echo "Ошибка выполнения"' ERR
      d8-crane() {
         if command -v d8 &>/dev/null && d8 cr &>/dev/null 2>&1; then
            d8 cr "$@"
         else
            crane "$@"
         fi
      }
      
      d8-crane-login() {
         if command -v d8 &>/dev/null && d8 cr &>/dev/null 2>&1; then
            d8 cr login "$1" -u "license-token" -p "$2"
         else
            crane auth login "$1" -u "license-token" -p "$2"
         fi
      }
      
      check_external_modules() {
         local repo="$1"
      
         local modules=$(d8 k get modulerelease -o json | jq -r '.items[] | select(.metadata.ownerReferences[] | select(.kind=="ModuleSource" and .name=="deckhouse")) | "\(.spec.moduleName) \(.spec.version)"')
         [[ -z "$modules" ]] && return 0
         local registry_modules=$(d8-crane ls "$repo" 2>/dev/null)
      
         echo "Модуль | Наличие модуля"
         echo "-------|---------------"
      
         echo "$modules" | while read module version; do
            grep -qx "$module" <<< "$registry_modules" && list="✅" || list="❌"
            echo "$module | $list"
         done
      }
      
      d8-crane --help > /dev/null 2>&1 || { echo "ERROR: crane not found"; exit 1; }
      d8-crane-login "registry.deckhouse.ru" "$LICENSE_TOKEN"
      check_external_modules "registry.deckhouse.ru/deckhouse/se-plus/modules"
      )
      
    3. Отключите модули которые не были найдены в новой редакции, если это допустимо. Иначе, прервите процесс переключения.

  3. Убедитесь в выполнении всех задач в очередях DP, прежде чем продолжить процесс переключения:

    d8 system queue list
    

    Пример вывода (очереди пусты)...

    Summary:
    - 'main' queue: empty.
    - 88 other queues (0 active, 88 empty): 0 tasks.
    - no tasks to handle.
    
  1. Определите список внутренних модулей, которые используются в кластере и не поддерживаются в DP новой редакции. Для этого выполните следующие шаги:

    1. Подготовьте переменную окружения, указав лицензионный ключ для редакции, на которую вы планируете переключиться:

      LICENSE_TOKEN=<ЛИЦЕНЗИОННЫЙ_КЛЮЧ>
      
    2. Получите список внутренних модулей, которые не поддерживаются в DP ee:

      (set -e
      trap 'echo "Ошибка выполнения"' ERR
      
      echo
      echo "Запуск пода deckhouse новой редакции с командой 'sleep -- infinity'"
      
      DECKHOUSE_VERSION=$(d8 k -n d8-system get deploy deckhouse -ojson | jq -r '.spec.template.spec.containers[] | select(.name == "deckhouse") | .image' | awk -F: '{print $NF}')
      d8 k create secret docker-registry ee-image-pull-secret --docker-server=registry.deckhouse.ru --docker-username=license-token --docker-password=${LICENSE_TOKEN}
      d8 k run ee-image --image=registry.deckhouse.ru/deckhouse/ee/install:$DECKHOUSE_VERSION \
      --overrides="{\"spec\": {\"imagePullSecrets\":[{\"name\": \"ee-image-pull-secret\"}]}}" \
      --command sleep -- infinity
      d8 k wait --for=condition=ready pod/ee-image --timeout=300s
      
      echo
      echo "Получение информации по внутренним модулям из текущей и новой редакции"
      echo "Сравнение внутренних модулей текущей и новой редакции"
      NEW_MODULES=$(d8 k exec ee-image -- ls -l deckhouse/modules/ |   grep -oE "\d.*-\w*" | awk {'print $9'} | cut -c5-)
      USED_MODULES=$(d8 k get modules -o custom-columns=NAME:.metadata.name,SOURCE:.properties.source,STATE:.properties.state,ENABLED:.status.phase | grep Embedded | grep -E 'Enabled|Ready' | awk {'print $1'})
      MODULES_TO_DISABLE=$(echo "$USED_MODULES" | tr ' ' '\n' | grep -Fxv -f <(echo "$NEW_MODULES" | tr ' ' '\n') 2>&1) || { status=$?; [ $status -eq 1 ] && MODULES_TO_DISABLE="" || exit $status; }
      
      echo
      echo "Модули, которые не поддерживаются в желаемой редакции (код редакции - ee, версия - $DECKHOUSE_VERSION):"
      echo MODULES_TO_DISABLE=\"$MODULES_TO_DISABLE\"
      )
      
      echo
      echo "Удаление пода deckhouse новой редакции"
      d8 k delete pod/ee-image secret/ee-image-pull-secret --wait=true --ignore-not-found=true
      
    3. Отключите модули из полученного списка, если это допустимо (функциональность модулей не используется, или вы готовы от нее отказаться). Иначе, прервите процесс переключения.

      Отключить модули из полученного списка можно в веб-интерфейсе DP в разделе «Система» → «Управление системой» → «Deckhouse» → «Модули», либо выполнив следующую команду:

      echo $MODULES_TO_DISABLE | tr ' ' '\n' | awk {'print "d8 platform module disable",$1'} | bash
      
  2. Определите список внешних модулей, запущенных из moduleSource/deckhouse, которые не поддерживаются в DP новой редакции. Для этого выполните следующие шаги:

    1. Подготовьте переменную окружения, указав лицензионный ключ для редакции, на которую вы планируете переключиться:

      LICENSE_TOKEN=<ЛИЦЕНЗИОННЫЙ_КЛЮЧ>
      
    2. Получите список внешних модулей запущенных из moduleSource/deckhouse с результатом проверки их наличия в DP новой редакции:

      (set -e
      trap 'echo "Ошибка выполнения"' ERR
      d8-crane() {
         if command -v d8 &>/dev/null && d8 cr &>/dev/null 2>&1; then
            d8 cr "$@"
         else
            crane "$@"
         fi
      }
      
      d8-crane-login() {
         if command -v d8 &>/dev/null && d8 cr &>/dev/null 2>&1; then
            d8 cr login "$1" -u "license-token" -p "$2"
         else
            crane auth login "$1" -u "license-token" -p "$2"
         fi
      }
      
      check_external_modules() {
         local repo="$1"
      
         local modules=$(d8 k get modulerelease -o json | jq -r '.items[] | select(.metadata.ownerReferences[] | select(.kind=="ModuleSource" and .name=="deckhouse")) | "\(.spec.moduleName) \(.spec.version)"')
         [[ -z "$modules" ]] && return 0
         local registry_modules=$(d8-crane ls "$repo" 2>/dev/null)
      
         echo "Модуль | Наличие модуля"
         echo "-------|---------------"
      
         echo "$modules" | while read module version; do
            grep -qx "$module" <<< "$registry_modules" && list="✅" || list="❌"
            echo "$module | $list"
         done
      }
      
      d8-crane --help > /dev/null 2>&1 || { echo "ERROR: crane not found"; exit 1; }
      d8-crane-login "registry.deckhouse.ru" "$LICENSE_TOKEN"
      check_external_modules "registry.deckhouse.ru/deckhouse/ee/modules"
      )
      
    3. Отключите модули которые не были найдены в новой редакции, если это допустимо. Иначе, прервите процесс переключения.

  3. Убедитесь в выполнении всех задач в очередях DP, прежде чем продолжить процесс переключения:

    d8 system queue list
    

    Пример вывода (очереди пусты)...

    Summary:
    - 'main' queue: empty.
    - 88 other queues (0 active, 88 empty): 0 tasks.
    - no tasks to handle.
    
  1. При переключении на DP CSE возможна временная недоступность компонентов кластера.
  2. Каждый узел кластера будет поочерёдно перезагружен с очисткой кеша образов containerd. Чтобы управлять моментом перезагрузки, заранее переведите все NodeGroup, включая master, в ручной режим подтверждения простоя:

    1. Сохраните текущий режим подтверждения простоя всех NodeGroup, чтобы вернуть исходные значения после переключения:

      d8 k get ng -o custom-columns=NAME:.metadata.name,MODE:.spec.disruptions.approvalMode
      

      Значение <none> означает, что режим не задан явно и используется значение по умолчанию (Automatic).

    2. Переведите все NodeGroup в ручной режим:

      d8 k patch ng <ИМЯ_NODEGROUP> --type=merge -p '{"spec":{"disruptions":{"approvalMode":"Manual"}}}'
      

    После завершения переключения верните исходные значения: группам, где режим был задан явно, установите прежнее значение; группам со значением <none> удалите параметр:

    d8 k patch ng <ИМЯ_NODEGROUP> --type=json -p='[{"op":"remove","path":"/spec/disruptions/approvalMode"}]'
    
  3. Переключение на DP CSE возможно только с DP EE (Enterprise Edition). Переключение поддерживается только между одинаковыми минорными версиями DP. Например, с DP EE 1.67.x на DP CSE 1.67.x.```

    При необходимости, выполните обновление DP EE до соответствующей минорной версии и последней патч-версии.

    Актуальные патч-версии DP CSE: v1.58.2, v1.64.1, v1.67.4, v1.73.0. Также, информацию о доступных версиях DP CSE можно получить в разделе Обновления DP Certified Security Edition на официальном сайте.

  4. Убедитесь, что версия Kubernetes, используемая в кластере, поддерживается в желаемой версии DP CSE:
    • DP CSE 1.58 и 1.64 поддерживает Kubernetes версии 1.27;
    • DP CSE 1.67 поддерживает Kubernetes версий 1.27 и 1.29.

    При необходимости, обновите версию Kubernetes в кластере до поддерживаемой:

    • Выполните команду:

      d8 platform edit cluster-configuration
      
    • Измените параметр kubernetesVersion на необходимое значение, например, "1.29" (в кавычках) для Kubernetes 1.29.
    • Сохраните изменения. Узлы кластера начнут последовательно обновляться.
    • Дождитесь окончания обновления. Отслеживать ход обновления можно с помощью команды d8 k get no. Обновление считается завершенным, когда в выводе команды у каждого узла кластера в колонке VERSION появится обновленная версия.
  5. Начиная с DP CSE 1.77, поддерживается только containerd v2 — containerd v1 в редакции отсутствует. Убедитесь, что в кластере не используется containerd v1: параметр defaultCRI в ClusterConfiguration не равен Containerd и ни в одной группе узлов не задан spec.cri.type: Containerd. Иначе переключение будет заблокировано.

    При необходимости мигрируйте узлы на containerd v2 до переключения редакции.

  6. Определите список внутренних модулей, которые используются в кластере и не поддерживаются в DP новой редакции. Для этого выполните следующие шаги:

    1. Подготовьте переменную окружения, указав лицензионный ключ для редакции, на которую вы планируете переключиться:

      LICENSE_TOKEN=<ЛИЦЕНЗИОННЫЙ_КЛЮЧ>
      
    2. Получите список внутренних модулей, которые не поддерживаются в DP cse:

      (set -e
      trap 'echo "Ошибка выполнения"' ERR
      
      echo
      echo "Запуск пода deckhouse новой редакции с командой 'sleep -- infinity'"
      
      DECKHOUSE_VERSION=$(d8 k -n d8-system get deploy deckhouse -ojson | jq -r '.spec.template.spec.containers[] | select(.name == "deckhouse") | .image' | awk -F: '{print $NF}')
      d8 k create secret docker-registry cse-image-pull-secret --docker-server=registry-cse.deckhouse.ru --docker-username=license-token --docker-password=${LICENSE_TOKEN}
      d8 k run cse-image --image=registry-cse.deckhouse.ru/deckhouse/cse/install:$DECKHOUSE_VERSION \
      --overrides="{\"spec\": {\"imagePullSecrets\":[{\"name\": \"cse-image-pull-secret\"}]}}" \
      --command sleep -- infinity
      d8 k wait --for=condition=ready pod/cse-image --timeout=300s
      
      echo
      echo "Получение информации по внутренним модулям из текущей и новой редакции"
      echo "Сравнение внутренних модулей текущей и новой редакции"
      NEW_MODULES=$(d8 k exec cse-image -- ls -l deckhouse/modules/ |   grep -oE "\d.*-\w*" | awk {'print $9'} | cut -c5-)
      USED_MODULES=$(d8 k get modules -o custom-columns=NAME:.metadata.name,SOURCE:.properties.source,STATE:.properties.state,ENABLED:.status.phase | grep Embedded | grep -E 'Enabled|Ready' | awk {'print $1'})
      MODULES_TO_DISABLE=$(echo "$USED_MODULES" | tr ' ' '\n' | grep -Fxv -f <(echo "$NEW_MODULES" | tr ' ' '\n') 2>&1) || { status=$?; [ $status -eq 1 ] && MODULES_TO_DISABLE="" || exit $status; }
      
      echo
      echo "Модули, которые не поддерживаются в желаемой редакции (код редакции - cse, версия - $DECKHOUSE_VERSION):"
      echo MODULES_TO_DISABLE=\"$MODULES_TO_DISABLE\"
      )
      
      echo
      echo "Удаление пода deckhouse новой редакции"
      d8 k delete pod/cse-image secret/cse-image-pull-secret --wait=true --ignore-not-found=true
      
    3. Отключите модули из полученного списка, если это допустимо (функциональность модулей не используется, или вы готовы от нее отказаться). Иначе, прервите процесс переключения.

      Отключить модули из полученного списка можно в веб-интерфейсе DP в разделе «Система» → «Управление системой» → «Deckhouse» → «Модули», либо выполнив следующую команду:

      echo $MODULES_TO_DISABLE | tr ' ' '\n' | awk {'print "d8 platform module disable",$1'} | bash
      
  7. Определите список внешних модулей, запущенных из moduleSource/deckhouse, которые не поддерживаются в DP новой редакции. Для этого выполните следующие шаги:

    1. Подготовьте переменную окружения, указав лицензионный ключ для редакции, на которую вы планируете переключиться:

      LICENSE_TOKEN=<ЛИЦЕНЗИОННЫЙ_КЛЮЧ>
      
    2. Получите список внешних модулей запущенных из moduleSource/deckhouse с результатом проверки их наличия в DP новой редакции:

      (set -e
      trap 'echo "Ошибка выполнения"' ERR
      d8-crane() {
         if command -v d8 &>/dev/null && d8 cr &>/dev/null 2>&1; then
            d8 cr "$@"
         else
            crane "$@"
         fi
      }
      
      d8-crane-login() {
         if command -v d8 &>/dev/null && d8 cr &>/dev/null 2>&1; then
            d8 cr login "$1" -u "license-token" -p "$2"
         else
            crane auth login "$1" -u "license-token" -p "$2"
         fi
      }
      
      check_external_modules() {
         local repo="$1"
      
         local modules=$(d8 k get modulerelease -o json | jq -r '.items[] | select(.metadata.ownerReferences[] | select(.kind=="ModuleSource" and .name=="deckhouse")) | "\(.spec.moduleName) \(.spec.version)"')
         [[ -z "$modules" ]] && return 0
         local registry_modules=$(d8-crane ls "$repo" 2>/dev/null)
      
         echo "Модуль | Наличие модуля"
         echo "-------|---------------"
      
         echo "$modules" | while read module version; do
            grep -qx "$module" <<< "$registry_modules" && list="✅" || list="❌"
            echo "$module | $list"
         done
      }
      
      d8-crane --help > /dev/null 2>&1 || { echo "ERROR: crane not found"; exit 1; }
      d8-crane-login "registry-cse.deckhouse.ru" "$LICENSE_TOKEN"
      check_external_modules "registry-cse.deckhouse.ru/deckhouse/cse/modules"
      )
      
    3. Отключите модули которые не были найдены в новой редакции, если это допустимо. Иначе, прервите процесс переключения.

  8. Убедитесь в выполнении всех задач в очередях DP, прежде чем продолжить процесс переключения:

    d8 system queue list
    

    Пример вывода (очереди пусты)...

    Summary:
    - 'main' queue: empty.
    - 88 other queues (0 active, 88 empty): 0 tasks.
    - no tasks to handle.
    

Переключение редакции

Выбор способа переключения

При выборе способа переключения редакции учитывайте то, каким образом в кластере организована работа с хранилищем образов контейнеров DP.

Существует два способа работы с хранилищем образов контейнеров DP:

  • С использованием модуля registry — конфигурация работы с хранилищем образов DP задана в секции registry параметров модуля deckhouse (ModuleConfig deckhouse). Это обеспечивает более плавный процесс перехода и автоматическую проверку наличия необходимых образов. Если в кластере используется этот способ работы с хранилищем образов контейнеров DP, для переключения редакции воспользуйтесь разделом «Переключение с помощью модуля registry».

  • Без использования модуля registry — конфигурация работы с хранилищем образов DP задаётся при установке кластера в InitConfiguration, параметр registry.mode модуля deckhouse (ModuleConfig deckhouse) установлен в Unmanaged, параметр registry.unmanaged модуля deckhouse не задан.

    Этот способ — единственный доступный для managed Kubernetes-кластеров, где control plane управляется провайдером облачных услуг, а не DP (например, Amazon EKS, Azure AKS, Google GKE и др.).

    Если в кластере используется этот способ работы с хранилищем образов контейнеров DP, для переключения редакции воспользуйтесь разделом «Переключение без использования модуля registry».

Переключение с помощью модуля registry

  • Перед выполнением дальнейших шагов выполните подготовительные действия, описанные в разделе «Подготовка к переключению».
  • Данное переключение необходимо выполнять только в режиме Unmanaged. Убедитесь, что в кластере используется модуль registry. В moduleConfig deckhouse должны быть указаны параметры хранилища образов предыдущей редакции DP в Unmanaged режиме работы. Если это не так, выполните миграцию на использование модуля registry и переключите режим работы с хранилищем образов в Unmanaged.
  • Данный способ не подходит для managed Kubernetes (EKS, AKS, GKE) и для DP CSE ниже 1.73.
  • Переключние в CSE выполнятеся только из EE редакции.
  1. Только для DP CSE — удалите поле releaseChannel в moduleConfig deckhouse:

    apiVersion: deckhouse.io/v1alpha1
    kind: ModuleConfig
    metadata:
      name: deckhouse
    spec:
      version: 1
      enabled: true
      settings:
        #  releaseChannel
        ...
    
  2. В ModuleConfig deckhouse укажите imagesRepo целевой редакции и checkMode: Relax:

    Выполните команду для редактирования ModuleConfig deckhouse:

    d8 k edit moduleconfig deckhouse
    

    Выберите пример для вашей целевой редакции:

    • DP CE
    • DP BE
    • DP SE
    • DP SE+
    • DP EE
    • DP CSE
    apiVersion: deckhouse.io/v1alpha1
    kind: ModuleConfig
    metadata:
      name: deckhouse
    spec:
      version: 1
      enabled: true
      settings:
        registry:
          mode: Unmanaged
          unmanaged:
            checkMode: Relax
            imagesRepo: registry.deckhouse.ru/deckhouse/ce
            scheme: HTTPS
    
    apiVersion: deckhouse.io/v1alpha1
    kind: ModuleConfig
    metadata:
      name: deckhouse
    spec:
      version: 1
      enabled: true
      settings:
        registry:
          mode: Unmanaged
          unmanaged:
            license: <ЛИЦЕНЗИОННЫЙ_КЛЮЧ>
            checkMode: Relax
            imagesRepo: registry.deckhouse.ru/deckhouse/be
            scheme: HTTPS
    
    apiVersion: deckhouse.io/v1alpha1
    kind: ModuleConfig
    metadata:
      name: deckhouse
    spec:
      version: 1
      enabled: true
      settings:
        registry:
          mode: Unmanaged
          unmanaged:
            license: <ЛИЦЕНЗИОННЫЙ_КЛЮЧ>
            checkMode: Relax
            imagesRepo: registry.deckhouse.ru/deckhouse/se
            scheme: HTTPS
    
    apiVersion: deckhouse.io/v1alpha1
    kind: ModuleConfig
    metadata:
      name: deckhouse
    spec:
      version: 1
      enabled: true
      settings:
        registry:
          mode: Unmanaged
          unmanaged:
            license: <ЛИЦЕНЗИОННЫЙ_КЛЮЧ>
            checkMode: Relax
            imagesRepo: registry.deckhouse.ru/deckhouse/se-plus
            scheme: HTTPS
    
    apiVersion: deckhouse.io/v1alpha1
    kind: ModuleConfig
    metadata:
      name: deckhouse
    spec:
      version: 1
      enabled: true
      settings:
        registry:
          mode: Unmanaged
          unmanaged:
            license: <ЛИЦЕНЗИОННЫЙ_КЛЮЧ>
            checkMode: Relax
            imagesRepo: registry.deckhouse.ru/deckhouse/ee
            scheme: HTTPS
    
    apiVersion: deckhouse.io/v1alpha1
    kind: ModuleConfig
    metadata:
      name: deckhouse
    spec:
      version: 1
      enabled: true
      settings:
        registry:
          mode: Unmanaged
          unmanaged:
            license: <ЛИЦЕНЗИОННЫЙ_КЛЮЧ>
            checkMode: Relax
            imagesRepo: registry-cse.deckhouse.ru/deckhouse/cse
            scheme: HTTPS
    
  3. Убедитесь, что поды deckhouse запустились после смены хранилища образов:

    1. Для этого, воспользуйтесь командой:

      d8 k -n d8-system get pods -l "app=deckhouse"
      
    2. Если под находится в ImagePullBackoff с ошибкой скачивания сайдкар-контейнеров, укажите актуальные образы:

      Получить актуальные дайджесты образов сайдкаров:

      DECKHOUSE_VERSION=$(d8 k -n d8-system get deploy deckhouse -ojson | jq -r '.spec.template.spec.containers[] | select(.name == "deckhouse") | .image' | awk -F':' '{print $1}')
      DKP_TAG=$(d8 k -n d8-system get deploy deckhouse -ojson | jq -r '.spec.template.spec.containers[] | select(.name == "deckhouse") | .image' | awk -F':' '{print $2}')
      
      d8 k run dkp-image --image=$DECKHOUSE_VERSION/install:$DKP_TAG --command sleep -- infinity
      d8 k wait --for=condition=ready pod/dkp-image --timeout=300s
      
      DECKHOUSE_KUBE_RBAC_PROXY=$(d8 k exec dkp-image -- cat /deckhouse/candi/images_digests.json | jq -r ".common.kubeRbacProxy")
      DECKHOUSE_INIT=$(d8 k exec dkp-image -- cat /deckhouse/candi/images_digests.json | jq -r ".deckhouse.init")
      
      d8 k delete pod dkp-image
      

      Применение образов:

      d8 k -n d8-system set image deployment/deckhouse \
      kube-rbac-proxy=$DECKHOUSE_VERSION@$DECKHOUSE_KUBE_RBAC_PROXY \
      init-downloaded-modules=$DECKHOUSE_VERSION@$DECKHOUSE_INIT
      
    3. Убедитесь, в отсутствии ошибки скачивания образа:

      d8 k -n d8-system get pods -l "app=deckhouse"
      
  4. Дождитесь переключения.

    Проверка статуса переключения:

    d8 k -n d8-system -o yaml get secret registry-state | yq -C -P '.data | del .state | map_values(@base64d) | .conditions = (.conditions | from_yaml) | {"conditions": [.conditions[] | select(.type == "Ready" or .type == "RegistryContainsRequiredImages")]}'
    

    Пример успешного вывода:

    • CE/BE/SE/SE+/EE
    • CSE
    conditions:
      - lastTransitionTime: "2026-05-05T13:53:23Z"
        message: |-
          Mode: Default
          registry.deckhouse.ru: all 1 items are checked
        reason: Ready
        status: "True"
        type: RegistryContainsRequiredImages
      - lastTransitionTime: "2026-05-05T13:54:49Z"
        message: ""
        reason: ""
        status: "True"
        type: Ready
    
    conditions:
      - lastTransitionTime: "2026-05-05T13:53:23Z"
        message: |-
          Mode: Default
          registry-cse.deckhouse.ru: all 1 items are checked
        reason: Ready
        status: "True"
        type: RegistryContainsRequiredImages
      - lastTransitionTime: "2026-05-05T13:54:49Z"
        message: ""
        reason: ""
        status: "True"
        type: Ready
    
  5. Верните checkMode в Default:

    d8 k patch moduleconfig deckhouse --type=json -p='[{"op": "replace", "path": "/spec/settings/registry/unmanaged/checkMode", "value": "Default"}]'
    
  6. Снова проверьте статус переключения.

    Проверка статуса:

    d8 k -n d8-system -o yaml get secret registry-state | yq -C -P '.data | del .state | map_values(@base64d) | .conditions = (.conditions | from_yaml) | {"conditions": [.conditions[] | select(.type == "Ready" or .type == "RegistryContainsRequiredImages")]}'
    

    Пример успешного вывода:

    • CE/BE/SE/SE+/EE
    • CSE
    conditions:
      - lastTransitionTime: "2026-05-05T13:53:23Z"
        message: |-
          Mode: Default
          registry.deckhouse.ru: all 182 items are checked
        reason: Ready
        status: "True"
        type: RegistryContainsRequiredImages
      - lastTransitionTime: "2026-05-05T13:54:49Z"
        message: ""
        reason: ""
        status: "True"
        type: Ready
    
    conditions:
      - lastTransitionTime: "2026-05-05T13:53:23Z"
        message: |-
          Mode: Default
          registry-cse.deckhouse.ru: all 182 items are checked
        reason: Ready
        status: "True"
        type: RegistryContainsRequiredImages
      - lastTransitionTime: "2026-05-05T13:54:49Z"
        message: ""
        reason: ""
        status: "True"
        type: Ready
    
  7. Проверьте наличие подов с ошибками загрузки образов:

    d8 k get pods -A | awk 'NR==1 || /^d8-/' | grep -E 'ImagePullBackOff|ErrImagePull'
    

    Для каждого проблемного модуля на всех master-узлах выполните следующие команды, указав имя модуля:

    rm -rf /var/lib/deckhouse/downloaded/<ИМЯ_МОДУЛЯ>/
    d8 k rollout restart deploy -n d8-system deckhouse
    
  8. Проверьте поды с образами из хранилища образов контейнеров для старой редакции:

    d8 k get pods -A -o json | jq -r '.items[] | select(.spec.containers[] | select(.image | contains("deckhouse.ru/deckhouse/<КОД_ПРЕДЫДУЩЕЙ_РЕДАКЦИИ>"))) | .metadata.namespace + "\t" + .metadata.name' | sort | uniq
    
  9. Только для DP CSE — подтвердите перезагрузку узлов:

    Каждый узел один раз перезагрузится с очисткой кеша образов containerd. После перезагрузки узел заново скачает все образы из хранилища образов контейнеров.

    Подтверждайте узлы по одному, дожидаясь возвращения каждого в состояние Ready.

    В ручном режиме подтверждения простоя DP не вытесняет поды с узла — аннотация подтверждения сразу разрешает очистку состояния containerd. Вытесните нагрузку самостоятельно:

    d8 k drain <ИМЯ_УЗЛА> --ignore-daemonsets --delete-emptydir-data
    

    Не подтверждайте узел, пока манифесты control plane на master-узлах не начнут ссылаться на образы DP CSE: команда grep image: /etc/kubernetes/manifests/* не должна возвращать строк с deckhouse/ee. Если такие строки ещё есть, дождитесь, пока control-plane-manager перепишет манифесты. До подтверждения узел работает штатно, но не переходит в состояние UPTODATE.

    Подтвердите обновление узла:

    d8 k annotate node <ИМЯ_УЗЛА> update.node.deckhouse.io/disruption-approved=
    

    После возвращения узла в состояние Ready верните его в планирование:

    d8 k uncordon <ИМЯ_УЗЛА>
    
  10. Только для DP CSE — установите releaseChannel в moduleConfig deckhouse:

    apiVersion: deckhouse.io/v1alpha1
    kind: ModuleConfig
    metadata:
      name: deckhouse
    spec:
      version: 1
      enabled: true
      settings:
        releaseChannel: LTS
        ...
    
  11. Только для DP CSE — включите модуль chrony:

    d8 system module enable chrony
    

Переключение без использования модуля registry

Выберите целевую редакцию:

  • DP CE/BE/SE/SE+/EE
  • DP CSE v1.73
  • DP CSE v1.58/v1.64/v1.67
  1. Выполните команду для указания данных аутентификации в хранилище образов:

    • DP CE
    • DP BE
    • DP SE
    • DP SE+
    • DP EE

    Для DP CE данный шаг не требуется.

    Если необходимо добавить конфигурации для дополнительного registry в containerd, воспользуйтесь инструкцией из раздела «Как добавить конфигурацию для дополнительного registry в containerd».

    Для ContainerdV1:

    AUTH_STRING="$(echo -n license-token:${LICENSE_TOKEN} | base64 )"
    d8 k --as=system:sudouser apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: containerdv1-be-config.sh
    spec:
      nodeGroups:
      - '*'
      bundles:
      - '*'
      weight: 1
      content: |
        mkdir -p /etc/containerd/conf.d
        bb-sync-file /etc/containerd/conf.d/be-registry.toml - << "EOF"
        [plugins]
          [plugins."io.containerd.grpc.v1.cri"]
            [plugins."io.containerd.grpc.v1.cri".registry.configs]
              [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
                [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.deckhouse.ru"]
                  endpoint = ["https://registry.deckhouse.ru"]
              [plugins."io.containerd.grpc.v1.cri".registry.configs."registry.deckhouse.ru".auth]
                auth = "$AUTH_STRING"
        EOF
    EOF
    

    Для ContainerdV2:

    d8 k --as=system:sudouser apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: containerdv2-be-config.sh
    spec:
      nodeGroups:
      - '*'
      bundles:
      - '*'
      weight: 31
      content: |
        mkdir -p /etc/containerd/registry.d/registry.deckhouse.ru
        bb-sync-file "/etc/containerd/registry.d/registry.deckhouse.ru/hosts.toml" - << "EOF"
        [host]
    
          [host."https://registry.deckhouse.ru"]
             capabilities = ["pull", "resolve"]
             [host."https://registry.deckhouse.ru".auth]
                username = "license-token"
                password = "${LICENSE_TOKEN}"
        EOF
    EOF
    

    Дождитесь синхронизации сервиса bashible (значение в колонке UPTODATE у NodeGroup должно совпадать с NODES):

    d8 k get ng -o custom-columns=NAME:.metadata.name,NODES:.status.nodes,READY:.status.ready,UPTODATE:.status.upToDate
    

    В логе bashible должно быть Configuration is in sync, nothing to do:

    journalctl -u bashible -n 5
    

    Если необходимо добавить конфигурации для дополнительного registry в containerd, воспользуйтесь инструкцией из раздела «Как добавить конфигурацию для дополнительного registry в containerd».

    Для ContainerdV1:

    AUTH_STRING="$(echo -n license-token:${LICENSE_TOKEN} | base64 )"
    d8 k --as=system:sudouser apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: containerdv1-se-config.sh
    spec:
      nodeGroups:
      - '*'
      bundles:
      - '*'
      weight: 1
      content: |
        mkdir -p /etc/containerd/conf.d
        bb-sync-file /etc/containerd/conf.d/se-registry.toml - << "EOF"
        [plugins]
          [plugins."io.containerd.grpc.v1.cri"]
            [plugins."io.containerd.grpc.v1.cri".registry.configs]
              [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
                [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.deckhouse.ru"]
                  endpoint = ["https://registry.deckhouse.ru"]
              [plugins."io.containerd.grpc.v1.cri".registry.configs."registry.deckhouse.ru".auth]
                auth = "$AUTH_STRING"
        EOF
    EOF
    

    Для ContainerdV2:

    d8 k --as=system:sudouser apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: containerdv2-se-config.sh
    spec:
      nodeGroups:
      - '*'
      bundles:
      - '*'
      weight: 31
      content: |
        mkdir -p /etc/containerd/registry.d/registry.deckhouse.ru
        bb-sync-file "/etc/containerd/registry.d/registry.deckhouse.ru/hosts.toml" - << "EOF"
        [host]
    
          [host."https://registry.deckhouse.ru"]
             capabilities = ["pull", "resolve"]
             [host."https://registry.deckhouse.ru".auth]
                username = "license-token"
                password = "${LICENSE_TOKEN}"
        EOF
    EOF
    

    Дождитесь синхронизации сервиса bashible (значение в колонке UPTODATE у NodeGroup должно совпадать с NODES):

    d8 k get ng -o custom-columns=NAME:.metadata.name,NODES:.status.nodes,READY:.status.ready,UPTODATE:.status.upToDate
    

    В логе bashible должно быть Configuration is in sync, nothing to do:

    journalctl -u bashible -n 5
    

    Если необходимо добавить конфигурации для дополнительного registry в containerd, воспользуйтесь инструкцией из раздела «Как добавить конфигурацию для дополнительного registry в containerd».

    Для ContainerdV1:

    AUTH_STRING="$(echo -n license-token:${LICENSE_TOKEN} | base64 )"
    d8 k --as=system:sudouser apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: containerdv1-se-plus-config.sh
    spec:
      nodeGroups:
      - '*'
      bundles:
      - '*'
      weight: 1
      content: |
        mkdir -p /etc/containerd/conf.d
        bb-sync-file /etc/containerd/conf.d/se-plus-registry.toml - << "EOF"
        [plugins]
          [plugins."io.containerd.grpc.v1.cri"]
            [plugins."io.containerd.grpc.v1.cri".registry.configs]
              [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
                [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.deckhouse.ru"]
                  endpoint = ["https://registry.deckhouse.ru"]
              [plugins."io.containerd.grpc.v1.cri".registry.configs."registry.deckhouse.ru".auth]
                auth = "$AUTH_STRING"
        EOF
    EOF
    

    Для ContainerdV2:

    d8 k --as=system:sudouser apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: containerdv2-se-plus-config.sh
    spec:
      nodeGroups:
      - '*'
      bundles:
      - '*'
      weight: 31
      content: |
        mkdir -p /etc/containerd/registry.d/registry.deckhouse.ru
        bb-sync-file "/etc/containerd/registry.d/registry.deckhouse.ru/hosts.toml" - << "EOF"
        [host]
    
          [host."https://registry.deckhouse.ru"]
             capabilities = ["pull", "resolve"]
             [host."https://registry.deckhouse.ru".auth]
                username = "license-token"
                password = "${LICENSE_TOKEN}"
        EOF
    EOF
    

    Дождитесь синхронизации сервиса bashible (значение в колонке UPTODATE у NodeGroup должно совпадать с NODES):

    d8 k get ng -o custom-columns=NAME:.metadata.name,NODES:.status.nodes,READY:.status.ready,UPTODATE:.status.upToDate
    

    В логе bashible должно быть Configuration is in sync, nothing to do:

    journalctl -u bashible -n 5
    

    Если необходимо добавить конфигурации для дополнительного registry в containerd, воспользуйтесь инструкцией из раздела «Как добавить конфигурацию для дополнительного registry в containerd».

    Для ContainerdV1:

    AUTH_STRING="$(echo -n license-token:${LICENSE_TOKEN} | base64 )"
    d8 k --as=system:sudouser apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: containerdv1-ee-config.sh
    spec:
      nodeGroups:
      - '*'
      bundles:
      - '*'
      weight: 1
      content: |
        mkdir -p /etc/containerd/conf.d
        bb-sync-file /etc/containerd/conf.d/ee-registry.toml - << "EOF"
        [plugins]
          [plugins."io.containerd.grpc.v1.cri"]
            [plugins."io.containerd.grpc.v1.cri".registry.configs]
              [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
                [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.deckhouse.ru"]
                  endpoint = ["https://registry.deckhouse.ru"]
              [plugins."io.containerd.grpc.v1.cri".registry.configs."registry.deckhouse.ru".auth]
                auth = "$AUTH_STRING"
        EOF
    EOF
    

    Для ContainerdV2:

    d8 k --as=system:sudouser apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: containerdv2-ee-config.sh
    spec:
      nodeGroups:
      - '*'
      bundles:
      - '*'
      weight: 31
      content: |
        mkdir -p /etc/containerd/registry.d/registry.deckhouse.ru
        bb-sync-file "/etc/containerd/registry.d/registry.deckhouse.ru/hosts.toml" - << "EOF"
        [host]
    
          [host."https://registry.deckhouse.ru"]
             capabilities = ["pull", "resolve"]
             [host."https://registry.deckhouse.ru".auth]
                username = "license-token"
                password = "${LICENSE_TOKEN}"
        EOF
    EOF
    

    Дождитесь синхронизации сервиса bashible (значение в колонке UPTODATE у NodeGroup должно совпадать с NODES):

    d8 k get ng -o custom-columns=NAME:.metadata.name,NODES:.status.nodes,READY:.status.ready,UPTODATE:.status.upToDate
    

    В логе bashible должно быть Configuration is in sync, nothing to do:

    journalctl -u bashible -n 5
    
  2. Переключите хранилище образов контейнеров:

    • DP CE
    • DP BE
    • DP SE
    • DP SE+
    • DP EE
    DECKHOUSE_VERSION=$(d8 k -n d8-system get deploy deckhouse -ojson | jq -r '.spec.template.spec.containers[] | select(.name == "deckhouse") | .image' | awk -F: '{print $NF}')
    
    d8 k -n d8-system exec -ti svc/deckhouse-leader -c deckhouse -- deckhouse-controller helper change-registry \
    --new-deckhouse-tag=$DECKHOUSE_VERSION \
    registry.deckhouse.ru/deckhouse/ce
    
    DECKHOUSE_VERSION=$(d8 k -n d8-system get deploy deckhouse -ojson | jq -r '.spec.template.spec.containers[] | select(.name == "deckhouse") | .image' | awk -F: '{print $NF}')
    
    AUTH_STRING="$(echo -n license-token:${LICENSE_TOKEN} | base64 )"
    DOCKER_CONFIG_JSON=$(echo -n "{\"auths\": {\"registry.deckhouse.ru\": {\"username\": \"license-token\", \"password\": \"${LICENSE_TOKEN}\", \"auth\": \"${AUTH_STRING}\"}}}" | base64 -w 0)
    
    d8 k --as system:sudouser -n d8-cloud-instance-manager patch secret deckhouse-registry \
    --type merge \
    --patch="{\"data\":{\".dockerconfigjson\":\"$DOCKER_CONFIG_JSON\"}}"
    
    d8 k -n d8-system exec -ti svc/deckhouse-leader -c deckhouse -- deckhouse-controller helper change-registry \
    --user=license-token \
    --password=$LICENSE_TOKEN \
    --new-deckhouse-tag=$DECKHOUSE_VERSION \
    registry.deckhouse.ru/deckhouse/be
    
    DECKHOUSE_VERSION=$(d8 k -n d8-system get deploy deckhouse -ojson | jq -r '.spec.template.spec.containers[] | select(.name == "deckhouse") | .image' | awk -F: '{print $NF}')
    
    AUTH_STRING="$(echo -n license-token:${LICENSE_TOKEN} | base64 )"
    DOCKER_CONFIG_JSON=$(echo -n "{\"auths\": {\"registry.deckhouse.ru\": {\"username\": \"license-token\", \"password\": \"${LICENSE_TOKEN}\", \"auth\": \"${AUTH_STRING}\"}}}" | base64 -w 0)
    
    d8 k --as system:sudouser -n d8-cloud-instance-manager patch secret deckhouse-registry \
    --type merge \
    --patch="{\"data\":{\".dockerconfigjson\":\"$DOCKER_CONFIG_JSON\"}}"
    
    d8 k -n d8-system exec -ti svc/deckhouse-leader -c deckhouse -- deckhouse-controller helper change-registry \
    --user=license-token \
    --password=$LICENSE_TOKEN \
    --new-deckhouse-tag=$DECKHOUSE_VERSION \
    registry.deckhouse.ru/deckhouse/se
    
    DECKHOUSE_VERSION=$(d8 k -n d8-system get deploy deckhouse -ojson | jq -r '.spec.template.spec.containers[] | select(.name == "deckhouse") | .image' | awk -F: '{print $NF}')
    
    AUTH_STRING="$(echo -n license-token:${LICENSE_TOKEN} | base64 )"
    DOCKER_CONFIG_JSON=$(echo -n "{\"auths\": {\"registry.deckhouse.ru\": {\"username\": \"license-token\", \"password\": \"${LICENSE_TOKEN}\", \"auth\": \"${AUTH_STRING}\"}}}" | base64 -w 0)
    
    d8 k --as system:sudouser -n d8-cloud-instance-manager patch secret deckhouse-registry \
    --type merge \
    --patch="{\"data\":{\".dockerconfigjson\":\"$DOCKER_CONFIG_JSON\"}}"
    
    d8 k -n d8-system exec -ti svc/deckhouse-leader -c deckhouse -- deckhouse-controller helper change-registry \
    --user=license-token \
    --password=$LICENSE_TOKEN \
    --new-deckhouse-tag=$DECKHOUSE_VERSION \
    registry.deckhouse.ru/deckhouse/se-plus
    
    DECKHOUSE_VERSION=$(d8 k -n d8-system get deploy deckhouse -ojson | jq -r '.spec.template.spec.containers[] | select(.name == "deckhouse") | .image' | awk -F: '{print $NF}')
    
    AUTH_STRING="$(echo -n license-token:${LICENSE_TOKEN} | base64 )"
    DOCKER_CONFIG_JSON=$(echo -n "{\"auths\": {\"registry.deckhouse.ru\": {\"username\": \"license-token\", \"password\": \"${LICENSE_TOKEN}\", \"auth\": \"${AUTH_STRING}\"}}}" | base64 -w 0)
    
    d8 k --as system:sudouser -n d8-cloud-instance-manager patch secret deckhouse-registry \
    --type merge \
    --patch="{\"data\":{\".dockerconfigjson\":\"$DOCKER_CONFIG_JSON\"}}"
    
    d8 k -n d8-system exec -ti svc/deckhouse-leader -c deckhouse -- deckhouse-controller helper change-registry \
    --user=license-token \
    --password=$LICENSE_TOKEN \
    --new-deckhouse-tag=$DECKHOUSE_VERSION \
    registry.deckhouse.ru/deckhouse/ee
    
  3. Убедитесь, что поды deckhouse запустились после смены хранилища образов:

    1. Для этого, воспользуйтесь командой:

      d8 k -n d8-system get pods -l "app=deckhouse"
      
    2. Если под находится в ImagePullBackoff с ошибкой скачивания сайдкар-контейнеров, укажите актуальные образы:

      Получить актуальные дайджесты образов сайдкаров:

      DECKHOUSE_VERSION=$(d8 k -n d8-system get deploy deckhouse -ojson | jq -r '.spec.template.spec.containers[] | select(.name == "deckhouse") | .image' | awk -F':' '{print $1}')
      DKP_TAG=$(d8 k -n d8-system get deploy deckhouse -ojson | jq -r '.spec.template.spec.containers[] | select(.name == "deckhouse") | .image' | awk -F':' '{print $2}')
      
      d8 k run dkp-image --image=$DECKHOUSE_VERSION/install:$DKP_TAG --command sleep -- infinity
      d8 k wait --for=condition=ready pod/dkp-image --timeout=300s
      
      DECKHOUSE_KUBE_RBAC_PROXY=$(d8 k exec dkp-image -- cat /deckhouse/candi/images_digests.json | jq -r ".common.kubeRbacProxy")
      DECKHOUSE_INIT=$(d8 k exec dkp-image -- cat /deckhouse/candi/images_digests.json | jq -r ".deckhouse.init")
      
      d8 k delete pod dkp-image
      

      Применение образов:

      d8 k -n d8-system set image deployment/deckhouse \
      kube-rbac-proxy=$DECKHOUSE_VERSION@$DECKHOUSE_KUBE_RBAC_PROXY \
      init-downloaded-modules=$DECKHOUSE_VERSION@$DECKHOUSE_INIT
      
    3. Убедитесь, в отсутствии ошибки скачивания образа:

      d8 k -n d8-system get pods -l "app=deckhouse"
      
  4. Дождитесь готовности DP:

    d8 system queue list
    

    Пример вывода (очереди пусты)...

    Summary:
    - 'main' queue: empty.
    - 88 other queues (0 active, 88 empty): 0 tasks.
    - no tasks to handle.
    
  5. Проверьте наличие подов с ошибками загрузки образов:

    d8 k get pods -A | awk 'NR==1 || /^d8-/' | grep -E 'ImagePullBackOff|ErrImagePull'
    

    Для каждого проблемного модуля на всех master-узлах выполните следующие команды, указав имя модуля:

    rm -rf /var/lib/deckhouse/downloaded/<ИМЯ_МОДУЛЯ>/
    d8 k rollout restart deploy -n d8-system deckhouse
    
  6. Проверьте поды с образами из хранилища образов контейнеров для старой редакции:

    d8 k get pods -A -o json | jq -r '.items[] | select(.spec.containers[] | select(.image | contains("deckhouse.ru/deckhouse/<КОД_ПРЕДЫДУЩЕЙ_РЕДАКЦИИ>"))) | .metadata.namespace + "\t" + .metadata.name' | sort | uniq
    
  7. Выполните очистку:

    • DP CE
    • DP BE
    • DP SE
    • DP SE+
    • DP EE

    Для DP CE данный шаг не требуется.

    Для ContainerdV1

    d8 k --as=system:sudouser delete ngc containerdv1-be-config.sh
    d8 k --as=system:sudouser apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: del-temp-config.sh
    spec:
      nodeGroups:
      - '*'
      bundles:
      - '*'
      weight: 1
      content: |
        if [ -f /etc/containerd/conf.d/be-registry.toml ]; then
          rm -f /etc/containerd/conf.d/be-registry.toml
        fi
    EOF
    
    d8 k --as=system:sudouser delete ngc del-temp-config.sh
    

    Для ContainerdV2

    d8 k --as=system:sudouser delete ngc containerdv2-be-config.sh
    

    Дождитесь синхронизации сервиса bashible (значение в колонке UPTODATE у NodeGroup должно совпадать с NODES):

    d8 k get ng -o custom-columns=NAME:.metadata.name,NODES:.status.nodes,READY:.status.ready,UPTODATE:.status.upToDate
    

    В логе bashible должно быть Configuration is in sync, nothing to do:

    journalctl -u bashible -n 5
    

    Для ContainerdV1

    d8 k --as=system:sudouser delete ngc containerdv1-se-config.sh
    d8 k --as=system:sudouser apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: del-temp-config.sh
    spec:
      nodeGroups:
      - '*'
      bundles:
      - '*'
      weight: 1
      content: |
        if [ -f /etc/containerd/conf.d/se-registry.toml ]; then
          rm -f /etc/containerd/conf.d/se-registry.toml
        fi
    EOF
    
    d8 k --as=system:sudouser delete ngc del-temp-config.sh
    

    Для ContainerdV2

    d8 k --as=system:sudouser delete ngc containerdv2-se-config.sh
    

    Дождитесь синхронизации сервиса bashible (значение в колонке UPTODATE у NodeGroup должно совпадать с NODES):

    d8 k get ng -o custom-columns=NAME:.metadata.name,NODES:.status.nodes,READY:.status.ready,UPTODATE:.status.upToDate
    

    В логе bashible должно быть Configuration is in sync, nothing to do:

    journalctl -u bashible -n 5
    

    Для ContainerdV1

    d8 k --as=system:sudouser delete ngc containerdv1-se-plus-config.sh
    d8 k --as=system:sudouser apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: del-temp-config.sh
    spec:
      nodeGroups:
      - '*'
      bundles:
      - '*'
      weight: 1
      content: |
        if [ -f /etc/containerd/conf.d/se-plus-registry.toml ]; then
          rm -f /etc/containerd/conf.d/se-plus-registry.toml
        fi
    EOF
    
    d8 k --as=system:sudouser delete ngc del-temp-config.sh
    

    Для ContainerdV2

    d8 k --as=system:sudouser delete ngc containerdv2-se-plus-config.sh
    

    Дождитесь синхронизации сервиса bashible (значение в колонке UPTODATE у NodeGroup должно совпадать с NODES):

    d8 k get ng -o custom-columns=NAME:.metadata.name,NODES:.status.nodes,READY:.status.ready,UPTODATE:.status.upToDate
    

    В логе bashible должно быть Configuration is in sync, nothing to do:

    journalctl -u bashible -n 5
    

    Для ContainerdV1

    d8 k --as=system:sudouser delete ngc containerdv1-ee-config.sh
    d8 k --as=system:sudouser apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: del-temp-config.sh
    spec:
      nodeGroups:
      - '*'
      bundles:
      - '*'
      weight: 1
      content: |
        if [ -f /etc/containerd/conf.d/ee-registry.toml ]; then
          rm -f /etc/containerd/conf.d/ee-registry.toml
        fi
    EOF
    
    d8 k --as=system:sudouser delete ngc del-temp-config.sh
    

    Для ContainerdV2

    d8 k --as=system:sudouser delete ngc containerdv2-ee-config.sh
    

    Дождитесь синхронизации сервиса bashible (значение в колонке UPTODATE у NodeGroup должно совпадать с NODES):

    d8 k get ng -o custom-columns=NAME:.metadata.name,NODES:.status.nodes,READY:.status.ready,UPTODATE:.status.upToDate
    

    В логе bashible должно быть Configuration is in sync, nothing to do:

    journalctl -u bashible -n 5
    
  1. Укажите версию DP CSE, которую вы хотите использовать:

    DECKHOUSE_VERSION=v1.73.3
    
  2. Выполните команду для указания данных аутентификации в хранилище образов:

    Если необходимо добавить конфигурации для дополнительного registry в containerd, воспользуйтесь инструкцией из раздела «Как добавить конфигурацию для дополнительного registry в containerd».

    Для ContainerdV1:

    AUTH_STRING="$(echo -n license-token:${LICENSE_TOKEN} | base64 )"
    d8 k --as=system:sudouser apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: containerdv1-cse-config.sh
    spec:
      nodeGroups:
      - '*'
      bundles:
      - '*'
      weight: 1
      content: |
        mkdir -p /etc/containerd/conf.d
        bb-sync-file /etc/containerd/conf.d/cse-registry.toml - << "EOF"
        [plugins]
          [plugins."io.containerd.grpc.v1.cri"]
            [plugins."io.containerd.grpc.v1.cri".registry.configs]
              [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
                [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry-cse.deckhouse.ru"]
                  endpoint = ["https://registry-cse.deckhouse.ru"]
              [plugins."io.containerd.grpc.v1.cri".registry.configs."registry-cse.deckhouse.ru".auth]
                auth = "$AUTH_STRING"
        EOF
    EOF
    

    Для ContainerdV2:

    d8 k --as=system:sudouser apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: containerdv2-cse-config.sh
    spec:
      nodeGroups:
      - '*'
      bundles:
      - '*'
      weight: 31
      content: |
        mkdir -p /etc/containerd/registry.d/registry-cse.deckhouse.ru
        bb-sync-file "/etc/containerd/registry.d/registry-cse.deckhouse.ru/hosts.toml" - << "EOF"
        [host]
       
          [host."https://registry-cse.deckhouse.ru"]
             capabilities = ["pull", "resolve"]
             [host."https://registry-cse.deckhouse.ru".auth]
                username = "license-token"
                password = "${LICENSE_TOKEN}"
        EOF
    EOF
    

    Дождитесь синхронизации сервиса bashible (значение в колонке UPTODATE у NodeGroup должно совпадать с NODES):

    d8 k get ng -o custom-columns=NAME:.metadata.name,NODES:.status.nodes,READY:.status.ready,UPTODATE:.status.upToDate
    

    В логе bashible должно быть Configuration is in sync, nothing to do:

    journalctl -u bashible -n 5
    
  3. Получите дайджесты образов (переменные будут использоваться в следующих шагах):

    d8 k run cse-image --image=registry-cse.deckhouse.ru/deckhouse/cse/install:$DECKHOUSE_VERSION --command sleep -- infinity
    d8 k wait --for=condition=ready pod/cse-image --timeout=300s
    CSE_SANDBOX_IMAGE=$(d8 k exec cse-image -- cat deckhouse/candi/images_digests.json | grep pause | grep -oE 'sha256:\w*')
    CSE_K8S_API_PROXY=$(d8 k exec cse-image -- cat deckhouse/candi/images_digests.json | grep kubernetesApiProxy | grep -oE 'sha256:\w*')
    CSE_DECKHOUSE_KUBE_RBAC_PROXY=$(d8 k exec cse-image -- cat deckhouse/candi/images_digests.json | jq -r ".common.kubeRbacProxy")
    CSE_DECKHOUSE_INIT_CONTAINER=$(d8 k exec cse-image -- cat deckhouse/candi/images_digests.json | jq -r ".common.init")
       
    d8 k delete pod cse-image
    
  4. Обновите данные аутентификации для доступа к хранилищу образов:

    AUTH_STRING="$(echo -n license-token:${LICENSE_TOKEN} | base64 )"
    d8 k -n d8-system create secret generic deckhouse-registry \
       --from-literal=".dockerconfigjson"="{\"auths\": { \"registry-cse.deckhouse.ru\": { \"username\": \"license-token\", \"password\": \"$LICENSE_TOKEN\", \"auth\": \"$AUTH_STRING\" }}}" \
       --from-literal="address"=registry-cse.deckhouse.ru \
       --from-literal="path"=/deckhouse/cse \
       --from-literal="scheme"=https \
       --type=kubernetes.io/dockerconfigjson \
       --dry-run=client -o yaml | d8 k -n d8-system exec -i svc/deckhouse-leader -c deckhouse -- d8 k replace -f -
    
  5. Смените образ DP CSE:

    d8 k -n d8-system set image deployment/deckhouse \
    init-downloaded-modules=registry-cse.deckhouse.ru/deckhouse/cse@$CSE_DECKHOUSE_INIT_CONTAINER \
    kube-rbac-proxy=registry-cse.deckhouse.ru/deckhouse/cse@$CSE_DECKHOUSE_KUBE_RBAC_PROXY \
    deckhouse=registry-cse.deckhouse.ru/deckhouse/cse:$DECKHOUSE_VERSION
    
  6. Подтвердите перезагрузку узлов:

    Каждый узел один раз перезагрузится с очисткой кеша образов containerd. После перезагрузки узел заново скачает все образы из хранилища образов контейнеров.

    Подтверждайте узлы по одному, дожидаясь возвращения каждого в состояние Ready.

    В ручном режиме подтверждения простоя DP не вытесняет поды с узла — аннотация подтверждения сразу разрешает очистку состояния containerd. Вытесните нагрузку самостоятельно:

    d8 k drain <ИМЯ_УЗЛА> --ignore-daemonsets --delete-emptydir-data
    

    Не подтверждайте узел, пока манифесты control plane на master-узлах не начнут ссылаться на образы DP CSE: команда grep image: /etc/kubernetes/manifests/* не должна возвращать строк с deckhouse/ee. Если такие строки ещё есть, дождитесь, пока control-plane-manager перепишет манифесты. До подтверждения узел работает штатно, но не переходит в состояние UPTODATE.

    Подтвердите обновление узла:

    d8 k annotate node <ИМЯ_УЗЛА> update.node.deckhouse.io/disruption-approved=
    

    После возвращения узла в состояние Ready верните его в планирование:

    d8 k uncordon <ИМЯ_УЗЛА>
    
  7. Дождитесь готовности DP:

    d8 system queue list
    

    Пример вывода (очереди пусты)...

    Summary:
    - 'main' queue: empty.
    - 88 other queues (0 active, 88 empty): 0 tasks.
    - no tasks to handle.
    
  8. Проверьте наличие подов с ошибками загрузки образов:

    d8 k get pods -A | awk 'NR==1 || /^d8-/' | grep -E 'ImagePullBackOff|ErrImagePull'
    

    Для каждого проблемного модуля на всех master-узлах выполните следующие команды, указав имя модуля:

    rm -rf /var/lib/deckhouse/downloaded/<ИМЯ_МОДУЛЯ>/
    d8 k rollout restart deploy -n d8-system deckhouse
    
  9. Проверьте поды с образами из хранилища образов контейнеров для старой редакции:

    d8 k get pods -A -o json | jq -r '.items[] | select(.spec.containers[] | select(.image | contains("deckhouse.ru/deckhouse/<КОД_ПРЕДЫДУЩЕЙ_РЕДАКЦИИ>"))) | .metadata.namespace + "\t" + .metadata.name' | sort | uniq
    
  10. Выполните очистку:

    Для ContainerdV1

    d8 k --as=system:sudouser delete ngc containerdv1-cse-config.sh
    d8 k --as=system:sudouser apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: del-temp-config.sh
    spec:
      nodeGroups:
      - '*'
      bundles:
      - '*'
      weight: 1
      content: |
        if [ -f /etc/containerd/conf.d/cse-registry.toml ]; then
          rm -f /etc/containerd/conf.d/cse-registry.toml
        fi
    EOF
    
    d8 k --as=system:sudouser delete ngc del-temp-config.sh
    

    Для ContainerdV2

    d8 k --as=system:sudouser delete ngc containerdv2-cse-config.sh
    

    Дождитесь синхронизации сервиса bashible (значение в колонке UPTODATE у NodeGroup должно совпадать с NODES):

    d8 k get ng -o custom-columns=NAME:.metadata.name,NODES:.status.nodes,READY:.status.ready,UPTODATE:.status.upToDate
    

    В логе bashible должно быть Configuration is in sync, nothing to do:

    journalctl -u bashible -n 5
    
  1. Укажите версию DP CSE, которую вы хотите использовать:

    • CSE 1.58
    • CSE 1.64
    • CSE 1.67
    DECKHOUSE_VERSION=v1.58.2
    
    DECKHOUSE_VERSION=v1.64.1
    
    DECKHOUSE_VERSION=v1.67.4
    
  2. Удалите поле releaseChannel в moduleConfig deckhouse:

    apiVersion: deckhouse.io/v1alpha1
    kind: ModuleConfig
    metadata:
      name: deckhouse
    spec:
      version: 1
      enabled: true
      settings:
        #  releaseChannel
        ...
    
  3. Выполните команду для указания данных аутентификации в хранилище образов:

    Если необходимо добавить конфигурации для дополнительного registry в containerd, воспользуйтесь инструкцией из раздела «Как добавить конфигурацию для дополнительного registry в containerd».

    AUTH_STRING="$(echo -n license-token:${LICENSE_TOKEN} | base64 )"
    d8 k apply -f - <<EOF
    ---
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: containerd-cse-config.sh
    spec:
      nodeGroups:
      - '*'
      bundles:
      - '*'
      weight: 30
      content: |
        _on_containerd_config_changed() {
          bb-flag-set containerd-need-restart
        }
        bb-event-on 'containerd-config-file-changed' '_on_containerd_config_changed'
        mkdir -p /etc/containerd/conf.d
        bb-sync-file /etc/containerd/conf.d/cse-registry.toml - containerd-config-file-changed << "EOF_TOML"
        [plugins]
          [plugins."io.containerd.grpc.v1.cri"]
            [plugins."io.containerd.grpc.v1.cri".registry]
              [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
                [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry-cse.deckhouse.ru"]
                  endpoint = ["https://registry-cse.deckhouse.ru"]
              [plugins."io.containerd.grpc.v1.cri".registry.configs]
                [plugins."io.containerd.grpc.v1.cri".registry.configs."registry-cse.deckhouse.ru".auth]
                  auth = "$AUTH_STRING"
        EOF_TOML
    EOF
    

    Дождитесь синхронизации сервиса bashible (значение в колонке UPTODATE у NodeGroup должно совпадать с NODES):

    d8 k get ng -o custom-columns=NAME:.metadata.name,NODES:.status.nodes,READY:.status.ready,UPTODATE:.status.upToDate
    

    В логе bashible должно быть Configuration is in sync, nothing to do:

    journalctl -u bashible -n 5
    
  4. Получите дайджесты образов (переменные будут использоваться в следующих шагах):

    • CSE 1.58
    • CSE 1.64 / 1.67
    d8 k run cse-image --image=registry-cse.deckhouse.ru/deckhouse/cse/install:$DECKHOUSE_VERSION --command sleep -- infinity
    d8 k wait --for=condition=ready pod/cse-image --timeout=300s
    CSE_SANDBOX_IMAGE=$(d8 k exec cse-image -- cat deckhouse/candi/images_digests.json | grep pause | grep -oE 'sha256:\w*')
    CSE_K8S_API_PROXY=$(d8 k exec cse-image -- cat deckhouse/candi/images_digests.json | grep kubernetesApiProxy | grep -oE 'sha256:\w*')
    CSE_DECKHOUSE_KUBE_RBAC_PROXY=$(d8 k exec cse-image -- cat deckhouse/candi/images_digests.json | jq -r ".common.kubeRbacProxy")
    
    d8 k delete pod cse-image
    
    d8 k run cse-image --image=registry-cse.deckhouse.ru/deckhouse/cse/install:$DECKHOUSE_VERSION --command sleep -- infinity
    d8 k wait --for=condition=ready pod/cse-image --timeout=300s
    CSE_SANDBOX_IMAGE=$(d8 k exec cse-image -- cat deckhouse/candi/images_digests.json | grep pause | grep -oE 'sha256:\w*')
    CSE_K8S_API_PROXY=$(d8 k exec cse-image -- cat deckhouse/candi/images_digests.json | grep kubernetesApiProxy | grep -oE 'sha256:\w*')
    CSE_DECKHOUSE_KUBE_RBAC_PROXY=$(d8 k exec cse-image -- cat deckhouse/candi/images_digests.json | jq -r ".common.kubeRbacProxy")
    CSE_DECKHOUSE_INIT_CONTAINER=$(d8 k exec cse-image -- cat deckhouse/candi/images_digests.json | jq -r ".common.init")
    
    d8 k delete pod cse-image
    
  5. Настройте образы на узлах:

    d8 k apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: cse-set-sha-images.sh
    spec:
      nodeGroups: ['*']
      bundles: ['*']
      weight: 50
      content: |
        _on_containerd_config_changed() { bb-flag-set containerd-need-restart }
        bb-event-on 'containerd-config-file-changed' '_on_containerd_config_changed'
        bb-sync-file /etc/containerd/conf.d/cse-sandbox.toml - containerd-config-file-changed << "EOF_TOML"
        [plugins]
          [plugins."io.containerd.grpc.v1.cri"]
            sandbox_image = "registry-cse.deckhouse.ru/deckhouse/cse@$CSE_SANDBOX_IMAGE"
        EOF_TOML
        sed -i 's|image: .*|image: registry-cse.deckhouse.ru/deckhouse/cse@$CSE_K8S_API_PROXY|' /var/lib/bashible/bundle_steps/051_pull_and_configure_kubernetes_api_proxy.sh
        sed -i 's|crictl pull .*|crictl pull registry-cse.deckhouse.ru/deckhouse/cse@$CSE_K8S_API_PROXY|' /var/lib/bashible/bundle_steps/051_pull_and_configure_kubernetes_api_proxy.sh
    EOF
    

    Дождитесь синхронизации сервиса bashible (значение в колонке UPTODATE у NodeGroup должно совпадать с NODES):

    d8 k get ng -o custom-columns=NAME:.metadata.name,NODES:.status.nodes,READY:.status.ready,UPTODATE:.status.upToDate
    

    В логе bashible должно быть Configuration is in sync, nothing to do:

    journalctl -u bashible -n 5
    
  6. Обновите данные аутентификации для доступа к хранилищу образов:

    AUTH_STRING="$(echo -n license-token:${LICENSE_TOKEN} | base64 )"
    d8 k -n d8-system create secret generic deckhouse-registry \
       --from-literal=".dockerconfigjson"="{\"auths\": { \"registry-cse.deckhouse.ru\": { \"username\": \"license-token\", \"password\": \"$LICENSE_TOKEN\", \"auth\": \"$AUTH_STRING\" }}}" \
       --from-literal="address"=registry-cse.deckhouse.ru \
       --from-literal="path"=/deckhouse/cse \
       --from-literal="scheme"=https \
       --type=kubernetes.io/dockerconfigjson \
       --dry-run=client -o yaml | d8 k -n d8-system exec -i svc/deckhouse-leader -c deckhouse -- d8 k replace -f -
    
  7. Смените образ DP CSE:

    • CSE 1.58
    • CSE 1.64 / 1.67
    d8 k -n d8-system set image deployment/deckhouse \
    kube-rbac-proxy=registry-cse.deckhouse.ru/deckhouse/cse@$CSE_DECKHOUSE_KUBE_RBAC_PROXY \
    deckhouse=registry-cse.deckhouse.ru/deckhouse/cse:$DECKHOUSE_VERSION
    
    d8 k -n d8-system set image deployment/deckhouse \
    init-downloaded-modules=registry-cse.deckhouse.ru/deckhouse/cse@$CSE_DECKHOUSE_INIT_CONTAINER \
    kube-rbac-proxy=registry-cse.deckhouse.ru/deckhouse/cse@$CSE_DECKHOUSE_KUBE_RBAC_PROXY \
    deckhouse=registry-cse.deckhouse.ru/deckhouse/cse:$DECKHOUSE_VERSION
    
  8. Дождитесь готовности DP:

    d8 system queue list
    

    Пример вывода (очереди пусты)...

    Summary:
    - 'main' queue: empty.
    - 88 other queues (0 active, 88 empty): 0 tasks.
    - no tasks to handle.
    
  9. Проверьте поды с образами из хранилища образов контейнеров для старой редакции:

    d8 k get pods -A -o json | jq -r '.items[] | select(.spec.containers[] | select(.image | contains("deckhouse.ru/deckhouse/<КОД_ПРЕДЫДУЩЕЙ_РЕДАКЦИИ>"))) | .metadata.namespace + "\t" + .metadata.name' | sort | uniq
    
  10. Установите releaseChannel в moduleConfig deckhouse:

    apiVersion: deckhouse.io/v1alpha1
    kind: ModuleConfig
    metadata:
      name: deckhouse
    spec:
      version: 1
      enabled: true
      settings:
        releaseChannel: LTS
        ...
    
  11. Включите модуль chrony:

    d8 system module enable chrony
    
  12. Выполните очистку:

    d8 k delete ngc containerd-cse-config.sh cse-set-sha-images.sh
    d8 k delete pod cse-image --ignore-not-found
    d8 k apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: NodeGroupConfiguration
    metadata:
      name: del-temp-config.sh
    spec:
      nodeGroups:
      - '*'
      bundles:
      - '*'
      weight: 90
      content: |
        rm -f /etc/containerd/conf.d/cse-registry.toml /etc/containerd/conf.d/cse-sandbox.toml
    EOF
    d8 k delete ngc del-temp-config.sh
    

    Дождитесь синхронизации сервиса bashible (значение в колонке UPTODATE у NodeGroup должно совпадать с NODES):

    d8 k get ng -o custom-columns=NAME:.metadata.name,NODES:.status.nodes,READY:.status.ready,UPTODATE:.status.upToDate
    

    В логе bashible должно быть Configuration is in sync, nothing to do:

    journalctl -u bashible -n 5
    

Дополнительные ресурсы