1. Introduction
Dans cet atelier de programmation, vous allez créer une application de démonstration de base qui illustre comment intégrer différents services Google Cloud pour un service situé dans un projet soumis à des restrictions de conformité. Ce projet utilise les fonctionnalités de sécurité suivantes :
- Périmètres de données pour vous aider à répondre aux contrôles des environnements réglementés
- Des clés de chiffrement gérées par le client ( CMEK) pour protéger les données au repos
- Des nœuds protégés GKE et des nœuds confidentiels GKE pour sécuriser les données pendant le traitement
- Workload Identity pour GKE afin de gérer l'accès à Vertex AI, qui utilise Gemini pour les tâches de traitement d'images
- L'IA générative sur Vertex A pour gérer la détection des casques de protection à partir d'un flux vidéo
Cet atelier de programmation s'adresse aux développeurs de tous niveaux, y compris aux débutants. Vous utiliserez l'interface de ligne de commande dans Google Cloud Shell et le code Python. Vous n'avez pas besoin d'être un expert en Python, mais une compréhension de base de la lecture de code vous aidera à comprendre les concepts.
Remarque : Il s'agit d'une preuve de concept simplifiée, et non d'une application de production. Appliquez des précautions supplémentaires, telles qu'un accès externe authentifié et sécurisé à ce service dans un scénario réel.
2. Avant de commencer
Configuration du projet
../shared/_project-setup.md
Démarrer Cloud Shell
Cloud Shell est un environnement de ligne de commande exécuté dans Google Cloud, qui est préchargé avec les outils nécessaires.
- Cliquez sur Activer Cloud Shell en haut de la console Google Cloud :

