How to Remove Apicurio v2

This guide shows you how to move the bundled Keycloak and its MySQL database from the Apicurio Registry v2 release to v3, disable v2, check that v3 authentication still works and delete the migration client.

Type

How-to guide

Goal

Run Apicurio Registry v3 on its own, with Keycloak owned by the v3 release and v2 removed.

Audience

Platform Operator with Helm access to the Axual Streaming release and kubectl exec access to the Keycloak MySQL pods in the kafka namespace.

When to use

Use this guide as the last stage of Upgrade Apicurio Registry from v2 to v3, once v3 has served production for your rollback window.

Prerequisites

Confirm the following before you begin.

Access and permissions required

You need the following access and permissions:

  • Helm access to the Axual Streaming release in the kafka namespace.

  • kubectl exec access to the Keycloak MySQL pods and the MySQL root password, when Step 1 applies.

  • An sr-admin user in the Apicurio realm, to test the login.

  • The client secret of the platform’s apicurio-api Keycloak client.

Tools and versions required

You need the following tools:

  • helm and kubectl

  • curl and jq

Resources that must exist before starting

The following resources must already exist before you start:

Disabling v2 deletes everything the v2 release owns, including the bundled apicurioKeycloakMysql database (realm, users, client secrets, sr-admin and sr-readonly grants). Complete the moves in Steps 1 and 2 that apply to you, and verify v3 authentication, before you disable v2.

After Step 3 there is no v2 to roll back to. Finish your rollback window first; see How to Roll Back the Apicurio v3 Upgrade.

Replace every <VALUE> placeholder and every example.com hostname with your actual value before running a command.

Step 1: Move the bundled Keycloak MySQL database to v3

The chart provides Keycloak as two independent pieces: its database (apicurioKeycloakMysql) and the Keycloak server (apicurioKeycloak). Move each piece from v2 to v3 only if it’s the bundled one; when a piece is externalised, v3 points at the same external instance and you skip that move.

Skip this step if your Keycloak database is externalised (for example Azure Database for MySQL). Neither release owns it, and v3’s Keycloak points at the same database in Step 2.

The bundled apicurioKeycloakMysql belongs to the v2 release, so stand up a v3-owned MySQL and copy the data into it. Don’t disable v2 yet.

  1. Enable a v3-owned MySQL on the v3 release:

    axual-streaming:
      apicurio-registry-v3:
        apicurioKeycloakMysql:
          enabled: true
          auth:
            database: "apicurio-kc-db"
            username: "keycloak"
            # use the same passwords as your existing v2 Keycloak database
  2. Copy the Keycloak data from the v2 database into the v3 database, for example with mysqldump while both MySQL pods are running:

    # Dump the v2 Keycloak database
    kubectl exec -n kafka <v2-mysql-pod> -- \
      mysqldump -u root -p"<root-password>" apicurio-kc-db > apicurio-kc-db.sql
    
    # Restore it into the v3 Keycloak database
    kubectl exec -i -n kafka <v3-mysql-pod> -- \
      mysql -u root -p"<root-password>" apicurio-kc-db < apicurio-kc-db.sql

Step 2: Move the bundled Keycloak to v3

Skip this step if Keycloak is externalised, deployed by a separate chart or release with apicurioKeycloak.enabled: false in the Apicurio chart. Apicurio v2 and v3 both point at the same external Keycloak, so there’s nothing to move; go straight to Step 3.

The bundled apicurioKeycloak belongs to the v2 release, so enable it on the v3 release, pointed at the v3-owned MySQL from Step 1, or at your external database if only the MySQL is externalised:

axual-streaming:
  apicurio-registry-v3:
    apicurioKeycloak:
      enabled: true
      realm: "apicurio"
      args: ['start']
      database:
        vendor: "mysql"
        hostname: "<keycloak-db-hostname>"   # the v3-owned MySQL from Step 1, or your external database
        database: "apicurio-kc-db"
        username: "keycloak"

Apply the change with a helm upgrade, using the same command as in Step 2: Deploy Apicurio v3, then restart the v3 Keycloak pod. Verify you can log in with an sr-admin user and that the realm, clients and role grants are present.

Step 3: Disable Apicurio v2

Only after v3 authentication is verified, disable the v2 registry so you no longer run two registries side by side:

global:
  apicurio:
    enabled: false

Apply the change with the same helm upgrade command.

Step 4: Verify Apicurio v2 is removed

Check that the v2 registry is gone and that v3 still authenticates and serves your schemas.

  1. List the Apicurio pods and ingresses:

    kubectl get pods,ingress -n kafka | grep apicurio

    No pod or ingress from the v2 apicurio-registry chart remains, including the legacy hostname. The v3 pods, whose names contain apicurio-registry-v3, show Running.

  2. Get a token for the platform’s apicurio-api client and count the artifacts on the production hostname:

    TOKEN=$(curl -skS --fail-with-body -X POST \
      "https://<APICURIO_KEYCLOAK_HOST>/auth/realms/<APICURIO_REALM>/protocol/openid-connect/token" \
      -d "grant_type=client_credentials&client_id=apicurio-api&client_secret=<APICURIO_API_CLIENT_SECRET>" \
      | jq -r '.access_token')
    
    curl -skS --fail-with-body \
      "https://apicurio.example.com/apis/registry/v3/search/artifacts?limit=1" \
      -H "Authorization: Bearer $TOKEN" | jq '.count'

    The token request succeeds and the count matches the one you recorded during the migration.

  3. Open https://apicurio.example.com in a browser and log in with an sr-admin user.

Step 5: Delete the migration client

The apicurio-migration client and the migration-admin realm role have no use once v2 is gone. In the Keycloak Admin Console for the Apicurio realm:

  1. Delete the client: Clients > apicurio-migration > Action > Delete.

  2. Delete the role: Realm roles > migration-admin > Action > Delete.