Automatiser la gestion des certificats TLS pour Cloud Service Mesh à l'aide de Certificate Authority Service

Ce tutoriel explique aux opérateurs de plates-formes comment automatiser la gestion des certificats TLS pour la passerelle d'entrée Cloud Service Mesh à l'aide de l'émetteur Certificate Authority Service (Service d'autorité de certification) pour l'outil cert-manager. Les certificats permettent à la passerelle d'entrée d'arrêter le trafic HTTPS, TLS et mTLS provenant des clients de votre cloud privé virtuel (VPC), mais qui se trouvent en dehors du maillage de services. Dans ce tutoriel, nous partons du principe que vous connaissez les concepts de base de Kubernetes et des certificats TLS.

Présentation

Cloud Service Mesh provisionne des certificats TLS pour chaque charge de travail du maillage de services. Ces certificats établissent une communication mTLS (authentification mutuelle TLS) chiffrée entre les charges de travail du maillage de services. L'une des autorités de certification compatibles émet et signe les certificats.

Cependant, Cloud Service Mesh ne provisionne pas automatiquement des certificats sur la passerelle d'entrée pour le trafic entrant dans le maillage de services. Une solution courante consiste à utiliser l'outil Open Source cert-manager pour automatiser la gestion des certificats sur la passerelle d'entrée.

L'outil cert-manager demande des certificats à un émetteur, qui représente une autorité de certification. CA Service est un Service Google Cloud qui vous permet de créer votre propre autorité de certification privée L'outil cert-manager peut demander des certificats à CA Service en utilisant l'émetteur externe Open Source de CA Service.

Une autorité de certification privée peut émettre des certificats TLS qui authentifient et chiffrent le trafic au sein d'un réseau interne. Les passerelles d'entrée Cloud Service Mesh sont souvent définies pour autoriser le trafic entrant provenant de clients situés au sein de votre mais en dehors du maillage de services. Pour le trafic réseau interne, vous pouvez utiliser une autorité de certification privée dans CA Service pour émettre des certificats pour la passerelle d'entrée.

Ce tutoriel décrit comment configurer l'outil cert-manager et l'émetteur CA Service pour automatiser le provisionnement et le renouvellement des certificats TLS pour la passerelle d'entrée. L'outil cert-manager provisionne les certificats en tant que ressources Secret Kubernetes de type TLS. Lorsque l'outil cert-manager renouvelle un certificat, il met à jour la ressource Secret avec un nouveau certificat. La passerelle d'entrée exécute le proxy Envoy et accepte le service de détection de secrets (SDS) d'Envoy. Le service SDS permet à la passerelle d'entrée d'utiliser un nouveau certificat sans qu'un administrateur ne doive redémarrer ou actualiser le processus.

Les proxys side-car qui font partie du maillage peuvent obtenir des certificats TLS à partir de Certificate Authority Service ou Cloud Service Mesh. Dans ce tutoriel, vous allez utiliser CA Service pour les certificats de proxys side-car et de la passerelle d'entrée. Cela vous permet d'utiliser une autorité de certification racine pour tous les certificats TLS.

Le schéma suivant illustre les ressources que vous provisionnez dans ce tutoriel. Vous provisionnez un équilibreur de charge réseau passthrough interne pour la passerelle d'entrée. L'équilibreur de charge réseau passthrough interne n'est pas un proxy. De ce fait, il n'arrête pas les connexions TCP et n'effectue pas de handshake TLS. Au lieu de cela, il achemine les connexions vers les pods du déploiement istio-ingressgateway.

Le secret hello-example-com-credential contient un certificat et une clé privée. La passerelle hello configure les pods du déploiement istio-ingressgateway afin qu'ils effectuent des handshakes TLS à l'aide de ce certificat et de cette clé privée pour les requêtes dont le nom d'hôte est hello.example.com.

Gestion mTLS avec CA Service

Les pods du déploiement google-cas-issuer dans l'espace de noms cert-manager demandent des certificats à l'autorité de certification que vous créez dans CA Service. Vous créez un Liaison de stratégie Identity and Access Management qui autorise les pods ca-service-isser d'emprunter l'identité d'un compte de service Google Fédération d'identité de charge de travail pour GKE Vous autorisez ce compte de service Google à demander des certificats à votre autorité de certification dans CA Service en créant une liaison de stratégie IAM dans votre pool d'autorités de certification.

Objectifs

Coûts

Ce tutoriel utilise les composants facturables suivants de Google Cloud :

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût. Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Une fois que vous avez terminé ce tutoriel, vous pouvez éviter de continuer à payer des frais en supprimant les ressources que vous avez créées. Pour en savoir plus, consultez la section Effectuer un nettoyage.

