Accéder à des registres privés avec des certificats CA privés


Cette page explique comment autoriser les charges de travail exécutées dans Google Kubernetes Engine (GKE) à accéder à des registres d'images privés à l'aide de la clé publique de l'autorité de certification (CA) ayant émis le certificat pour le registre.

Fonctionnement

Vous stockez la clé publique de l'autorité de certification utilisée pour émettre des certificats pour vos registres privés dans Secret Manager et configurez les noms de domaine complets (FQDN) des registres qui utilisent cette clé publique pour la validation des certificats. GKE récupère automatiquement la clé et met à jour la configuration du registre de l'environnement d'exécution du conteneur lors de l'amorçage des nœuds. Lorsque vous déployez une charge de travail qui utilise une image de conteneur de votre registre privé, les étapes suivantes se produisent:

  1. Le kubelet du nœud tente d'extraire l'image du registre privé.
  2. Le registre présente un certificat TLS côté serveur.
  3. L'environnement d'exécution du conteneur valide le certificat du registre de manière cryptographique et s'assure que le nom de domaine complet correspond à celui que vous avez spécifié.
  4. Si la validation réussit, GKE extrait l'image et planifie votre charge de travail.

Avantages

Cette méthode d'accès aux registres privés offre les avantages suivants:

  1. Amélioration de la fiabilité de la configuration de l'environnement d'exécution des conteneurs: l'utilisation de méthodes telles que des DaemonSets pour définir la configuration containerd entraîne un risque de condition de concurrence, où d'autres DaemonSets peuvent s'exécuter avant votre DaemonSet de configuration.
  2. Réduire les failles aux attaques par élévation des privilèges: vous n'avez plus besoin d'exécuter des DaemonSets privilégiés qui modifient la configuration de l'environnement d'exécution des conteneurs.
  3. Réduction des frais de gestion: Secret Manager vous permet de stocker les clés publiques CA dans un emplacement central, de gérer l'accès aux clés à l'aide d'IAM ; et d'implémenter le contrôle des versions et les annotations. Pour en savoir plus, consultez la présentation du produit Secret Manager.
  4. Amélioration de la possibilité de réaliser des audits: Cloud Logging collecte déjà les journaux, y compris lorsque des certificats sont ajoutés à un cluster et lorsque les nœuds GKE extraient des images.

Tarification

Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :

  • GKE
  • Secret Manager
  • Logging : GKE génère des journaux d'audit pour les activités d'administration et, si cette option est activée, des journaux d'audit pour l'accès aux données pour cette fonctionnalité. Pour en savoir plus sur les différents types de journaux d'audit, consultez la page Journaux d'audit GKE.

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût.

Avant de commencer

Avant de commencer, effectuez les tâches suivantes :

  • Activez l'API Google Kubernetes Engine.
  • Activer l'API Google Kubernetes Engine
  • Si vous souhaitez utiliser Google Cloud CLI pour cette tâche, installez puis initialisez gcloud CLI. Si vous avez déjà installé gcloud CLI, assurez-vous de disposer de la dernière version en exécutant la commande gcloud components update.
  • Activez l'API Secret Manager

    Activer l'API

  • Vous devez déjà disposer d'un registre privé et de certificats CA privés pour accéder au registre. Ce guide ne couvre pas la configuration d'un registre privé ni la création de certificats.

Conditions requises

Pour utiliser des clés publiques de CA privée afin d'accéder à des registres privés, vous devez répondre aux exigences suivantes:

  • Vos clusters doivent utiliser GKE version 1.27.3-gke.1700 ou ultérieure.
  • Vous devez utiliser une image de nœud Container-Optimized OS avec containerd, qui est la valeur par défaut pour tous les clusters GKE. Les images de nœuds Ubuntu avec containerd ne sont pas acceptées. Les images de nœuds Windows Server ne sont pas acceptées.
  • Vos pools de nœuds doivent disposer du niveau d'accès cloud-platform pour que vos nœuds puissent télécharger les certificats. Pour en savoir plus, consultez la section Niveaux d'accès par défaut dans GKE. Ce document explique comment définir le niveau d'accès lorsque vous créez un cluster ou un pool de nœuds.

