Utiliser un datastore Cassandra externe

Cet article explique comment connecter un environnement d'exécution Apigee hybrid à un datastore Cassandra dans un autre cluster Kubernetes. Dans cette configuration, le cluster d'exécution ne comporte aucun pod Cassandra. Le nom de cette configuration est le mode external datastore (magasin de données externe).

Topologie à deux clusters

Le mode datastore externe utilise deux clusters Kubernetes :

  • Le cluster Cassandra exécute l'anneau Cassandra. Il n'exécute pas les composants d'exécution hybrides.
  • Le cluster d'exécution exécute les composants d'exécution hybrides, mais il ne comporte aucun pod Cassandra. Les composants d'exécution se connectent à l'anneau Cassandra du cluster Cassandra via le réseau.

L'opérateur Apigee s'exécute dans les deux clusters. Vous installez cert-manager, les définitions de ressources personnalisées (CRD) Apigee et le graphique apigee-operator dans chaque cluster. Le tableau suivant indique les composants de chaque cluster :

Composant Cluster Cassandra Cluster d'exécution
cert-manager Oui Oui
CRD Apigee et chart apigee-operator Oui Oui
Graphique apigee-datastore Oui, avec les pods Cassandra Oui, avec replicaCount: 0 et sans pods Cassandra
Tous les autres graphiques hybrides, tels que apigee-telemetry, apigee-redis, apigee-ingress-manager, apigee-org, apigee-env et apigee-virtualhost Non Oui

L'opérateur Apigee effectue une tâche différente dans chaque cluster :

  • Dans le cluster Cassandra, l'opérateur crée les pods Cassandra. Il gère également le cycle de vie de Cassandra, par exemple lorsque vous mettez à l'échelle l'anneau.
  • Dans le cluster d'exécution, l'opérateur ne crée pas de pods Cassandra. Il crée un service sans adresse IP de cluster et un objet Endpoints qui pointent vers l'anneau Cassandra du cluster Cassandra. Si vous activez la synchronisation dynamique des points de terminaison, l'opérateur du cluster d'exécution lit également les points de terminaison Cassandra à partir du cluster Cassandra.

Vue d'ensemble de la configuration

Suivez les étapes ci-dessous dans l'ordre. L'ordre est important. L'autorité de certification (AC) du certificat partagé doit se trouver dans le cluster d'exécution avant que celui-ci n'émette des certificats. Pour en savoir plus, consultez Partager l'autorité de certification Apigee avant d'installer l'opérateur.

  1. Dans le cluster Cassandra, installez cert-manager, les CRD Apigee, le chart apigee-operator et le chart apigee-datastore.
  2. Assurez-vous que les pods Cassandra du cluster Cassandra sont prêts.
  3. Dans le cluster d'exécution, installez cert-manager.
  4. Copiez le secret apigee-ca du cluster Cassandra vers le cluster d'exécution. Effectuez cette étape avant d'installer le graphique apigee-operator dans le cluster d'exécution.
  5. Dans le cluster d'exécution, installez les composants d'exécution hybride. Utilisez les remplacements de datastore externe pour le graphique apigee-datastore. Utilisez les mêmes identifiants Cassandra que dans le cluster Cassandra.
  6. (Recommandé) Activez la synchronisation dynamique des points de terminaison.
  7. Vérifiez la connexion.

Pour connaître la procédure d'installation de chaque graphique, consultez Installer Apigee hybrid à l'aide de Helm.

Avant de commencer

Assurez-vous que votre environnement répond aux exigences suivantes :

  • Connexion réseau à Cassandra. Le cluster d'exécution doit se connecter aux pods Cassandra sur le port TCP 9042. Placez les deux clusters dans un VPC partagé ou dans des réseaux avec une connexion privée entre eux.
  • Une seule région. Placez les deux clusters dans la même région. Le délai aller-retour entre les clusters s'ajoute à la latence de chaque requête d'exécution.
  • cert-manager dans les deux clusters. Dans chaque cluster, cert-manager émet les certificats pour la connexion mTLS entre l'exécution et Cassandra. Installez cert-manager dans le cluster Cassandra et dans le cluster d'exécution.
  • Un itinéraire vers chaque pod Cassandra. Le pilote client Cassandra se connecte directement à chaque pod Cassandra. Le cluster d'exécution doit se connecter à l'adresse IP de chaque pod Cassandra, et pas seulement à une seule adresse. Un équilibreur de charge ou une adresse IP virtuelle unique devant l'anneau ne répondent pas à cette exigence.
  • Connexion réseau au serveur d'API Kubernetes. Cette exigence ne s'applique que si vous utilisez la synchronisation dynamique des points de terminaison. Le cluster d'exécution doit se connecter au serveur d'API Kubernetes du cluster Cassandra.