Avant de commencer

  1. Dans la console Google Cloud, accédez à la page de sélection du projet, puis sélectionnez ou créez un projet.

  2. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  3. Dans la console Google Cloud, accédez à Cloud Shell.

    En bas de la fenêtre de la console Google Cloud, une session Cloud Shell s'ouvre et affiche une invite de ligne de commande. Utilisez Cloud Shell pour exécuter toutes les commandes de ce tutoriel.

  4. Définissez le projet de la console Google Cloud que vous souhaitez utiliser pour ce tutoriel :

    gcloud config set core/project PROJECT_ID
    

    Remplacez PROJECT_ID par l'ID de votre projet Cloud.

    Dans la boîte de dialogue "Autoriser Cloud Shell", cliquez sur Autoriser. En cliquant sur Autoriser, vous autorisez les commandes gcloud que vous exécutez dans Cloud Shell à s'authentifier auprès des API Google à l'aide de vos identifiants utilisateur.

  5. Activez les API Resource Manager, GKE, GKE Hub, Cloud Service Mesh CA et CA Service :

    gcloud services enable \
        cloudresourcemanager.googleapis.com \
        container.googleapis.com \
        gkehub.googleapis.com \
        meshca.googleapis.com \
        privateca.googleapis.com
    

Configurer le service d'autorité de certification

Dans cette section, vous allez créer une autorité de certification racine et deux autorités de certification subordonnées dans CA Service. L'une des autorités de certification subordonnées émet des certificats pour la passerelle d'entrée, et l'autre pour les proxys side-car du maillage.

Pour plus de simplicité, vous utilisez le même projet pour le cluster GKE et les autorités de certification racine et subordonnées dans ce tutoriel. Dans votre propre environnement, vous pouvez utiliser un projet différent pour le cluster GKE et les autorités de certification.

  1. Dans Cloud Shell, créez un pool d'autorités de certification à utiliser pour l'autorité de certification racine :

    gcloud privateca pools create ROOT_CA_POOL \
        --location CA_LOCATION \
        --tier enterprise
    
    • ROOT_CA_POOL est le nom du pool d'autorités de certification. Exemple : root-ca-pool-tutorial.
    • CA_LOCATION est l'emplacement du pool d'autorités de certification. Exemple : us-central1.

    Vous pouvez répertorier les emplacements CA Service disponibles à l'aide de la commande suivante : gcloud privateca locations list

  2. Créez et activez une autorité de certification racine :

    gcloud privateca roots create ROOT_CA \
        --auto-enable \
        --key-algorithm ec-p384-sha384 \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --subject "CN=Example Root CA, O=Example Organization" \
        --use-preset-profile root_unconstrained
    
    • ROOT_CA est le nom à utiliser pour l'autorité de certification racine. Exemple :root-ca-tutorial
  3. Créez un pool d'autorités de certification à utiliser pour l'autorité de certification subordonnée qui émet des certificats pour la passerelle d'entrée :

    gcloud privateca pools create SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --tier devops
    
    • SUBORDINATE_CA_POOL_GATEWAYS est le nom du pool d'autorités de certification. Exemple :subordinate-ca-mtls-pool-gateways-tutorial
  4. Créez et activez l'autorité de certification subordonnée qui émet des certificats pour la passerelle d'entrée :

    gcloud privateca subordinates create SUBORDINATE_CA_GATEWAYS \
        --auto-enable \
        --issuer-location CA_LOCATION \
        --issuer-pool ROOT_CA_POOL \
        --key-algorithm ec-p256-sha256 \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_GATEWAYS \
        --subject "CN=Example Gateway mTLS CA, O=Example Organization" \
        --use-preset-profile subordinate_mtls_pathlen_0
    
    • SUBORDINATE_CA_GATEWAYS est le nom à utiliser pour l'autorité de certification subordonnée. Exemple : subordinate-ca-mtls-gateways-tutorial.
    • L'option --use-preset-profile configure l'autorité de certification subordonnée pour utiliser le profil de certificat mTLS subordonné. Ce profil permet à l'autorité de certification subordonnée d'émettre les certificats TLS du client et du serveur pour mTLS.

    Si vous souhaitez que votre passerelle d'entrée utilise le protocole TLS simple au lieu de mTLS, votre autorité de certification subordonnée n'a besoin d'émettre que les certificats TLS du serveur. Dans ce cas, vous pouvez utiliser le profil de certificat TLS subordonné du serveur (subordinate_server_tls_pathlen_0).

  5. Créez une règle d'émission de certificat :

    cat << EOF > policy.yaml
    baselineValues:
      keyUsage:
        baseKeyUsage:
          digitalSignature: true
          keyEncipherment: true
        extendedKeyUsage:
          serverAuth: true
          clientAuth: true
      caOptions:
        isCa: false
    identityConstraints:
      allowSubjectPassthrough: false
      allowSubjectAltNamesPassthrough: true
      celExpression:
        expression: subject_alt_names.all(san, san.type == URI && san.value.startsWith("spiffe://PROJECT_ID.svc.id.goog/ns/") )
    EOF
    

    Cette règle d'émission oblige les autorités de certification à émettre uniquement des certificats pour les charges de travail du maillage.

  6. Créez un pool d'autorités de certification à utiliser pour l'autorité de certification subordonnée qui émet des certificats pour les proxys side-car du maillage. Appliquez la règle d'émission au pool d'autorités de certification :

    gcloud privateca pools create SUBORDINATE_CA_POOL_SIDECARS \
     --issuance-policy policy.yaml \
     --location CA_LOCATION \
     --tier devops
    
    • SUBORDINATE_CA_POOL_SIDECARS est le nom du pool d'autorités de certification. Exemple :subordinate-ca-mtls-pool-sidecars-tutorial
  7. Créez et activez l'autorité de certification subordonnée qui émet des certificats pour les proxys side-car du maillage :

    gcloud privateca subordinates create SUBORDINATE_CA_SIDECARS \
        --auto-enable \
        --issuer-location CA_LOCATION \
        --issuer-pool ROOT_CA_POOL \
        --key-algorithm ec-p256-sha256 \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_SIDECARS \
        --subject "CN=Example Sidecar mTLS CA, O=Example Organization" \
        --use-preset-profile subordinate_mtls_pathlen_0
    
    • SUBORDINATE_CA_GATEWAYS est le nom à utiliser pour l'autorité de certification subordonnée. Exemple : subordinate-ca-mtls-sidecars-tutorial.