Limites

Tenez compte des limites suivantes :

  • Vous ne pouvez pas utiliser de certificats CA privés dans les images de nœuds Ubuntu.
  • Vous ne pouvez pas utiliser de certificats CA privés dans les nœuds Windows Server.
  • Chaque cluster accepte jusqu'à cinq certificats CA privés pour les registres privés.
  • Chaque certificat peut comporter jusqu'à 25 noms de domaine complets (FQDN).
  • Chaque domaine ne peut être utilisé que dans un seul fichier de certificat. Toutefois, les groupes de certificats sont compatibles.
  • Les certificats doivent être encodés au format PEM.
  • Le serveur n'effectue pas automatiquement la rotation des certificats. Pour en savoir plus, consultez la section Effectuer une rotation de vos certificats CA privés.
  • Les FQDN présentent les limites suivantes :
    • La longueur maximale du FQDN est de 255 caractères, caractères spéciaux inclus.
    • Les FQDN ne peuvent contenir que des lettres, des chiffres et des tirets (-).
    • Punycode n'est pas accepté.
    • Les caractères génériques ne sont pas acceptés.

Migrer à partir de DaemonSets de configuration

Dans les clusters GKE Standard, vous pouvez déployer des DaemonSets privilégiés pour modifier la configuration de l'environnement d'exécution de vos conteneurs. Cette méthode modifie directement la configuration containerd sur chaque nœud.

Si vous utilisez des DaemonSets privilégiés pour configurer l'accès à des registres privés, tenez compte des points suivants avant d'utiliser ce document:

  • Le stockage de clés publiques d'autorités de certification privées dans Secret Manager ne configure que l'access aux registres privés. Les autres configurations liées au registre ne sont pas compatibles.
  • L'activation de cette fonctionnalité oblige votre cluster à utiliser le modèle de configuration de chemin d'accès à l'hôte CRI de containerd, qui est incompatible avec le modèle de configuration précédent. Si vous avez des DaemonSets qui modifient la configuration de l'hôte containerd, par exemple pour des registres privés, des miroirs ou des proxys non sécurisés, mettez-les à jour pour utiliser le modèle de chemin d'accès à l'hôte CRI.

    Pour connaître les champs disponibles dans le modèle de chemin d'accès à l'hôte CRI, consultez la section Configuration du registre dans le dépôt GitHub containerd.

Lorsque vous activez cette fonctionnalité, GKE applique le modèle de configuration de chemin d'accès à l'hôte CRI aux nouveaux nœuds du cluster. Les nœuds existants continuent à utiliser le modèle de configuration précédent jusqu'à ce qu'ils soient recréés lors d'événements tels que des mises à niveau.

Mettre à jour les objets DaemonSet pour qu'ils soient compatibles avec les deux modèles de configuration

Pour réduire le risque que vos DaemonSets de configuration ne fonctionnent pas sur les nœuds qui utilisent un modèle de configuration spécifique, assurez-vous qu'ils utilisent de manière conditionnelle un modèle de configuration spécifique en fonction des fichiers de configuration containerd sur le nœud. Pour obtenir un exemple de DaemonSet qui met en œuvre cette logique conditionnelle, consultez le fichier manifeste insecure-registry-config.yaml dans le dépôt GitHub GoogleCloudPlatform/k8s-node-tools.

Stocker vos clés publiques CA dans Secret Manager

Stockez les clés publiques de vos autorités de certification privées qui émettent vos certificats de registre privé en tant que secrets dans Secret Manager. Pour obtenir des instructions, consultez la section Créer un secret de la documentation de Secret Manager.

Configurer l'accès à Secret Manager depuis GKE