Partager l'autorité de certification Apigee avant d'installer l'opérateur

Installez cert-manager dans le cluster d'exécution. Copiez ensuite le secret de l'autorité de certification du cluster Cassandra vers le cluster d'exécution :

kubectl --context CASSANDRA_CLUSTER -n cert-manager get secret apigee-ca -o yaml \
  | grep -v -E '^\s+(resourceVersion|uid|creationTimestamp|selfLink):' \
  | kubectl --context RUNTIME_CLUSTER -n cert-manager apply -f -

Remplacez les éléments suivants :

  • CASSANDRA_CLUSTER : contexte kubectl du cluster Cassandra.
  • RUNTIME_CLUSTER : contexte kubectl du cluster d'exécution.

La commande grep supprime les champs de métadonnées appartenant au cluster Cassandra. Le serveur d'API Kubernetes ne crée pas d'objet avec une valeur resourceVersion.

Les installations multirégionales utilisent le même principe d'autorité de certification partagée. Pour une étape de copie similaire, consultez Effectuer une rotation du certificat CA racine. Pour la configuration mTLS de Cassandra, consultez Configurer l'authentification pour Cassandra.

Utiliser les mêmes identifiants Cassandra dans les deux clusters

Utilisez l'une des méthodes suivantes dans les fichiers de remplacement des deux clusters :

  • Définissez les mêmes noms d'utilisateur et mots de passe dans cassandra.auth : default, admin, ddl, dml, jmx et jolokia.
  • Définissez cassandra.auth.secret. Dans chaque cluster, le secret doit contenir les mêmes utilisateurs et mots de passe. Consultez Créer le secret.
  • Définissez cassandra.auth.secretProviderClass sur une SecretProviderClass qui lit le même magasin de secrets. Consultez Stocker des secrets Cassandra dans Hashicorp Vault.

Vous ne copiez pas le secret des identifiants à partir du cluster Cassandra. Le graphique du cluster d'exécution crée le secret à partir de vos remplacements. Pour trouver un échec d'authentification, consultez Vérifier la connexion.

Configurer le datastore externe

Dans le cluster d'exécution, le graphique apigee-datastore ne doit pas créer de pods Cassandra. Il doit pointer vers l'anneau Cassandra du cluster Cassandra. Ajoutez les paramètres cassandra suivants au fichier de remplacement du cluster d'exécution :

cassandra:
  # No Cassandra pods in the runtime cluster.
  replicaCount: 0
  properties:
    # A comma-separated list of the Cassandra pod IP addresses.
    externalHost: "CASSANDRA_IP_ADDRESSES"
  storage:
    # Required, even with replicaCount: 0.
    storageSize: "10Gi"

Où :

  • CASSANDRA_IP_ADDRESSES est une liste d'adresses IP des pods Cassandra dans le cluster Cassandra, séparées par des virgules. Par exemple : 10.0.0.1:9042,10.0.0.2:9042,10.0.0.3:9042. Le suffixe :9042 est facultatif. Pour obtenir la liste, exécutez la commande suivante :
    kubectl --context CASSANDRA_CLUSTER -n APIGEE_NAMESPACE get pods -l app=apigee-cassandra \
      -o jsonpath='{.items[*].status.podIP}' | tr ' ' ','
  • APIGEE_NAMESPACE est votre espace de noms Apigee. La valeur par défaut est apigee.
  • replicaCount: 0 indique à l'opérateur de ne créer aucun pod Cassandra dans le cluster d'exécution. L'opérateur crée un service sans adresse IP de cluster et un objet Endpoints qui pointent vers les adresses externalHost.
  • cassandra.properties.externalHost est une liste d'adresses IP Cassandra séparées par une virgule. Chaque adresse peut comporter un suffixe :port, mais l'opérateur ignore le port et utilise toujours le port 9042. L'opérateur n'accepte que les adresses IP. Il ignore les noms d'hôte et les noms DNS, et écrit un avertissement dans son journal pour chaque entrée ignorée.
  • cassandra.storage.storageSize est obligatoire, mais le cluster d'exécution ne crée pas de PersistentVolumes pour Cassandra. Le webhook de validation ApigeeDatastore vérifie toujours storageSize. Utilisez une quantité valide, par exemple 10Gi.