Créer un cluster Google Kubernetes Engine

  1. Dans Cloud Shell, créez un cluster GKE :

    gcloud container clusters create CLUSTER_NAME \
        --enable-ip-alias \
        --num-nodes 4 \
        --release-channel regular \
        --scopes cloud-platform \
        --workload-pool PROJECT_ID.svc.id.goog \
        --zone ZONE
    

    Remplacez CLUSTER_NAME par le nom que vous souhaitez utiliser pour le cluster. Exemple :asm-ingress-cert-manager-ca-service

    Remplacez ZONE par la zone que vous souhaitez utiliser pour le cluster. Exemple :us-central1-f

    Tenez compte des remarques suivantes pour cette commande :

    • L'option --release-channel sélectionne la version de GKE disponible pour le cluster.
    • Cloud Service Mesh et l'émetteur CA Service pour l'outil cert-manager nécessitent tous deux de définir le champ d'application cloud-platform sur les nœuds du cluster.
    • L'argument --workload-pool active la fédération d'identité de charge de travail pour GKE, ce qui permet au compte de service Kubernetes de l'émetteur du service CA pour emprunter l'identité d'un compte de service Google. Ainsi, les pods de l'émetteur CA Service peuvent accéder à l'API CA Service sans télécharger de fichier de clé pour le compte de service Google.
  2. Accordez des autorisations d'administrateur de cluster à votre compte utilisateur :

    kubectl create clusterrolebinding cluster-admin-binding \
        --clusterrole cluster-admin \
        --user $(gcloud config get-value core/account)
    

    Vous devez disposer des autorisations fournies par le cluster-admin Kubernetes ClusterRole pour créer le contrôle des accès basé sur les rôles (RBAC) pour Cloud Service Mesh et l'installation de l'outil cert-manager.

Installer le plan de contrôle Anthos Service Mesh

Dans ce tutoriel, vous allez installer Cloud Service Mesh géré d'un cluster GKE sur Google Cloud, toutes les ressources étant un seul projet. Dans votre propre environnement, vous pouvez appliquer la solution décrite dans ce document à l'aide de Cloud Service Mesh géré ou d'un plan de contrôle au sein du cluster.

Cloud Service Mesh fournit plusieurs options d'installation pour différents scénarios. Une fois ce tutoriel terminé, nous vous recommandons de consulter le guide d'installation pour sélectionner l'option la mieux adaptée à votre environnement.

  1. Dans Cloud Shell, téléchargez l'outil d'installation asmcli :

    curl --location --output asmcli https://storage.googleapis.com/csm-artifacts/asm/asmcli_1.16
    
    chmod +x asmcli
    

    Vous utilisez asmcli pour installer le plan de contrôle Cloud Service Mesh.

  2. Installez le plan de contrôle Cloud Service Mesh :

    ./asmcli install \
        --ca gcp_cas \
        --ca_pool projects/PROJECT_ID/locations/CA_LOCATION/caPools/SUBORDINATE_CA_POOL_SIDECARS \
        --cluster_location ZONE \
        --cluster_name CLUSTER_NAME \
        --enable_all \
        --enable_registration \
        --fleet_id PROJECT_ID \
        --managed \
        --output_dir asm-files \
        --project_id PROJECT_ID \
        --verbose
    

    L'installation prend plusieurs minutes. Une fois l'installation terminée, la sortie suivante s'affiche :

    asmcli: Successfully installed ASM.
    

