GCP - Avancé : GKE Autopilot, BigQuery et architecture multi-projet
🎯 Objectifs
- ✅ Opérer GKE Autopilot en production avec Workload Identity et scaling avancé
- ✅ Analyser des données massives avec BigQuery
- ✅ Construire une architecture event-driven avec Pub/Sub
- ✅ Sécuriser avec Cloud Armor et VPC Service Controls
- ✅ Concevoir une architecture multi-projet avec Shared VPC et Terraform
📋 Prérequis
- GCP Intermédiaire (VPC, Cloud SQL, Cloud Run, Cloud Build, GKE de base)
- Kubernetes Avancé (RBAC Kubernetes, Helm, Horizontal Pod Autoscaler)
- Terraform Intermédiaire (modules, state, variables)
☸️ GKE Autopilot en Production
Workload Identity sur GKE
Le Workload Identity est la méthode recommandée pour donner à un pod GKE l'accès aux APIs Google Cloud, sans stocker de clés de compte de service.
Le principe : le Service Account Kubernetes d'un pod est fédéré avec un Service Account GCP. GKE échange automatiquement les tokens.
# Activer Workload Identity sur le cluster
gcloud container clusters update mon-cluster \
--region europe-west9 \
--workload-pool=mon-projet.svc.id.goog
# Créer un Service Account GCP
gcloud iam service-accounts create ksa-mon-app \
--display-name "Service Account pour mon-app sur GKE"
# Accorder les permissions GCP nécessaires
gcloud projects add-iam-policy-binding mon-projet \
--member serviceAccount:ksa-mon-app@mon-projet.iam.gserviceaccount.com \
--role roles/storage.objectViewer
# Lier le KSA Kubernetes au GSA GCP
gcloud iam service-accounts add-iam-policy-binding \
ksa-mon-app@mon-projet.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:mon-projet.svc.id.goog[default/mon-ksa]"Manifeste Kubernetes :
apiVersion: v1
kind: ServiceAccount
metadata:
name: mon-ksa
namespace: default
annotations:
iam.gke.io/gcp-service-account: ksa-mon-app@mon-projet.iam.gserviceaccount.com
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mon-app
spec:
template:
spec:
serviceAccountName: mon-ksa
containers:
- name: mon-app
image: europe-west9-docker.pkg.dev/mon-projet/mon-repo/mon-app:v1.0
# Le pod obtient automatiquement un token GCP via le metadata serverVertical Pod Autoscaler (VPA)
En complément du HPA (horizontal), le VPA ajuste automatiquement les requests et limits CPU/mémoire des pods selon l'utilisation réelle :
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: mon-app-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: mon-app
updatePolicy:
updateMode: "Auto" # Recréera les pods avec les nouvelles resources
resourcePolicy:
containerPolicies:
- containerName: mon-app
minAllowed:
cpu: 100m
memory: 128Mi
maxAllowed:
cpu: 2
memory: 2GiMise à Niveau GKE
# Vérifier les versions disponibles
gcloud container get-server-config --region europe-west9
# Activer l'upgrade automatique (activé par défaut sur Autopilot)
gcloud container clusters update mon-cluster \
--region europe-west9 \
--enable-autoupgrade
# Configurer une maintenance window pour les upgrades
gcloud container clusters update mon-cluster \
--region europe-west9 \
--maintenance-window-start 2024-01-01T02:00:00Z \
--maintenance-window-end 2024-01-01T06:00:00Z \
--maintenance-window-recurrence 'FREQ=WEEKLY;BYDAY=SA,SU'📊 BigQuery
Concept
BigQuery est le data warehouse serverless de GCP. Il permet d'exécuter des requêtes SQL sur des téraoctets de données en quelques secondes, sans gérer d'infrastructure.
💡 Analogie : BigQuery c'est une base de données PostgreSQL, mais qui peut traiter des milliards de lignes aussi vite que quelques milliers. Le secret : un moteur columnar distribué sur des milliers de machines.
Concepts Clés
Projet GCP
└── Dataset (équivalent d'une base de données)
└── Table (données stockées en colonnes)
├── Native table (données dans BigQuery)
├── External table (données dans GCS, Bigtable...)
└── View (requête sauvegardée)Requêtes BigQuery
# Créer un dataset
bq mk \
--dataset \
--location EU \
mon-projet:mon_dataset
# Charger des données depuis GCS (CSV)
bq load \
--autodetect \
--source_format CSV \
mon-projet:mon_dataset.ma_table \
gs://mon-bucket/donnees.csv
# Requête SQL (comptage des commandes par pays)
bq query --use_legacy_sql=false '
SELECT
pays,
COUNT(*) AS nb_commandes,
SUM(montant) AS ca_total
FROM `mon-projet.mon_dataset.commandes`
WHERE DATE(date_commande) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
GROUP BY pays
ORDER BY ca_total DESC
LIMIT 10
'Tarification BigQuery
BigQuery propose deux modèles :
| Modèle | Tarification | Cas d'usage |
|---|---|---|
| À la demande | $5 par To scanné | Requêtes ponctuelles, exploration |
| Slots (Enterprise) | Capacité réservée (100 slots = ~$2000/mois) | Production, requêtes fréquentes |
⚠️ Bonne pratique : utilisez les partitions et le clustering pour réduire la quantité de données scannées et les coûts.
-- Créer une table partitionnée par date (chaque partition = 1 jour)
CREATE TABLE mon_dataset.commandes_partitionnees
PARTITION BY DATE(date_commande)
CLUSTER BY pays, statut
AS SELECT * FROM mon_dataset.commandes;
-- Requête sur une partition spécifique (scan minimal)
SELECT *
FROM mon_dataset.commandes_partitionnees
WHERE date_commande BETWEEN '2024-01-01' AND '2024-01-31'
AND pays = 'France';📨 Pub/Sub
Concept
Pub/Sub est le service de messagerie asynchrone de GCP. Il découple les producteurs des consommateurs : le producteur envoie un message dans un topic, les consommateurs le reçoivent via des subscriptions.
Producteur → Topic → Subscription 1 → Consommateur A (Cloud Run)
→ Subscription 2 → Consommateur B (Cloud Function)
→ Subscription 3 → BigQuery (streaming insert)Créer et Utiliser Pub/Sub
# Créer un topic
gcloud pubsub topics create mon-topic
# Créer une subscription (pull)
gcloud pubsub subscriptions create mon-sub \
--topic mon-topic \
--message-retention-duration 7d \
--ack-deadline 60
# Publier un message
gcloud pubsub topics publish mon-topic \
--message '{"type": "commande", "id": "12345", "montant": 99.99}'
# Consommer les messages
gcloud pubsub subscriptions pull mon-sub \
--auto-ack \
--limit 10 \
--format jsonDead Letter Topics
Si un message ne peut pas être traité après N tentatives, il est renvoyé dans un dead letter topic pour analyse :
# Créer le dead letter topic
gcloud pubsub topics create mon-topic-dlq
# Créer la subscription avec dead letter
gcloud pubsub subscriptions create mon-sub-avec-dlq \
--topic mon-topic \
--dead-letter-topic mon-topic-dlq \
--max-delivery-attempts 5Push Subscription vers Cloud Run
Une push subscription envoie les messages en HTTP vers votre service Cloud Run :
# Créer une push subscription vers Cloud Run
gcloud pubsub subscriptions create mon-sub-push \
--topic mon-topic \
--push-endpoint https://mon-service-xxxx-ew.a.run.app/pubsub \
--push-auth-service-account mon-sa@mon-projet.iam.gserviceaccount.com🔒 Sécurité Avancée
Cloud Armor - Protection contre les attaques
Cloud Armor protège les applications exposées sur un Global HTTP(S) Load Balancer contre les attaques DDoS et les menaces applicatives.
# Créer une politique Cloud Armor
gcloud compute security-policies create ma-politique \
--description "Protection WAF production"
# Règle 1 : Bloquer les 10 principales menaces OWASP
gcloud compute security-policies rules create 1000 \
--security-policy ma-politique \
--expression 'evaluatePreconfiguredExpr("xss-stable")' \
--action deny-403 \
--description "Bloquer les attaques XSS"
# Règle 2 : Rate limiting (max 100 req/min par IP)
gcloud compute security-policies rules create 2000 \
--security-policy ma-politique \
--expression 'true' \
--action throttle \
--rate-limit-threshold-count 100 \
--rate-limit-threshold-interval-sec 60 \
--conform-action allow \
--exceed-action deny-429
# Attacher la politique à un backend service
gcloud compute backend-services update mon-backend \
--global \
--security-policy ma-politiqueVPC Service Controls
Les VPC Service Controls créent un périmètre de sécurité autour des APIs GCP. Même si un attaquant vole des credentials, il ne peut pas exporter des données hors du périmètre.
# Créer une politique d'accès
gcloud access-context-manager policies create \
--organization ORGANISATION_ID \
--title "Politique production"
# Créer un périmètre de service
gcloud access-context-manager perimeters create mon-perimetre \
--policy POLICY_ID \
--title "Périmètre production" \
--resources projects/MON_PROJET_NUM \
--restricted-services storage.googleapis.com,bigquery.googleapis.com \
--access-levels accessPolicies/POLICY_ID/accessLevels/mon-niveau🏢 Architecture Multi-Projet avec Shared VPC
Pourquoi plusieurs projets ?
Séparer les workloads en projets distincts apporte :
- Isolation de la facturation : voir les coûts par équipe/application
- Isolation des ressources : une erreur dans le projet dev n'affecte pas la prod
- Contrôle IAM granulaire : accès par projet, pas global
Shared VPC
Un Shared VPC centralise le réseau dans un projet "hôte" et le partage avec des projets "services" :
Projet Hôte (réseau centralisé)
├── VPC Partagé : 10.0.0.0/8
│ ├── subnet-prod 10.1.0.0/16 → Projet prod
│ ├── subnet-staging 10.2.0.0/16 → Projet staging
│ └── subnet-dev 10.3.0.0/16 → Projet dev
└── Règles de pare-feu centralisées
Projet prod → utilise subnet-prod → ses VMs ont des IPs 10.1.x.x
Projet staging → utilise subnet-staging# Activer le Shared VPC sur le projet hôte
gcloud compute shared-vpc enable mon-projet-hote
# Associer le projet service au projet hôte
gcloud compute shared-vpc associated-projects add mon-projet-service \
--host-project mon-projet-hote
# Dans le projet service, créer une VM dans le subnet partagé
gcloud compute instances create ma-vm \
--project mon-projet-service \
--zone europe-west9-a \
--machine-type e2-standard-2 \
--subnet projects/mon-projet-hote/regions/europe-west9/subnetworks/subnet-prodTerraform pour Architecture Multi-Projet
# modules/gcp-project/main.tf
resource "google_project" "project" {
name = var.project_name
project_id = var.project_id
folder_id = var.folder_id
billing_account = var.billing_account_id
}
resource "google_project_service" "apis" {
for_each = toset(var.enabled_apis)
project = google_project.project.project_id
service = each.value
disable_on_destroy = false
}
# Gérer le state Terraform avec un backend GCS partagé
# backend.tf
terraform {
backend "gcs" {
bucket = "mon-bucket-terraform-state"
prefix = "projets/mon-projet"
}
}💰 Optimisation des Coûts GCP
| Levier | Économie | Outil GCP |
|---|---|---|
| Committed Use Discounts | jusqu'à 57% | Console Billing |
| Spot VMs | jusqu'à 91% | gcloud (--provisioning-model=SPOT) |
| Rightsizing | variable | Recommandations VM dans la console |
| Budget Alerts | - | Cloud Billing Budgets |
| Labels | - | Tags sur ressources pour allocation coûts |
# Lancer une Spot VM (interruptible avec 30 secondes de préavis)
gcloud compute instances create mon-batch \
--machine-type n2-standard-4 \
--zone europe-west9-a \
--provisioning-model SPOT \
--instance-termination-action DELETE
# Créer une alerte de budget
gcloud billing budgets create \
--billing-account BILLING_ACCOUNT_ID \
--display-name "Budget prod novembre" \
--budget-amount 500EUR \
--threshold-rule percent=0.8 \
--threshold-rule percent=1.0📌 Points Clés
- Workload Identity = plus de clés JSON sur GKE ; les pods s'authentifient via OIDC automatiquement
- BigQuery : utilisez les partitions et le clustering pour diviser les coûts par 10 ou plus
- Pub/Sub découple les services ; les dead letter topics permettent d'analyser les messages non traités
- Cloud Armor protège contre DDoS et OWASP ; attachez-le à votre Global Load Balancer
- Shared VPC : centralisez le réseau dans un projet hôte, les projets services l'utilisent sans dupliquer l'infrastructure réseau