Pour vous assurer que le compte de service IAM du cluster dispose des autorisations nécessaires pour extraire des secrets de Secret Manager, demandez à votre administrateur d'accorder au compte de service IAM du cluster les rôles IAM suivants sur le secret:

Pour en savoir plus sur l'attribution de rôles, consultez la section Gérer les accès.

Ces rôles prédéfinis contiennent les autorisations requises pour extraire les secrets de Secret Manager. Pour connaître les autorisations exactes requises, développez la section Autorisations requises :

Autorisations requises

Les autorisations suivantes sont requises pour extraire des secrets de Secret Manager:

  • resourcemanager.projects.get
  • resourcemanager.projects.list
  • secretmanager.secrets.get
  • secretmanager.secrets.list
  • secretmanager.versions.get
  • secretmanager.versions.list
  • secretmanager.versions.access

Votre administrateur peut également attribuer ces autorisations au compte de service IAM du cluster avec des rôles personnalisés ou d'autres rôles prédéfinis.

Si vous n'avez pas associé de compte de service IAM personnalisé à votre cluster ou à votre pool de nœuds (ce que nous recommandons), le cluster utilise le compte de service Compute Engine par défaut. Si possible, nous vous recommandons de configurer vos clusters et vos pools de nœuds avec un compte de service IAM doté de privilèges minimaux. Pour obtenir des instructions, consultez la section Utiliser le principe du moindre privilège pour les comptes de service.

Créer un fichier de configuration d'exécution

Pour autoriser l'utilisation de certificats CA privés pour des registres privés dans GKE, vous devez créer un fichier YAML pour modifier la configuration containerd.

  1. Obtenez votre numéro de projet Google Cloud :

    gcloud projects describe PROJECT_ID \
        --format="value(projectNumber)"
    

    Le résultat est le numéro de votre projet.

  2. Enregistrez la configuration suivante sous containerd-configuration.yaml :

    privateRegistryAccessConfig:
    enabled: true
    certificateAuthorityDomainConfig:
      - gcpSecretManagerCertificateConfig:
          secretURI: "projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/SECRET_VERSION
        fqdns:
          - "FQDN1"
          - "FQDN2"
    

    Remplacez les éléments suivants :

    • PROJECT_NUMBER: numéro de projet que vous avez obtenu à l'étape précédente.
    • SECRET_VERSION: numéro de version de votre secret dans Secret Manager. Vous pouvez éventuellement utiliser un alias de version, mais nous vous recommandons d'utiliser le numéro de version afin d'éviter toute complexité de gestion.
    • FQDN1, FQDN2: noms de domaine complets de vos registres privés. Vous pouvez également utiliser une adresse IPv4 si un certificat a été émis pour cette adresse, mais nous ne le recommandons pas.

Pour obtenir une description de ces champs, consultez la section privateRegistryAccessConfig dans le tableau des options de configuration disponibles pour containerd.

Appliquer la configuration containerd aux nouveaux clusters

Cette section explique comment appliquer un fichier de configuration containerd lorsque vous créez un cluster GKE.

Exécutez la commande ci-dessous.

gcloud container clusters create-auto CLUSTER_NAME \
    --location=LOCATION \
    --scopes="cloud-platform" \
    --containerd-config-from-file="PATH_TO_CONFIG_FILE"

Remplacez les éléments suivants :

  • CLUSTER_NAME : nom de votre nouveau cluster
  • LOCATION : emplacement Compute Engine du nouveau cluster.
  • PATH_TO_CONFIG_FILE: chemin d'accès au fichier de configuration que vous avez créé, par exemple ~/containerd-configuration.yaml.

Vous pouvez activer la configuration de registre privé sur les nouveaux clusters Standard en exécutant la commande gcloud container clusters create avec les mêmes options.

Appliquer la configuration containerd aux clusters existants

Cette section vous explique comment appliquer une configuration containerd à des clusters et à des nœuds existants.

Vérifier les niveaux d'accès