Installer la passerelle d'entrée

  1. Dans Cloud Shell, créez un espace de noms Kubernetes pour la passerelle d'entrée :

    kubectl create namespace GATEWAY_NAMESPACE
    
    • GATEWAY_NAMESPACE correspond au nom de l'espace de noms que vous souhaitez utiliser pour la passerelle d'entrée. Exemple : istio-ingress.
  2. Réserver une adresse IP interne statique à utiliser pour l'équilibreur de charge réseau passthrough interne de la passerelle d'entrée:

    LOAD_BALANCER_IP=$(gcloud compute addresses create \
        asm-ingress-gateway-ilb \
        --region REGION \
        --subnet default \
        --format 'value(address)')
    
    • Remplacez REGION par la région contenant les zones utilisées par les nœuds de votre cluster GKE. Par exemple, si votre cluster utilise la zone us-central1-f, remplacez REGION par us-central1.

    Cette commande réserve une adresse IP du sous-réseau par défaut dans la région spécifiée.

  3. Créer un fichier manifeste d'opérateur pour la passerelle d'entrée:

    cat << EOF > ingressgateway-operator.yaml
    apiVersion: install.istio.io/v1alpha1
    kind: IstioOperator
    metadata:
      name: ingressgateway-operator
      annotations:
        config.kubernetes.io/local-config: "true"
    spec:
      profile: empty
      revision: asm-managed
      components:
        ingressGateways:
        - name: istio-ingressgateway
          namespace: GATEWAY_NAMESPACE
          enabled: true
          k8s:
            overlays:
            - apiVersion: apps/v1
              kind: Deployment
              name: istio-ingressgateway
              patches:
              - path: spec.template.metadata.annotations
                value:
                  inject.istio.io/templates: gateway
              - path: spec.template.metadata.labels.sidecar\.istio\.io/inject
                value: "true"
              - path: spec.template.spec.containers[name:istio-proxy]
                value:
                  name: istio-proxy
                  image: auto
            service:
              loadBalancerIP: $LOAD_BALANCER_IP
            serviceAnnotations:
              networking.gke.io/load-balancer-type: Internal
              networking.gke.io/internal-load-balancer-allow-global-access: "true"
    EOF
    

    Notez les points suivants concernant le fichier manifeste d'opérateur :

  4. Créez le fichier manifeste d'installation de la passerelle d'entrée à l'aide du fichier manifeste d'opérateur et de l'outil istioctl téléchargés par le script asmcli lors de l'installation du plan de contrôle :

    ./asm-files/istioctl manifest generate \
        --filename ingressgateway-operator.yaml \
        --output ingressgateway
    
  5. Installez la passerelle d'entrée :

    kubectl apply --recursive --filename ingressgateway/
    

Installer l'outil cert-manager

  1. Dans Cloud Shell, téléchargez et appliquez le fichier manifeste d'installation de l'outil cert-manager :

    CERT_MANAGER_VERSION=v1.5.4
    
    curl --location --output cert-manager.yaml "https://github.com/jetstack/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.yaml"
    
    kubectl apply --filename cert-manager.yaml
    

    L'installation de l'outil cert-manager prend environ une minute.

Installer le contrôleur d'émetteur CA Service

Le contrôleur émetteur du service CA permet à l'outil cert-manager de demander des certificats à l'aide d'autorité de certification. Le contrôleur utilise le mécanisme d'extension de l'émetteur externe de l'outil cert-manager.

  1. Dans Cloud Shell, créez un compte de service Google :

    gcloud iam service-accounts create CAS_ISSUER_GSA \
        --display-name "CA Service issuer for cert-manager"
    
    • CAS_ISSUER_GSA correspond au nom du compte de service Google. Exemple :cert-manager-ca-service-issuer

    Le contrôleur d'émetteur Certificate Authority Service utilise ce compte de service Google pour s'authentifier auprès des API Certificate Authority Service.

  2. Créez une liaison de stratégie Identity and Access Management, qui permet au compte de service Google du contrôleur d'émetteur Certificate Authority Service de demander des certificats au pool d'autorités de certification contenant votre autorité de certification subordonnée :

    gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    
  3. Téléchargez le fichier manifeste d'installation du contrôleur d'émetteur Certificate Authority Service :

    CAS_ISSUER_VERSION=v0.5.3
    
    curl --location --output ca-service-issuer.yaml "https://github.com/jetstack/google-cas-issuer/releases/download/${CAS_ISSUER_VERSION}/google-cas-issuer-${CAS_ISSUER_VERSION}.yaml"
    
  4. Créez une liaison de stratégie IAM pour autoriser le compte de service Kubernetes ksa-google-cas-issuer dans l'espace de noms cert-manager à usurper l'identité du compte de service Google (GSA) à l'aide de la fédération d'identité de charge de travail pour GKE :

    gcloud iam service-accounts add-iam-policy-binding \
     CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[cert-manager/ksa-google-cas-issuer]" \
        --role roles/iam.workloadIdentityUser
    

    Les pods du contrôleur d'émetteur CA Service utilisent le compte de service Kubernetes ksa-google-cas-issuer.

  5. Installez le contrôleur d'émetteur CA Service dans votre cluster GKE :

    kubectl apply --filename ca-service-issuer.yaml
    
  6. Ajoutez l'annotation iam.gke.io/gcp-service-account de la fédération d'identité de charge de travail pour GKE au compte de service Kubernetes utilisé par les pods du contrôleur d'émetteur CA Service :

    kubectl annotate serviceaccount ksa-google-cas-issuer --namespace cert-manager \
       "iam.gke.io/gcp-service-account=CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com"
    

    Cette annotation informe GKE que le compte de service Kubernetes peut emprunter l'identité du compte de service Google pour accéder aux API Google.