- Une fois connecté à Cloud Shell, exécutez cette commande pour vérifier votre authentification dans Cloud Shell :
gcloud auth list
- Exécutez la commande suivante pour vérifier que votre projet est configuré pour être utilisé avec gcloud :
gcloud config get project
- Vérifiez que le projet est celui attendu, puis exécutez la commande ci-dessous pour définir l'ID de votre projet :
export PROJECT_ID=$(gcloud config get project)
Autorisations IAM requises
Le compte que vous utilisez pour cet atelier de programmation doit disposer des rôles IAM suivants. Ces autorisations sont nécessaires pour créer les ressources Google Cloud requises (projets, dossiers, clusters GKE, clés KMS, comptes de service, etc.) et configurer la charge de travail Assured Workloads.
Au niveau de l'organisation :
- roles/assuredworkloads.admin (Administrateur Assured Workloads) : pour créer et gérer la ressource Assured Workloads elle-même, en veillant à la configuration de la conformité.
Au niveau du compte de facturation (sur votre compte de facturation) :
- roles/billing.accountUser (Utilisateur de compte de facturation) : pour associer le compte de facturation spécifié.
Configurer les variables de l'atelier de programmation
Pour créer l'infrastructure nécessaire, vous devez fournir les variables d'environnement suivantes :
# The ID of the Billing Account in the format (XXXXXX-XXXXXX-XXXXXX).
# This value will be used to attach in the projects created using Assured Workloads
export BILLING_ACCOUNT=
# The ID of a Google Cloud Platform organization
# Run `gcloud organizations list` to check all your available organizations
export GCP_ORGANIZATION=
# The numeric ID of a folder where the Assured Workloads will create the resources.
export FOLDER_ID=
# Region where the application will be deployed.
# Since you are using Assured Workloads, you MUST use one of the valid locations as described here: <https://docs.cloud.google.com/assured-workloads/docs/locations>
export REGION="us-central1"
# The ID of an existing Google Cloud project to be used for API quota and billing purposes.
# This project will only be used to enable the Assured Workloads API and create an Assured Workload.
export QUOTA_PROJECT_ID=
# Random suffix used to avoid naming collisions when creating the GCP projects.
export RANDOM_SUFFIX=$(cat /dev/urandom | tr -dc 'a-z0-9' | head -c 5 ; echo)
# The ID of the projects that will be created using Assured Workloads.
# You can modify this value if you want a custom id.
export PROJECT_ID="il5-gemini-vision-aw-${RANDOM_SUFFIX}"
export KMS_PROJECT_ID="il5-gemini-vision-kms-${RANDOM_SUFFIX}"
3. Créer la base d'Assured Workloads
Vous pouvez maintenant créer la base de votre application dans un environnement réglementé. Utilisez Assured Workloads pour appliquer les exigences de conformité en créant un environnement contrôlé pour vos ressources.
Configurer votre projet de quota
Activez l'API Assured Workloads dans votre projet de quota. Cette API est requise pour créer et gérer Assured Workloads.
gcloud services enable assuredworkloads.googleapis.com \
--project="${QUOTA_PROJECT_ID}"
Créer l'environnement de charge de travail Assured Workloads
La commande suivante crée une "zone d'atterrissage" sécurisée pour votre démonstration. Elle crée deux projets Google Cloud sous le dossier et le compte de facturation que vous avez spécifiés.
- Un projet héberge votre cluster GKE et votre application.
- L'autre projet gère vos clés de chiffrement gérées par le client (CMEK).
Il applique automatiquement les contrôles de conformité IL5 spécifiés aux deux projets dès leur création.
Exécutez la commande suivante pour créer l'environnement de charge de travail.
export ASSURED_WORKLOAD_ID=$(gcloud assured workloads create \
--project="${QUOTA_PROJECT_ID}" \
--display-name="DoD IL5 Gemini Vision Demo" \
--compliance-regime="IL5" \
--billing-account="billingAccounts/${BILLING_ACCOUNT}" \
--location="${REGION}" \
--organization="${GCP_ORGANIZATION}" \
--provisioned-resources-parent="folders/${FOLDER_ID}" \
--resource-settings="consumer-project-id=${PROJECT_ID},consumer-project-name=DoD IL5 Workloads,encryption-keys-project-id=${KMS_PROJECT_ID},encryption-keys-project-name=DoD IL5 KMS" \
--labels="codelab=gemini-vision-demo" \
--format="value(name)")
echo "Assured Workload created: ${ASSURED_WORKLOAD_ID}"
export WORKLOAD_FOLDER_ID=$(gcloud assured workloads describe ${ASSURED_WORKLOAD_ID} \
--location="${REGION}" \
--project="${QUOTA_PROJECT_ID}" \
--format="json" | grep -B 1 "CONSUMER_FOLDER" | grep -oE "[0-9]{10,}")
echo "Assured Workload folder created: ${WORKLOAD_FOLDER_ID}"
gcloud projects create "${PROJECT_ID}" \
--folder="${WORKLOAD_FOLDER_ID}" \
--name="DoD IL5 Workloads"
gcloud billing projects link "${PROJECT_ID}" \
--billing-account="${BILLING_ACCOUNT}"
export PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)")
Activer les API Google Cloud requises
Avant de créer, activez les API requises pour les services nécessaires.
La commande ci-dessous active tous les services nécessaires pour cet atelier de programmation dans votre projet de charge de travail principal.
gcloud services enable \
aiplatform.googleapis.com \
artifactregistry.googleapis.com \
cloudkms.googleapis.com \
compute.googleapis.com \
container.googleapis.com \
iam.googleapis.com \
logging.googleapis.com \
monitoring.googleapis.com \
--project="${PROJECT_ID}"
4. Configurer l'infrastructure GKE
Créez l'infrastructure de base qui prend en charge votre cluster GKE. Cela implique de configurer un réseau dédié pour votre cluster et de configurer vos propres clés de chiffrement pour protéger les données sur vos nœuds.
Configurer le réseau VPC
Créez un cloud privé virtuel (VPC) et un sous-réseau personnalisés. Cette approche vous offre un contrôle total sur la plage d'adresses IP et garantit que votre cluster est isolé comme prévu.
Exécutez les commandes suivantes pour créer le réseau VPC et un sous-réseau dans la région que vous avez spécifiée.
export GKE_NETWORK_NAME="il5-gke-network"
export GKE_SUBNETWORK_NAME="il5-gke-subnet"
gcloud compute networks create "${GKE_NETWORK_NAME}" \
--description="VPC network for GKE cluster in DoD IL5 Assured Workload" \
--subnet-mode="custom" \
--project="${PROJECT_ID}"
gcloud compute networks subnets create "${GKE_SUBNETWORK_NAME}" \
--network="${GKE_NETWORK_NAME}" \
--range="10.10.0.0/20" \
--region="${REGION}" \
--description="Subnet for GKE cluster nodes in DoD IL5 Assured Workload" \
--project="${PROJECT_ID}"
Configurer le chiffrement avec Cloud KMS
Pour répondre aux exigences de conformité strictes concernant les données au repos, utilisez des clés de chiffrement gérées par le client (CMEK). Cela vous donne un contrôle direct sur les clés utilisées pour chiffrer les disques de démarrage de vos nœuds GKE.
export KMS_KEYRING_NAME="il5_gke_key_ring"
export KMS_KEY_NAME="il5_gke_key"
gcloud kms keyrings create "${KMS_KEYRING_NAME}" \
--location="$REGION" \
--project="${KMS_PROJECT_ID}"
gcloud kms keys create "${KMS_KEY_NAME}" \
--keyring="${KMS_KEYRING_NAME}" \
--location="${REGION}" \
--purpose="encryption" \
--project="${KMS_PROJECT_ID}"
Étant donné que la clé de chiffrement existe dans un projet KMS distinct du service qui doit l'utiliser, l'agent de service Google Compute Engine du projet de charge de travail doit avoir accès à la clé.
Vous devez explicitement accorder à l'agent de service GCE du projet de charge de travail l'autorisation d'utiliser cette clé. La commande ci-dessous ajoute une liaison de stratégie IAM à la clé, en attribuant le rôle nécessaire à l'agent de service.
gcloud kms keys add-iam-policy-binding "${KMS_KEY_NAME}" \
--location="${REGION}" \
--keyring="${KMS_KEYRING_NAME}" \
--member="serviceAccount:service-${PROJECT_NUMBER}@compute-system.iam.gserviceaccount.com" \
--role="roles/cloudkms.cryptoKeyEncrypterDecrypter" \
--project="${KMS_PROJECT_ID}"
Configurer un compte de service de nœud GKE
export GKE_NODE_SA=gke-node-sa
gcloud iam service-accounts create "${GKE_NODE_SA}" \
--display-name="GKE Node Service Account" \
--project="${PROJECT_ID}"
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${GKE_NODE_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/logging.logWriter"
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${GKE_NODE_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/monitoring.metricWriter"
5. Créer et configurer un cluster GKE
Vous pouvez maintenant créer le cluster GKE. La commande suivante provisionne un cluster GKE avec plusieurs fonctionnalités de sécurité activées.
Cette opération prend plusieurs minutes, car Google Cloud provisionne les nœuds et le plan de contrôle.
export GKE_CLUSTER=ppe-app
gcloud beta container clusters create "${GKE_CLUSTER}" \
--project="$PROJECT_ID" \
--region="$REGION" \
--service-account="${GKE_NODE_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
--release-channel="regular" \
--machine-type="n2d-standard-4" \
--image-type="COS_CONTAINERD" \
--disk-type="pd-ssd" \
--disk-size="50" \
--boot-disk-kms-key="projects/${KMS_PROJECT_ID}/locations/${REGION}/keyRings/${KMS_KEYRING_NAME}/cryptoKeys/${KMS_KEY_NAME}" \
--metadata disable-legacy-endpoints=true \
--num-nodes="1" \
--network="projects/${PROJECT_ID}/global/networks/${GKE_NETWORK_NAME}" \
--subnetwork="projects/${PROJECT_ID}/regions/${REGION}/subnetworks/${GKE_SUBNETWORK_NAME}" \
--security-posture="standard" \
--workload-vulnerability-scanning="disabled" \
--workload-pool="${PROJECT_ID}.svc.id.goog" \
--workload-metadata=GKE_METADATA \
--addons="HorizontalPodAutoscaling,HttpLoadBalancing,NodeLocalDNS,GcePersistentDiskCsiDriver" \
--max-surge-upgrade=1 \
--max-unavailable-upgrade=0 \
--binauthz-evaluation-mode="DISABLED" \
--no-enable-basic-auth \
--enable-autoupgrade \
--enable-autorepair \
--enable-confidential-nodes \
--confidential-node-type=sev \
--enable-ip-access \
--enable-ip-alias \
--enable-managed-prometheus \
--enable-dns-access \
--enable-shielded-nodes \
--shielded-integrity-monitoring \
--shielded-secure-boot
Se connecter au nouveau cluster
Pour interagir avec votre nouveau cluster, configurez votre outil de ligne de commande kubectl local.
Cette commande récupère les identifiants et le point de terminaison du cluster, et configure automatiquement votre fichier kubeconfig local. Après avoir exécuté cette commande, toutes les commandes kubectl que vous exécuterez seront dirigées vers votre nouveau cluster GKE.
gcloud container clusters get-credentials "${GKE_CLUSTER}" \
--region="${REGION}" \
--project="${PROJECT_ID}" \
--dns-endpoint
6. Configurer l'identité de l'application
Pour connecter un compte de service Kubernetes à un compte de service Google Cloud IAM, configurez Workload Identity.
Créer des comptes de service
Créez un compte de service Kubernetes (KSA) dédié dans votre cluster.
export GKE_NAMESPACE=default
export GKE_SA=ppe-sa
kubectl create sa "${GKE_SA}" --namespace="${GKE_NAMESPACE}"
Ensuite, votre application a besoin d'une identité dans Google Cloud. Créez un compte de service Google Cloud IAM pour l'application. Une fois le compte de service créé, accordez-lui les rôles nécessaires.
# Create GCP service account
gcloud iam service-accounts create "${GKE_SA}" \
--project="${PROJECT_ID}"
# Grant necessary roles
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${GKE_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"
Autoriser le compte de service Kubernetes à emprunter l'identité du compte IAM
Une fois les deux comptes de service créés, la dernière étape consiste à créer le lien entre eux. Il s'agit d'un processus en deux parties. Tout d'abord, ajoutez une stratégie IAM à votre compte de service Google Cloud.
# Allow the Kubernetes service account to act as GCP service account by using Workload Identity
gcloud iam service-accounts add-iam-policy-binding "${GKE_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
--project="${PROJECT_ID}" \
--role="roles/iam.workloadIdentityUser" \
--member="serviceAccount:${PROJECT_ID}.svc.id.goog[${GKE_NAMESPACE}/${GKE_SA}]"
Ensuite, annotez votre compte de service Kubernetes.
kubectl annotate --namespace="${GKE_NAMESPACE}" serviceaccount "$GKE_SA" \
iam.gke.io/gcp-service-account="${GKE_SA}@${PROJECT_ID}.iam.gserviceaccount.com"
Une fois cette opération terminée, tous les pods exécutés dans votre cluster avec le compte de service Kubernetes peuvent désormais accéder à l'API Vertex.
Remarque : Il est possible d'éliminer l'emprunt d'identité du compte de service pour simplifier cette configuration. Pour en savoir plus et connaître les limites, cliquez ici.
7. Créer et déployer l'application
Il est temps d'empaqueter votre application, de la stocker et de la déployer sur votre cluster GKE.
Créer le dépôt Artifact Registry
Avant de pouvoir exécuter l'application, empaquetez-la en tant que conteneur Docker et stockez-la dans un dépôt Artifact Registry. Utilisez la commande ci-dessous pour créer ce dépôt.
export REPOSITORY_ID=ppe-repo
gcloud artifacts repositories create "${REPOSITORY_ID}" \
--repository-format=docker \
--location="${REGION}" \
--project="${PROJECT_ID}" \
--description="Regional Docker repo for PPE App"
Vous devez explicitement accorder au compte de service utilisé par les nœuds GKE la possibilité de lire à partir de votre nouveau dépôt.
gcloud artifacts repositories add-iam-policy-binding "${REPOSITORY_ID}" \
--location="${REGION}" \
--role="roles/artifactregistry.reader" \
--project="${PROJECT_ID}" \
--member="serviceAccount:${GKE_NODE_SA}@${PROJECT_ID}.iam.gserviceaccount.com"
Créer et transférer l'image Docker
Créez et transférez l'image Docker vers le dépôt. Tout d'abord, clonez le code source et créez l'image de conteneur. Ensuite, ajoutez-y le chemin d'accès complet à Artifact Registry, puis transférez-le vers le dépôt que vous avez créé précédemment.
git clone https://github.com/GoogleCloudPlatform/next-26-sessions.git
cd BRK3-034-workplace-safety
cd ppe
export IMAGE_TAG="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_ID}/ppe-app:v15"
docker build -t "${IMAGE_TAG}" .
docker push "${IMAGE_TAG}"
Déployer sur GKE
Une fois l'image de conteneur disponible dans Artifact Registry, la dernière étape consiste à demander à GKE de l'extraire et de l'exécuter. Pour ce faire, définissez les ressources de votre application dans un fichier manifeste Kubernetes et appliquez-le au cluster. Cette commande crée les objets de déploiement et de service définis dans le fichier.
export GKE_DEPLOY=ppe-detector
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: ${GKE_DEPLOY}
spec:
replicas: 2
selector:
matchLabels:
app: ${GKE_DEPLOY}
template:
metadata:
labels:
app: ${GKE_DEPLOY}
spec:
serviceAccountName: ${GKE_SA}
containers:
- name: ${GKE_DEPLOY}
image: ${IMAGE_TAG}
env:
- name: PROJECT_ID
value: ${PROJECT_ID}
- name: LOCATION
value: ${REGION}
ports:
- containerPort: 8080
resources:
requests:
cpu: "250m"
memory: "512Mi"
limits:
cpu: "500m"
memory: "1Gi"
---
apiVersion: v1
kind: Service
metadata:
name: ${GKE_DEPLOY}
spec:
type: LoadBalancer
selector:
app: ${GKE_DEPLOY}
ports:
- protocol: TCP
port: 80
targetPort: 8080
EOF
8. Tester l'application
La dernière étape consiste à accéder à l'application de démonstration et à la tester. Pour ce faire, vous devez récupérer l'adresse IP externe attribuée au service et interagir avec elle via une interface simple.
Récupérer l'adresse IP externe du service
Obtenez l'adresse IP externe du service exposé (le provisionnement prend environ 30 secondes).
export IP_ADDRESS=$(kubectl get service "${GKE_DEPLOY}" -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo $IP_ADDRESS
Exécuter l'interface en local
Pour cette démonstration, l'interface est une simple page HTML/JavaScript qui ne fait pas partie du déploiement GKE. Elle est conçue pour s'exécuter sur votre ordinateur local.
L'interface doit être diffusée à partir de GCP dans une application de production. Sur votre ordinateur local :
# Update the index.html file with the server IP address
cd frontend
# For Linux
sed -i "s#\(const BACKEND_URL = \"http://\)[^/]\+\(\/analyze\";\)#\1${IP_ADDRESS}\2#g" "index.html"
# For MacOS
#sed -i '' "s#\(const BACKEND_URL = #\"http://\)[^/]*\(\/analyze\";\)#\1${IP_ADDRESS}\2#g" "index.html"
python3 -m http.server 8001
Ouvrez http://localhost:8001/index.html dans Chrome.
9. Effectuer un nettoyage
Pour éviter des frais continus, supprimez les ressources créées dans cet atelier de programmation.
Supprimer le cluster GKE
Pour supprimer l'application entière, il vous suffit de supprimer le cluster GKE. Pour ce faire, exécutez la commande suivante :
gcloud container clusters delete "${GKE_CLUSTER}" \
--region="$REGION" \
--project="${PROJECT_ID}"
Supprimer les charges de travail Assured Workloads
Exécutez les commandes suivantes pour supprimer toutes les ressources associées à Assured Workloads.
# Workload project deletion
gcloud billing projects unlink "${PROJECT_ID}"
gcloud projects delete "${PROJECT_ID}"
# KMS project deletion
gcloud billing projects unlink "${KMS_PROJECT_ID}"
gcloud projects delete "${KMS_PROJECT_ID}"
# Assured Workload folder deletion
gcloud resource-manager folders delete ${WORKLOAD_FOLDER_ID} --quiet
# Assured Workload deletion
gcloud assured workloads delete "${ASSURED_WORKLOAD_ID}" \
--location="${REGION}" \
--organization="${GCP_ORGANIZATION}" \
--project="${QUOTA_PROJECT_ID}"
10. Félicitations
Mission accomplie ! Vous avez créé un système de détection de la sécurité sur le lieu de travail pour les secteurs réglementés qui utilise Gemini pour détecter les casques de protection.
Ce que vous avez accompli :
- Protection et confidentialité des données : vous avez provisionné un nœud GKE confidentiel avec CMEK.
- Périmètres de données : vous avez activé les contrôles de conformité de la plate-forme pour un environnement réglementé.