Les clusters existants doivent disposer du niveau d'accès cloud-platform pour utiliser cette fonctionnalité. Cette section explique comment vérifier vos niveaux d'accès et mettre à jour un cluster existant avec un fichier de configuration de registre privé nouveau ou modifié.

Pour en savoir plus sur les niveaux d'accès par défaut dans les nouveaux clusters, consultez la section Niveaux d'accès dans GKE.

Vérifier les niveaux d'accès à Autopilot

Exécutez la commande ci-dessous.

gcloud container clusters describe CLUSTER_NAME \
    --location=LOCATION \
    --flatten=nodeConfig \
    --format='csv[delimiter="\\n",no-heading](oauthScopes)'

Si votre cluster ne dispose pas du niveau d'accès https://www.googleapis.com/auth/cloud-platform, créez un cluster avec ce niveau d'accès.

Vérifier les niveaux d'accès standards

Pour vérifier les niveaux d'accès à votre cluster standard, vérifiez un pool de nœuds:

gcloud container node-pools describe NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=LOCATION \
    --flatten=nodeConfig \
    --format='csv[delimiter="\\n",no-heading](oauthScopes)'

Remplacez NODE_POOL_NAME par le nom du pool de nœuds.

Si votre cluster ne dispose pas du niveau d'accès https://www.googleapis.com/auth/cloud-platform, créez un pool de nœuds doté du niveau d'accès cloud-platform et supprimez le pool de nœuds existant.

Mettre à jour le cluster pour utiliser votre fichier de configuration

Exécutez la commande ci-dessous.

gcloud container clusters update CLUSTER_NAME \
    --location=LOCATION \
    --containerd-config-from-file="PATH_TO_CONFIG_FILE"

Recréer des nœuds dans des clusters standards

Si votre cluster standard n'utilise pas les mises à niveau automatiques, vous devez recréer manuellement vos pools de nœuds pour appliquer la nouvelle configuration. Pour déclencher une recréation manuelle des nœuds, mettez à niveau votre cluster vers la version GKE qu'il utilise déjà.

gcloud container clusters upgrade CLUSTER_NAME \
    --location=LOCATION \
    --cluster-version=VERSION

Remplacez VERSION par la même version de correctifs de GKE que celle utilisée par le cluster.

Vérifier que votre cluster peut accéder au registre privé

Exécutez la commande ci-dessous.

gcloud container clusters describe CLUSTER_NAME \
    --location=LOCATION \
    --flatten="nodePoolDefaults.nodeConfigDefaults.containerdConfig"

Le résultat ressemble à ce qui suit :

    containerdConfig:
      privateRegistryAccessConfig:
        certificateAuthorityDomainConfig:
        - fqdns:
          - 203.0.113.105
          gcpSecretManagerCertificateConfig:
            secretUri: projects/123456789012/secrets/example-secret-name/versions/1
        enabled: true

Déployer une charge de travail qui accède à une image privée

Dans cette section, vous allez déployer un pod statique qui référence une image de votre registre privé.

  1. Enregistrez le manifeste suivant sous le nom private-registry-pod.yaml :

    apiVersion: v1
    kind: Pod
    metadata:
      name: private-registry-pod
    spec:
      containers:
      - name: private-image
        image: IMAGE_NAME
    

    Remplacez IMAGE_NAME par le nom de votre image privée.

  2. Déployez le pod :

    kubectl create -f private-registry-pod.yaml
    

Effectuer une rotation de vos certificats CA privés