Créer un émetteur de certificat

  1. Dans Cloud Shell, créez et appliquez un fichier manifeste GoogleCASIssuer :

    cat << EOF > gateway-cas-issuer.yaml
    apiVersion: cas-issuer.jetstack.io/v1beta1
    kind: GoogleCASIssuer
    metadata:
      name: gateway-cas-issuer
      namespace: GATEWAY_NAMESPACE
    spec:
      caPoolId: SUBORDINATE_CA_POOL_GATEWAYS
      location: CA_LOCATION
      project: PROJECT_ID
    EOF
    
    kubectl apply --filename gateway-cas-issuer.yaml
    

    L'émetteur permet à l'outil cert-manager de provisionner des certificats à partir du pool d'autorités de certification subordonnées dans l'espace de noms de la passerelle d'entrée.

Déploiement d'un exemple d'application

Dans cette section, vous allez vérifier que l'outil cert-manager peut utiliser l'émetteur CA Service pour obtenir des certificats auprès de CA Service. Pour ce faire, vous allez déployer un exemple d'application contenant la configuration de routage des requêtes et un certificat pour la passerelle d'entrée.

  1. Dans Cloud Shell, créez un espace de noms pour les ressources de l'exemple d'application :

    cat << EOF > sample-app-namespace.yaml
    apiVersion: v1
    kind: Namespace
    metadata:
      name: APP_NAMESPACE
      annotations:
        mesh.cloud.google.com/proxy: '{"managed":"true"}'
      labels:
        istio.io/rev: asm-managed
    EOF
    
    kubectl apply --filename sample-app-namespace.yaml
    
    • APP_NAMESPACE est le nom de l'espace de noms pour l'exemple d'application. Par exemple, sample-app.

    L'annotation mesh.cloud.google.com/proxy active le plan de données géré pour l'espace de noms.

    Le libellé istio.io/rev: asm-managed sélectionne le canal de publication standard pour le plan de données géré dans l'espace de noms de l'exemple d'application. Modifiez la valeur de ce libellé si vous utilisez les canaux de publication rapides ou stables.

  2. Créez une ressource Deployment pour l'exemple d'application :

    cat << EOF > deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello
      namespace: APP_NAMESPACE
      labels:
        app: hello
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: hello
      template:
        metadata:
          labels:
            app: hello
        spec:
          containers:
          - image: gcr.io/google-samples/hello-app:1.0
            name: hello-app
            ports:
            - containerPort: 8080
    EOF
    
    kubectl apply --filename deployment.yaml
    
  3. Créez une ressource Service pour l'exemple d'application :

    cat << EOF > service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: SERVICE_NAME
      namespace: APP_NAMESPACE
    spec:
      ports:
      - name: http-hello
        port: 8080
      selector:
        app: hello
      type: ClusterIP
    EOF
    
    kubectl apply --filename service.yaml
    
    • SERVICE_NAME est le nom du service ; Exemple : hello.
  4. Créez une ressource Certificate pour le nom de domaine hello.example.com à l'aide de l'émetteur de certificats :

    cat << EOF > certificate.yaml
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: hello-example-com-certificate
      namespace: GATEWAY_NAMESPACE
    spec:
      secretName: hello-example-com-credential
      commonName: hello.example.com
      dnsNames:
      - hello.example.com
      duration: 24h
      renewBefore: 8h
      issuerRef:
        group: cas-issuer.jetstack.io
        kind: GoogleCASIssuer
        name: gateway-cas-issuer
    EOF
    
    kubectl apply --filename certificate.yaml
    

    L'espace de noms du certificat doit correspondre à celui de la passerelle d'entrée. En règle générale, seuls les administrateurs de plates-formes peuvent modifier les ressources de cet espace de noms, car les modifications peuvent affecter l'ensemble du maillage de services. L'outil cert-manager crée la ressource Secret du certificat TLS dans le même espace de noms. Cela signifie que les administrateurs d'applications n'ont pas besoin d'avoir accès à l'espace de noms de la passerelle d'entrée.

    Vous pouvez ajouter des noms d'hôte supplémentaires dans la liste dnsNames du certificat. Ces noms d'hôte sont inclus dans le certificat en tant que noms d'objet de remplacement (SAN).

  5. Créer une passerelle pour l'exemple d'application:

    cat << EOF > gateway.yaml
    apiVersion: networking.istio.io/v1beta1
    kind: Gateway
    metadata:
      name: GATEWAY_NAME
      namespace: GATEWAY_NAMESPACE
    spec:
      selector:
        istio: ingressgateway
      servers:
      - hosts:
        - APP_NAMESPACE/hello.example.com
        port:
          name: https-hello
          number: 443
          protocol: HTTPS
        tls:
          credentialName: hello-example-com-credential
          mode: MUTUAL
    EOF
    
    kubectl apply --filename gateway.yaml
    
    • GATEWAY_NAME correspond au nom de la passerelle. Exemple : hello.
    • Le champ credentialName de la passerelle correspond au champ secretName du certificat. L'outil cert-manager crée un secret Kubernetes avec le certificat TLS de CA Service. Ce certificat permet à la passerelle d'entrée d'arrêter le trafic TLS destiné à hello.example.com.

    Le fichier manifeste de la passerelle spécifie la classe MUTUAL TLS (mTLS). Si vous souhaitez configurer la passerelle pour qu'elle utilise le protocole TLS standard, définissez le mode TLS de la passerelle sur SIMPLE.

  6. Créez une ressource VirtualService pour l'exemple d'application :

    cat << EOF > virtual-service.yaml
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: hello
      namespace: APP_NAMESPACE
    spec:
      hosts:
      - hello.example.com
      gateways:
      - GATEWAY_NAMESPACE/GATEWAY_NAME
      http:
      - route:
        - destination:
            host: SERVICE_NAME
            port:
              number: 8080
    EOF
    
    kubectl apply --filename virtual-service.yaml
    

    Gateway et VirtualService utilisent des espaces de noms différents. Ce modèle courant limite les modifications apportées au routage basé sur l'hôte dans la passerelle aux administrateurs de plates-formes qui sont autorisés à modifier les ressources dans l'espace de noms de la passerelle d'entrée.

    Les administrateurs d'applications autorisés à modifier la ressource VirtualService dans l'espace de noms de l'exemple d'application peuvent modifier le routage en fonction d'autres champs de requête, tels que le chemin de l'URL, sans se coordonner avec les administrateurs de la plates-formes.

