• Русский
  • Руководство по миграции Harbor: с версии 2.6.4 на 2.12

    Инструкции по миграции

    В этом руководстве описывается процесс обновления Harbor с версии 2.6.4 до версии 2.12. Учитывая большой разрыв между версиями и необходимость обеспечения стабильности обновления, мы используем подход миграции данных. Преимущества данного подхода:

    1. Избежание сложности обновления через несколько промежуточных версий
    2. Повторное использование данных хранилища реестра для ускорения процесса обновления

    Общий процесс миграции выглядит следующим образом:

    1. Миграция данных Helm charts в хранилище реестра.
    2. Резервное копирование базы данных PostgreSQL и восстановление её в экземпляр PostgreSQL 14.
    3. Остановка старого экземпляра Harbor.
    4. Развёртывание нового экземпляра Harbor с использованием восстановленной базы данных PostgreSQL и оригинального хранилища реестра из старого экземпляра Harbor.

    Миграция данных Helm charts

    Harbor поддерживает два способа хранения данных Helm charts: 1. хранение непосредственно в хранилище реестра Harbor через OCI API; 2. хранение в backend chartmuseum, размещённом в Harbor, через API chartmuseum.

    Начиная с Harbor 2.6, Chartmuseum устарел и был удалён в Harbor 2.8. Если ваш старый экземпляр использует chartmuseum, необходимо мигрировать данные charts в хранилище реестра.

    Требования

    Миграция данных Helm charts

    Инструмент копирует Helm charts, но не удаляет их из Chartmuseum.

    Для миграции данных charts в хранилище реестра выполните:

    export HARBOR_URL=<адрес harbor>
    export HARBOR_USER=<имя пользователя harbor>
    export HARBOR_PASSWORD=<пароль harbor>
    # если harbor использует http, добавьте -plain-http
    # если harbor использует самоподписанный https, добавьте -insecure
    # для получения дополнительных параметров выполните `podman run -ti --rm alaudadockerhub/chartmuseum2oci:v1.1.0-g41baf1e --help`
    podman run -ti --rm alaudadockerhub/chartmuseum2oci:v1.1.0-g41baf1e --url $HARBOR_URL --username $HARBOR_USER --password $HARBOR_PASSWORD

    Ожидаемый вывод:

    2023/06/28 16:17:32 416 Helm charts to migrate from Chartmuseum to OCI
       100% |████████████████████████████████████████████████████████████████████████████████████████████| (416/416, 20 it/min)
    2023/06/28 16:38:14 416 Helm charts successfully migrated from Chartmuseum to OCI

    Если необходимо мигрировать только часть данных, можно отфильтровать данные по проекту согласно документации.

    Для информации о работе с OCI Helm charts обратитесь к следующим документам:

    INFO

    Начиная с Harbor 2.8, поддержка chartmuseum прекращена.

    Если вы хотите продолжать использовать chart-репозитории, управляемые chartmuseum, пожалуйста, свяжитесь с нами для получения поддержки.

    Продолжительность миграции

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

    По результатам тестирования с базой данных размером 7.6 ГБ миграция занимает примерно 18 минут (используется хранилище с производительностью 6000 IOPS на чтение и 2000 IOPS на запись).

    Резервное копирование

    Выполните следующую команду для резервного копирования базы данных pg старого экземпляра с помощью pg_dump:

    export INSTANCE_NAME=<имя экземпляра harbor> INSTANCE_NAMESPACE=<namespace экземпляра harbor>
    
    kubectl -n ${INSTANCE_NAMESPACE} exec -it ${INSTANCE_NAME}-database-0 -- bash
    
    # Выполнить команду резервного копирования
    pg_dump -U postgres -d registry > /tmp/harbor_database.dump
    
    # Скопировать резервную копию на локальную машину
    kubectl -n ${INSTANCE_NAMESPACE} cp ${INSTANCE_NAME}-database-0:/tmp/harbor_database.dump ./harbor_database.dump
    Резервное копирование данных реестра является необязательным

    Данные реестра обычно очень большие, требуют дополнительного места для резервного копирования и занимают много времени, что затрудняет их резервное копирование. Кроме того, при обновлении экземпляра Harbor структура хранилища реестра обычно не меняется, поэтому новый экземпляр может напрямую использовать хранилище старого экземпляра.

    Миграция базы данных

    При миграции Harbor с версии 2.6 на 2.12 меняется версия базы данных — с PostgreSQL 12 на PostgreSQL 14. Поэтому необходимо сначала импортировать резервную копию базы данных старого экземпляра в новую базу данных (PostgreSQL 14). Затем с помощью инструмента миграции данных Harbor выполнить миграцию структуры и данных базы данных в формат, совместимый с Harbor 2.12.

    Требования

    Подготовьте новый экземпляр PostgreSQL версии 14. Резервная копия базы данных Harbor будет восстановлена в этот экземпляр, после чего будет выполнена миграция структуры базы данных.

    Восстановление базы данных

    Импортируйте резервную копию базы данных в базу данных, используемую новым экземпляром. В примере ниже показан процесс импорта с помощью psql. Для конкретных методов импорта обратитесь к документации поставщика базы данных.

    # Создайте новую базу данных для нового экземпляра PostgreSQL.
    # В этом примере имя базы данных — `registry`.
    dropdb -U postgres registry
    createdb -U postgres registry
    
    # Старый экземпляр использует пользователя harbor для подключения к базе данных,
    # но этот пользователь может отсутствовать в новой базе,
    # поэтому необходимо заменить пользователя на существующего в новом экземпляре PostgreSQL.
    # В этом примере используется пользователь `postgres`.
    sed -i 's/OWNER TO harbor/OWNER TO postgres/g' /tmp/harbor_database.dump
    psql -U postgres -d registry -f /tmp/harbor_database.dump
    NOTE

    Из-за несовпадения версий базы данных в процессе импорта могут возникать ошибки, связанные с отсутствием ролей или функций, которые можно игнорировать. Например:

    • ERROR: role "admin" does not exist
    • ERROR: function metric_helpers.pg_stat_statements(boolean) does not exist
    • ERROR: schema "metric_helpers" already exists
    • ERROR: function "get_btree_bloat_approx" already exists with same argument types

    Миграция базы данных

    Данные Harbor 2.6 теперь импортированы в базу данных нового экземпляра. Далее запустите задачу миграции данных для преобразования структуры и данных базы в формат, совместимый с Harbor 2.12.

    Установите параметры подключения к новому экземпляру PostgreSQL, затем создайте задачу для выполнения миграции базы данных:

    export POSTGRESQL_HOST=<хост базы данных>
    export POSTGRESQL_PORT=<порт базы данных>
    export POSTGRESQL_USERNAME=<имя пользователя базы данных>
    export POSTGRESQL_PASSWORD=<пароль базы данных>
    # Установите SSL режим в `require`, если старый экземпляр использует SSL, иначе `disable`.
    export POSTGRESQL_SSLMODE="require"
    export INSTANCE_NAMESPACE=<namespace экземпляра harbor>
    # Официальный образ migrator доступен по адресу `https://hub.docker.com/r/mgle/standalone-db-migrator`,
    # импортируйте его в ваш приватный реестр и укажите переменную окружения MIGRATOR_IMAGE для использования.
    export MIGRATOR_IMAGE=hub-mirrors.alauda.cn/mgle/standalone-db-migrator:v2.12.0
    
    kubectl -n ${INSTANCE_NAMESPACE}  apply -f - << EOF
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: harbor-db-migrate
    spec:
      backoffLimit: 5
      template:
        spec:
          restartPolicy: Never
          containers:
          - name: harbor-migrate
            image: ${MIGRATOR_IMAGE}
            command: ["/harbor/migrate"]
            env:
            - name: POSTGRESQL_HOST
              value: "${POSTGRESQL_HOST}"
            - name: POSTGRESQL_PORT
              value: "${POSTGRESQL_PORT}"
            - name: POSTGRESQL_USERNAME
              value: "${POSTGRESQL_USERNAME}"
            - name: POSTGRESQL_PASSWORD
              value: "${POSTGRESQL_PASSWORD}"
            - name: POSTGRESQL_DATABASE
              value: "registry"
            - name: POSTGRESQL_SSLMODE
              value: "${POSTGRESQL_SSLMODE}"
    EOF

    После завершения задачи можно просмотреть подробный прогресс и результаты миграции в логах задачи:

    2024-12-23T02:43:05Z [INFO] [/cmd/standalone-db-migrator/main.go:53]: Migrating the data to latest schema...
    2024-12-23T02:43:05Z [INFO] [/cmd/standalone-db-migrator/main.go:54]: DB info: postgres://harbor@test-6-database:5432/registry?sslmode=require
    2024-12-23T02:43:05Z [INFO] [/common/dao/base.go:67]: Registering database: type-PostgreSQL host-test-6-database port-5432 database-registry sslmode-"require"
    2024-12-23T02:43:05Z [INFO] [/common/dao/base.go:72]: Register database completed
    2024-12-23T02:43:05Z [INFO] [/common/dao/pgsql.go:135]: Upgrading schema for pgsql ...
    2024-12-23T02:43:05Z [INFO] [/go/pkg/mod/github.com/golang-migrate/migrate/v4@v4.18.1/migrate.go:765]: 100/u 2.7.0_schema (184.508549ms)
    2024-12-23T02:43:05Z [INFO] [/go/pkg/mod/github.com/golang-migrate/migrate/v4@v4.18.1/migrate.go:765]: 110/u 2.8.0_schema (275.019668ms)
    2024-12-23T02:43:05Z [INFO] [/go/pkg/mod/github.com/golang-migrate/migrate/v4@v4.18.1/migrate.go:765]: 111/u 2.8.1_schema (286.508359ms)
    2024-12-23T02:43:05Z [INFO] [/go/pkg/mod/github.com/golang-migrate/migrate/v4@v4.18.1/migrate.go:765]: 120/u 2.9.0_schema (357.027979ms)
    2024-12-23T02:43:05Z [INFO] [/go/pkg/mod/github.com/golang-migrate/migrate/v4@v4.18.1/migrate.go:765]: 130/u 2.10.0_schema (378.349099ms)
    2024-12-23T02:43:05Z [INFO] [/go/pkg/mod/github.com/golang-migrate/migrate/v4@v4.18.1/migrate.go:765]: 140/u 2.11.0_schema (399.407785ms)
    2024-12-23T02:43:05Z [INFO] [/go/pkg/mod/github.com/golang-migrate/migrate/v4@v4.18.1/migrate.go:765]: 150/u 2.12.0_schema (408.831695ms)
    2024-12-23T02:43:05Z [INFO] [/cmd/standalone-db-migrator/main.go:63]: Migration done.  The data schema in DB is now update to date.

    Остановка старого экземпляра Harbor

    Удалите оператор harbor через страницу Operator Hub, затем уменьшите количество реплик старого экземпляра Harbor следующими командами:

    export INSTANCE_NAME=<имя экземпляра harbor> INSTANCE_NAMESPACE=<namespace экземпляра harbor>
    
    kubectl -n ${INSTANCE_NAMESPACE} scale deployment -l release=${INSTANCE_NAME} --replicas=0
    kubectl -n ${INSTANCE_NAMESPACE} scale statefulset -l release=${INSTANCE_NAME} --replicas=0
    kubectl -n ${INSTANCE_NAMESPACE} delete service -l release=${INSTANCE_NAME}
    kubectl -n ${INSTANCE_NAMESPACE} delete ingress -l release=${INSTANCE_NAME}

    Развёртывание нового экземпляра Harbor

    TIP

    Новый экземпляр должен монтировать хранилище оригинального экземпляра, поэтому он должен находиться в том же namespace, что и оригинальный экземпляр.

    Развёртывайте новый экземпляр согласно документации по развёртыванию, обращая внимание на следующие моменты:

    1. Новый экземпляр должен подключаться к мигрированной базе данных PostgreSQL (версия 14)
    2. Не используйте Redis старого экземпляра Harbor, создайте новый
    3. Хранилище реестра должно использовать хранилище старого экземпляра
    4. Метод доступа должен совпадать с методом старого экземпляра, чтобы избежать сбоев в работе после миграции

    Для миграции конфигурации между старым и новым экземплярами обратитесь к следующим разделам.

    Получение конфигурации оригинального экземпляра

    Необходимо получить конфигурацию из оригинального экземпляра и преобразовать её в конфигурацию нового экземпляра:

    export INSTANCE_NAME=<имя экземпляра harbor> INSTANCE_NAMESPACE=<namespace экземпляра harbor>
    
    helm -n ${INSTANCE_NAMESPACE} get values ${INSTANCE_NAME}

    Преобразование конфигурации хранилища реестра

    Если оригинальный экземпляр развёрнут с использованием Host Path хранилища, конфигурация выглядит так:

    # Конфигурация оригинального экземпляра
    persistence:
      hostPath:
        registry:
          host:
            nodeName: <имя узла>
            path: <путь к хранилищу реестра>

    Преобразуйте в конфигурацию нового экземпляра:

    # Конфигурация нового экземпляра
    helmValues:
      persistence:
        enabled: true
        hostPath:
          registry:
            path: <путь к хранилищу реестра>
    
      registry:
        nodeSelector:
          kubernetes.io/hostname: <имя узла>

    Если оригинальный экземпляр развёрнут с использованием StorageClass, имена PVC фиксированы:

    • имя PVC для реестра: <имя старого экземпляра>-harbor-registry

    Используйте старый PVC в новом экземпляре.

    # Конфигурация нового экземпляра
    helmValues:
      persistence:
        enabled: true
        persistentVolumeClaim:
          registry:
            existingClaim: <имя старого экземпляра>-harbor-registry

    Если оригинальный экземпляр развёрнут с использованием PVC, конфигурация выглядит так:

    # Конфигурация оригинального экземпляра
    persistence:
      persistentVolumeClaim:
        registry:
          existingClaim: <имя pvc реестра>
    # Конфигурация нового экземпляра
    helmValues:
      persistence:
        enabled: true
        persistentVolumeClaim:
          registry:
            existingClaim: <имя pvc реестра>

    Преобразование конфигурации метода доступа

    Если оригинальный экземпляр развёрнут с NodePort, установите следующую конфигурацию:

    # Конфигурация нового экземпляра
    helmValues:
      expose:
        type: nodePort
        nodePort:
          name: harbor
          ports:
            http:
              port: 80
              nodePort: <номер node port>
    
      externalURL: http://<ip node port>:<номер node port>

    Если оригинальный экземпляр развёрнут с доменным именем, установите следующую конфигурацию:

    # Конфигурация http нового экземпляра
    helmValues:
      expose:
        type: ingress
        tls:
          enabled: false
        ingress:
          hosts:
            core: <доменное имя>
    
      externalURL: http://<доменное имя>
    # Конфигурация https нового экземпляра
    helmValues:
      expose:
        type: ingress
        tls:
          enabled: true
          certSource: "secret"
          secret:
            secretName: <секрет TLS сертификата>
        ingress:
          hosts:
            core: <доменное имя>
    
      externalURL: https://<доменное имя>

    Проверка

    1. Проверьте статус всех Pods:

      export INSTANCE_NAME=<имя экземпляра harbor> INSTANCE_NAMESPACE=<namespace экземпляра harbor>
      kubectl get pods -n ${INSTANCE_NAMESPACE} -l release=${INSTANCE_NAME}
    2. Убедитесь, что сервис Harbor доступен:

      • Зайдите в веб-интерфейс Harbor, проверьте наличие существующих проектов и образов
      • Проверьте вход в систему через Podman
    3. Проверьте операции push и pull образов и charts:

      • Тестируйте push и pull образов
      • Тестируйте push и pull OCI charts (опционально)
    4. После подтверждения успешной миграции можно вручную удалить старый экземпляр Harbor на странице DevOps Toolchain/Instances/.