Secret Manager et GKE ne peuvent pas effectuer de rotation automatique des certificats CA privés dans Secret Manager. Pour effectuer une rotation des certificats, procédez comme suit : Ces étapes nécessitent que vous recréiez les nœuds existants deux fois. Nous vous recommandons d'effectuer des rotations des certificats pendant les temps d'arrêt planifiés afin de minimiser l'impact des interruptions de la charge de travail.

  1. Créez un groupe de certificats encodé au format PEM contenant à la fois l'ancien et le nouveau certificat.
  2. Ajoutez le groupe en tant que nouvelle version de secret dans Secret Manager.
  3. Mettez à jour le champ secretURI du fichier de configuration de l'environnement d'exécution avec le nouveau numéro de version du secret.
  4. Mettez à jour votre cluster de sorte qu'il utilise la nouvelle version de secret.
  5. Obtenez l'horodatage de l'opération de mise à jour:

    gcloud container operations list \
        --filter="operationType ~ UPDATE_CLUSTER AND targetLink ~ CLUSTER_NAME" \
        --sort-by=startTime \
        --limit=1 \
        --format='value(endTime)'
    

    Le résultat ressemble à ce qui suit :

    2024-01-31T09:27:30.864308964Z
    
  6. Recherchez les nœuds créés avant la fin de l'opération de mise à jour:

    kubectl get nodes -o json | jq ".items[] |
    select(.metadata.creationTimestamp | fromdateiso8601 < $(date -d
    CLUSTER_UPDATE_TIMESTAMP +%s)) | .metadata.name"
    

    Remplacez CLUSTER_UPDATE_TIMESTAMP par l'horodatage de l'étape précédente.

    La sortie est une liste de noms de nœuds qui n'ont pas été recréés avec la configuration mise à jour. Lorsque le résultat est vide, passez à l'étape suivante.

  7. Créez une nouvelle version de votre secret dans Secret Manager uniquement avec le nouveau certificat.

  8. Répétez les étapes précédentes pour mettre à jour votre cluster, obtenir l'horodatage de l'opération et vérifier que vos nœuds utilisent la nouvelle version de secret.

  9. Supprimez l'ancienne version de secret de Secret Manager.

Afficher les journaux d'audit dans Logging

Cette section explique comment utiliser Logging pour vérifier si GKE a installé votre version de secret sur vos nœuds.

  1. Accédez à l'explorateur de journaux dans la console Google Cloud :

    Accéder à l'explorateur de journaux

  2. Spécifiez la requête suivante:

    resource.type="gce_instance"
    textPayload:"Installed certificate \\\"projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/SECRET_VERSION\\\""
    

    Si l'installation de votre certificat a réussi, le résultat ressemble à ce qui suit:

    "Installed certificate "projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/SECRET_VERSION""
    

    Si l'installation de votre certificat échoue, le résultat ressemble à ce qui suit:

    "Failed to install certificate "projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/SECRET_VERSION""
    

Bonnes pratiques

Nous vous recommandons de suivre les bonnes pratiques suivantes lorsque vous utilisez cette fonctionnalité:

  • N'utilisez pas d'alias pour les versions de secrets de Secret Manager. Utilisez le numéro de version généré automatiquement pour chaque version de secret. Au fil du temps, un alias peut pointer vers une version de certificat différente, ce qui peut compliquer le suivi des versions spécifiques utilisées par vos charges de travail.
  • Utilisez des intervalles et des exclusions de maintenance pour contrôler à quel moment GKE peut recréer vos nœuds afin d'appliquer des configurations containerd mises à jour.
  • Fournissez un accès aux secrets au niveau du secret, et non au niveau du projet.

Désactiver les options de configuration containerd

Pour supprimer votre configuration personnalisée, procédez comme suit:

  1. Mettez à jour le fichier de configuration pour spécifier enabled: false dans l'élément de configuration que vous souhaitez désactiver et supprimez tous les autres champs de l'élément, comme dans l'exemple suivant:

    privateRegistryAccessConfig:
      enabled: false
  2. Appliquez le fichier de configuration mis à jour au cluster : Pour obtenir des instructions, consultez la page Appliquer la configuration containerd aux clusters existants.

Résoudre les problèmes

Pour connaître les étapes de dépannage, consultez la page Résoudre les problèmes liés à l'environnement d'exécution du conteneur.