Si vous souhaitez découvrir d'autres options de configuration, lisez la documentation de l'API pour le certificat, Passerelle et VirtualService ressources.

Vous pouvez appliquer des règles d'authentification et d'autorisation au trafic entrant dans le maillage de services via la passerelle d'entrée. Pour ce faire, consultez la documentation le service Istio PeerAuthentication et AuthorizationPolicy API.

Valider la solution

Dans cette section, vous allez vérifier que vous pouvez envoyer des requêtes HTTPS à l'exemple d'application à l'aide du protocole mTLS depuis l'extérieur du maillage de services. Pour ce faire, vous devez créer une instance de VM Compute Engine, demander un certificat TLS client à CA Service et authentifier la requête auprès de l'exemple d'application à l'aide de ce certificat.

Vous avez besoin d'un accès SSH à l'instance de VM. Le réseau par défaut inclut une règle de pare-feu qui autorise l'accès SSH. Si vous ne disposez pas d'un accès SSH, suivez la documentation sur les règles de pare-feu pour créer une règle de pare-feu autorisant les connexions TCP entrantes sur le port 22.

  1. Dans Cloud Shell, créez un compte de service Google Cloud :

    gcloud iam service-accounts create CLIENT_VM_GSA \
        --display-name "CA Service tutorial VM instance service account"
    
    • CLIENT_VM_GSA correspond au nom du compte de service Google. Exemple :cas-tutorial-client

    Vous attribuez ce compte de service Google à l'instance de VM Compute Engine.

  2. Accordez le rôle Demandeur de certificat CA Service au compte de service Google sur le pool d'autorités de certification subordonnées de la passerelle :

    gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    

    Ce rôle permet de demander des certificats au pool d'autorités de certification.

  3. Créez une instance de VM Compute Engine dans le même VPC que le cluster GKE :

    gcloud compute instances create cas-tutorial-client \
        --scopes cloud-platform \
        --service-account CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --zone ZONE
    

    L'instance de VM nécessite le niveau d'accès cloud-platform pour accéder à l'API CA Service.

  4. Enregistrez l'adresse IP de l'équilibreur de charge réseau passthrough interne de la passerelle d'entrée dans un fichier:

    kubectl get services istio-ingressgateway \
       --namespace GATEWAY_NAMESPACE \
       --output jsonpath='{.status.loadBalancer.ingress[0].ip}' > ilb-ip.txt
    
  5. Enregistrez le certificat de clé publique de votre autorité de certification racine dans un fichier :

    gcloud privateca roots describe ROOT_CA \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --format 'value(pemCaCertificates)' > root-ca-cert.pem
    
  6. Copiez le certificat CA racine et le fichier contenant l'adresse IP équilibreur de charge réseau passthrough interne de passerelle d'entrée vers l'instance de VM:

    gcloud compute scp root-ca-cert.pem ilb-ip.txt cas-tutorial-client:~ \
       --zone ZONE
    
  7. Connectez-vous à l'instance de VM via SSH :

    gcloud compute ssh cas-tutorial-client --zone ZONE
    

    Exécutez les autres commandes de cette section depuis la session SSH.

  8. Installez les packages ca-certificates et coreutils, ainsi que curl. openssl et jq d'outils de ligne de commande:

    sudo apt-get update --yes
    
    sudo apt-get install --yes ca-certificates coreutils curl jq openssl
    
  9. Créez une paire de clés pour le certificat TLS client :

    openssl genrsa -out private-key.pem 2048
    
    openssl rsa -in private-key.pem -pubout -out public-key.pem
    
  10. Interrogez le serveur de métadonnées pour obtenir l'adresse e-mail de l'identité du compte de service Google associée à l'instance de VM :

    GSA_EMAIL=$(curl --silent --header "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email)
    
  11. Créez un fichier JSON que vous utilisez en tant que corps de requête lorsque vous demandez un certificat TLS client à partir de l'API Certificate Authority Service :

    cat << EOF > request.json
    {
      "config": {
        "publicKey": {
          "format": "PEM",
          "key": "$(base64 --wrap 0 public-key.pem)"
        },
        "subjectConfig": {
          "subject": {
            "commonName": "$(hostname --short)",
            "organization": "Example Organization"
          },
          "subjectAltName": {
            "dnsNames": [
              "$(hostname --fqdn)"
            ],
            "emailAddresses": [
              "$GSA_EMAIL"
            ]
          }
        },
        "x509Config": {
          "caOptions": {
            "isCa": false
          },
          "keyUsage": {
            "baseKeyUsage": {
              "digitalSignature": true,
              "keyEncipherment": true
            },
            "extendedKeyUsage": {
              "clientAuth": true
            }
          }
        }
      },
      "lifetime": "86400s"
    }
    EOF
    

    Pour en savoir plus sur les champs de la section sur la configuration, consultez le type CertificateConfig dans la documentation de l'API CA Service.

  12. Demandez un jeton d'accès OAuth 2.0 au serveur de métadonnées :

    TOKEN=$(curl --silent --header "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token | jq --raw-output ".access_token")
    

    Ce jeton d'accès fournit les autorisations accordées au compte de service Google associé à l'instance de VM.

  13. Demandez un certificat TLS client à partir de l'API CA Service et stockez le corps de la réponse dans un fichier :

    curl --silent --request POST \
        --header "Authorization: Bearer $TOKEN" \
        --header "Content-Type: application/json" \
        --data @request.json \
        --output response.json \
        "https://privateca.googleapis.com/v1/projects/PROJECT_ID/locations/CA_LOCATION/caPools/SUBORDINATE_CA_POOL_GATEWAYS/certificates"
    

    La commande utilise le jeton d'accès pour authentifier la requête API.

  14. Enregistrez le certificat client et la chaîne de certificats dans un fichier :

    jq --raw-output --join-output ".pemCertificate , .pemCertificateChain[]" response.json > client-cert-chain.pem
    
  15. Utilisez curl pour envoyer une requête HTTPS de l'instance de VM à l'exemple d'application :

    curl --cert client-cert-chain.pem --key private-key.pem \
        --cacert root-ca-cert.pem \
        --resolve hello.example.com:443:$(cat ilb-ip.txt) \
        --silent https://hello.example.com | head -n1
    

    Le résultat ressemble à ceci :

    Hello, world!
    

    Cette réponse indique que curl a bien envoyé la requête HTTPS à l'aide de mTLS. L'exemple d'application renvoie le message qui s'affiche dans la sortie du terminal.

    La commande curl réalise les actions suivantes :

    • Les options --cert et --key indiquent à curl d'utiliser le certificat TLS client et la clé privée pour authentifier la requête. Le fichier du certificat client contient la chaîne complète de certificats, du certificat client à l'autorité de certification racine.

    • L'option --cacert demande à curl de vérifier que l'autorité de certification racine que vous avez créée dans ce tutoriel, ou l'une de ses autorités de certification subordonnées, a émis le certificat du serveur.

      Si vous omettez cette option, curl tente de vérifier le certificat du serveur. en utilisant le bundle d'autorités de certification par défaut de votre système d'exploitation, tel que ca-certificates sur Debian. La validation échoue, car le groupe d'autorités de certification par défaut n'inclut pas l'autorité de certification racine que vous avez créée dans ce tutoriel.

    • L'option --resolve demande à curl d'utiliser l'adresse IP de l'équilibreur de charge réseau interne à stratégie directe comme destination pour les requêtes permettant d'héberger hello.example.com sur le port 443.

      Si vous omettez cette option, curl tente d'utiliser le DNS pour résoudre le nom d'hôte hello.example.com. La résolution DNS échoue, car il n'existe aucune entrée DNS pour ce nom d'hôte.

      Dans votre propre environnement, nous vous recommandons de créer un enregistrement DNS A pointant vers l'adresse IP de l'équilibreur de charge réseau passthrough interne ($LOAD_BALANCER_IP). Créez cet enregistrement à l'aide de Cloud DNS en suivant la documentation sur la gestion des enregistrements.

    • L'option --silent supprime les rapports de progression du téléchargement de la réponse dans la sortie du terminal.

    • La commande achemine la sortie curl vers head -n1. Résultat : la sortie dans le terminal n'inclut que la première ligne du corps de la réponse.

  16. Quittez la session SSH :

    exit
    

Dans cette section, vous avez demandé un certificat TLS client directement à partir de l'API CA Service. Si le client correspond à la passerelle de sortie d'un autre maillage de services dans un cluster Kubernetes distinct, vous pouvez utiliser l'outil cert-manager et l'émetteur Certificate Authority Service avec la même autorité de certification racine pour fournir les certificats clients à la passerelle de sortie.

Dans d'autres situations, vous pouvez utiliser des outils tels que Hashicorp Vault, Terraform ou gcloud pour demander des certificats TLS clients pour les charges de travail en dehors du maillage de services. Consultez la documentation de CA Service pour obtenir des exemples de solutions et la documentation gcloud pour en savoir plus sur CA Service.

(Facultatif) Ajouter des certificats CA au truststore

Cette section facultative décrit comment ajouter des certificats CA au magasin de certificats CA approuvés pour la distribution Debian de Linux. Ces instructions s'appliquent également aux distributions dérivées de Debian, telles qu'Ubuntu.

Lorsque vous ajoutez des certificats CA à ce magasin, vous n'avez pas besoin de spécifier l'emplacement des certificats CA approuvés lors de l'envoi de requêtes HTTPS à l'aide de curl, Python, Go et Ruby.

  1. Connectez-vous à l'instance de VM via SSH :

    gcloud compute ssh cas-tutorial-client --zone ZONE
    

    Exécutez les autres commandes de cette section depuis la session SSH.

  2. Copiez le certificat CA racine dans le répertoire /usr/local/share/ca-certificates et assurez-vous que le fichier comporte l'extension .crt :

    sudo cp root-ca-cert.pem /usr/local/share/ca-certificates/cas-rootca.crt
    
  3. Définissez les autorisations du fichier pour que tous les utilisateurs puissent lire le fichier du certificat CA racine :

    sudo chmod 644 /usr/local/share/ca-certificates/cas-rootca.crt
    
  4. Exécutez la update-ca-certificates. script:

    sudo update-ca-certificates
    

    Ce script ajoute le certificat à l'ensemble de certificats approuvés du répertoire /etc/ssl/certs et dans le fichier /etc/ssl/certs/ca-certificates.crt.

    Le résultat est le suivant :

    Updating certificates in /etc/ssl/certs...
    1 added, 0 removed; done.
    Running hooks in /etc/ca-certificates/update.d...
    done.
    
  5. Utilisez curl pour envoyer une requête HTTPS de l'instance de VM à l'exemple d'application :

    curl --cert client-cert-chain.pem --key private-key.pem \
       --resolve hello.example.com:443:$(cat ilb-ip.txt) \
       --silent https://hello.example.com | head -n1
    

    Le résultat ressemble à ceci :

    Hello, world!
    

    Cette réponse indique que curl a bien envoyé la requête HTTPS à l'aide de mTLS et a validé le certificat TLS du serveur à partir de la passerelle d'entrée à l'aide du magasin de certificats CA par défaut.

  6. Quittez la session SSH :

    exit
    

Résoudre les problèmes

Si le contrôleur d'émetteur CA Service ne crée pas le secret du certificat TLS, affichez les journaux du contrôleur d'émetteur CA Service :

kubectl logs deployment/google-cas-issuer --namespace cert-manager

Si vous rencontrez des problèmes lors de l'installation de Cloud Service Mesh, exécutez l'outil asmcli pour valider votre projet Cloud et votre cluster GKE.

Si vous rencontrez d'autres problèmes avec ce tutoriel, nous vous recommandons de consulter les documents ci-dessous :

Effectuer un nettoyage

Pour éviter que les ressources utilisées lors de ce tutoriel continuent d'être facturées sur votre compte Google Cloud, supprimez le projet ou les ressources individuelles.

Supprimer le projet

  1. Dans Cloud Shell, supprimez le projet :

    gcloud projects delete PROJECT_ID
    

Supprimer les ressources

Si vous souhaitez conserver le projet Google Cloud que vous avez utilisé dans ce tutoriel, supprimez les différentes ressources :

  1. Dans Cloud Shell, annulez l'enregistrement du cluster GKE à partir de GKE Hub :

    gcloud container hub memberships unregister CLUSTER_NAME \
        --gke-cluster ZONE/CLUSTER_NAME
    
  2. Supprimez le cluster GKE :

    gcloud container clusters delete CLUSTER_NAME \
        --zone ZONE --async --quiet
    
  3. Supprimez les liaisons de stratégie IAM du pool d'autorités de certification subordonnées :

    gcloud privateca pools remove-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    
    gcloud privateca pools remove-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    
  4. Désactivez et planifiez la suppression des autorités de certification subordonnées et de l'autorité de certification racine :

    gcloud privateca subordinates disable SUBORDINATE_CA_GATEWAYS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_GATEWAYS \
        --quiet
    
    gcloud privateca subordinates delete SUBORDINATE_CA_GATEWAYS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_GATEWAYS \
        --ignore-active-certificates \
        --quiet
    
    gcloud privateca subordinates disable SUBORDINATE_CA_SIDECARS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_SIDECARS \
        --quiet
    
    gcloud privateca subordinates delete SUBORDINATE_CA_SIDECARS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_SIDECARS \
        --ignore-active-certificates \
        --quiet
    
    gcloud privateca roots disable ROOT_CA \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --quiet
    
    gcloud privateca roots delete ROOT_CA \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --ignore-active-certificates \
        --quiet
    
  5. Supprimez la liaison de stratégie IAM du compte de service Google du contrôleur d'émetteur CA Service :

    gcloud iam service-accounts remove-iam-policy-binding \
        CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[cert-manager/ksa-google-cas-issuer]" \
        --role roles/iam.workloadIdentityUser
    
  6. Supprimez les comptes de service Google :

    gcloud iam service-accounts delete --quiet \
        CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com
    
    gcloud iam service-accounts delete --quiet \
        CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com
    
  7. Supprimez l'adresse IP de l'équilibreur de charge réservée :

    gcloud compute addresses delete asm-ingress-gateway-ilb \
        --region REGION --quiet
    
  8. Supprimez l'instance de VM Compute Engine :

    gcloud compute instances delete cas-tutorial-client \
        --zone ZONE --quiet
    

Étape suivante