L'adresse IP d'un pod change lorsque vous mettez à l'échelle l'anneau et lorsque Kubernetes replanifie un pod. La liste dans externalHost devient alors incorrecte. Nous vous recommandons donc d'utiliser la synchronisation dynamique des points de terminaison. La synchronisation dynamique des points de terminaison permet de maintenir à jour automatiquement la liste des adresses IP des pods Cassandra. N'utilisez externalHost seul que pour une installation simple ou pour la première configuration.

Maintenir les points de terminaison à jour grâce à la synchronisation dynamique

Avec externalHost uniquement, vous devez modifier vos remplacements chaque fois que l'anneau Cassandra change. La synchronisation dynamique des points de terminaison supprime cette étape manuelle. L'opérateur du cluster d'exécution lit les points de terminaison Cassandra prêts à l'emploi à partir du cluster Cassandra à intervalles réguliers. Il copie ensuite ces points de terminaison dans l'objet "Endpoints" du cluster d'exécution.

Nous vous recommandons de synchroniser les points de terminaison de manière dynamique. Les adresses IP des pods changent chaque fois que vous mettez à l'échelle l'anneau ou que Kubernetes replanifie un pod. La synchronisation dynamique des points de terminaison lit les adresses IP des pods prêts du service Cassandra sans adresse IP de cluster. Ainsi, l'objet Endpoints du cluster d'exécution contient toujours les adresses IP actuelles des pods Cassandra.

Avec la synchronisation dynamique des points de terminaison, externalHost reste nécessaire. L'opérateur l'utilise dans les deux conditions suivantes :

  • Avant la première lecture réussie à partir du cluster Cassandra.
  • Lorsqu'une lecture à partir du cluster Cassandra échoue et qu'il n'y a pas de points de terminaison à partir d'une lecture réussie précédente.

Si une lecture échoue et qu'il existe des points de terminaison provenant d'une lecture précédente réussie, l'opérateur conserve ces points de terminaison. L'exécution conserve sa connexion à Cassandra.

Pour activer la synchronisation dynamique des points de terminaison, ajoutez le bloc externalEndpointsSync au fichier de remplacement du cluster d'exécution :

cassandra:
  replicaCount: 0
  properties:
    # The first endpoints, and the fallback if a read fails.
    externalHost: "CASSANDRA_IP_ADDRESSES"
    externalEndpointsSync:
      # A secret in the runtime cluster. Its "kubeconfig" key holds the
      # kubeconfig for the Cassandra cluster.
      secretRef: apigee-remote-cass-kubeconfig
      # The namespace of the Cassandra headless Service in the Cassandra cluster.
      namespace: apigee
      # The Cassandra headless Service in the Cassandra cluster.
      serviceName: apigee-cassandra-default
      # The interval between reads, in seconds. The default is 30.
      intervalSeconds: 30
  storage:
    storageSize: "10Gi"

Créer un compte de service en lecture seule dans le cluster Cassandra

L'opérateur du cluster d'exécution utilise un fichier kubeconfig pour se connecter au cluster Cassandra. Ce fichier kubeconfig doit utiliser un compte de service en lecture seule avec le moindre privilège. Ce compte de service ne peut lire que les points de terminaison Cassandra. Il ne peut pas modifier les ressources du cluster Cassandra.

Dans le cluster Cassandra, créez les ressources suivantes :

  • Un ServiceAccount, par exemple apigee-endpoint-reader.
  • Un rôle et une liaison de rôle dans l'espace de noms Cassandra. Ce rôle n'accorde que les verbes get, list et watch sur le cœur endpoints. N'utilisez pas d'autres verbes, comme create, update, patch ou delete. Ne donnez pas accès à d'autres ressources.
  • Secret de jeton à longue durée de vie pour le compte de service.

Créez ensuite un fichier kubeconfig pour le serveur d'API Kubernetes du cluster Cassandra. Ce fichier kubeconfig doit utiliser le jeton du compte de service. Dans le cluster d'exécution, créez un secret avec le nom que vous avez défini dans externalEndpointsSync.secretRef. Placez le fichier kubeconfig dans la clé kubeconfig :

kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE create secret generic \
  apigee-remote-cass-kubeconfig --from-file=kubeconfig=READER_KUBECONFIG_FILE

Remplacez READER_KUBECONFIG_FILE par le chemin d'accès au fichier kubeconfig pour le compte de service en lecture seule.

Le fichier kubeconfig contient un jeton de longue durée. Conservez ce code secret aussi précieusement que vos autres identifiants.

Surveiller la synchronisation des points de terminaison dynamiques

Si une lecture à partir du cluster Cassandra échoue, le runtime conserve sa connexion. Toutefois, les points de terminaison du cluster d'exécution ne changent pas tant qu'une lecture n'a pas de nouveau réussi. Surveillez la synchronisation afin de détecter un échec persistant avant que l'anneau Cassandra ne change.

L'opérateur du cluster d'exécution fournit les signaux suivants :

  • Condition EndpointSyncDegraded dans l'état de la ressource ApigeeDatastore. L'état devient True après trois échecs de lecture consécutifs. La raison est RemoteReadFailed ou NoReadyRemoteEndpoints. Une fois la lecture effectuée, l'état devient False avec la raison SyncSucceeded.
  • Métrique external_endpoint_sync_last_success_timestamp. Cette métrique correspond à l'heure de la dernière lecture réussie, en secondes Unix.
  • Métrique external_endpoint_sync_failures_total. Cette métrique comptabilise les lectures ayant échoué.

Les deux métriques comportent les libellés namespace et name de la ressource ApigeeDatastore. L'opérateur les affiche sur son point de terminaison de métriques.

Pour afficher la condition, exécutez la commande suivante :

kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE get apigeedatastore default \
  -o jsonpath='{.status.conditions}'

Nous vous recommandons de configurer une alerte pour la condition EndpointSyncDegraded. L'état ApigeeDatastore maintient la condition lorsque l'opérateur redémarre. Seule une lecture réussie définit la condition sur False.

Si vous utilisez également une alerte sur la métrique, envoyez une alerte lorsque l'une de ces deux expressions est vraie :

  • time() - external_endpoint_sync_last_success_timestamp > 300
  • absent(external_endpoint_sync_last_success_timestamp)

L'opérateur ne définit la métrique qu'après une lecture réussie. Si l'opérateur redémarre alors que les lectures échouent, la métrique est absente. La première expression ne correspond pas, et seule la seconde envoie l'alerte.

Vérifier la connexion

Après avoir installé les composants du runtime, effectuez les vérifications suivantes dans le cluster de runtime :

  1. Assurez-vous que le cluster d'exécution ne comporte aucun pod Cassandra :

    kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE get pods -l app=apigee-cassandra

    Le résultat est No resources found.

  2. Assurez-vous que l'objet Endpoints pointe vers l'anneau Cassandra :

    kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE get endpoints apigee-cassandra-default

    La colonne ENDPOINTS affiche les adresses IP Cassandra. Si vous utilisez la synchronisation dynamique des points de terminaison, il s'agit des adresses IP des pods Cassandra prêts à l'emploi dans le cluster Cassandra.

  3. Assurez-vous que les tâches de configuration de Cassandra sont terminées :

    kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE get jobs \
      | grep -E 'apigee-cassandra-(schema|user)-setup'

    La colonne COMPLETIONS affiche 1/1 pour chaque job. Si un job ne se termine pas, examinez son journal pour détecter les erreurs d'authentification. Assurez-vous ensuite que les deux clusters utilisent les mêmes identifiants Cassandra.

Faire évoluer l'anneau Cassandra

L'opérateur Apigee du cluster Cassandra est propriétaire du cycle de vie de Cassandra. Faites évoluer Cassandra dans le cluster Cassandra. Vous ne pouvez pas effectuer un scaling de Cassandra à partir du cluster d'exécution.

Respectez les mêmes règles que pour un anneau Cassandra dans le cluster d'exécution :

  • Faites évoluer Cassandra par multiples de trois. Cela permet de maintenir l'équilibre de l'anneau sur trois zones de disponibilité.
  • Avant d'augmenter le nombre de pods, assurez-vous que le cluster Cassandra dispose d'une capacité de nœuds suffisante.
  • Si vous n'utilisez pas la synchronisation dynamique des points de terminaison, mettez à jour externalHost après chaque opération de scaling.

Pour en savoir plus, consultez Scaling de Cassandra.

Étapes suivantes