Config Connector
Config Connector est un opérateur pour GKE, qui permet de gérer les ressources Google Cloud via des manifestes Kubernetes.
Il peut remplacer Terraform ou travailler conjointement avec Terraform.
Ce memo détaille :
- comment déployer Config Connector sur un cluster GKE
- comment utiliser Config Connector pour gérer des ressources GCP
Liens utiles
-
Documentation d’installation
https://cloud.google.com/config-connector/docs/how-to/advanced-install#namespaced-mode -
Documentation de référence des ressources gcp disponibles :
https://cloud.google.com/config-connector/docs/reference/overview
Créer un cluster Kubernetes de test
gcloud container clusters create "mon-cluster" --zone "europe-west1-b" \
--machine-type "n1-standard-2" --image-type "COS" --disk-size "100" \
--num-nodes "1" --enable-autoscaling --min-nodes "1" --max-nodes "2" \
--network "default" --enable-stackdriver-kubernetes --enable-ip-alias \
--addons ConfigConnector --workload-pool mon-projet-123456.svc.id.goog \
--cluster-version latest
--addons ConfigConnector
permet d’installer automatiquement ConfigConnector sur le cluster--workload-pool PROJECT_ID.svc.id.goog
permet d’activer Workload Identity sur le cluster
Si on est sur un cluster déjà existant il est possible d’activer Workload Identity à postériori :
Activer Workload Identity sur le cluster :
gcloud container clusters update CLUSTER_NAME \
--workload-pool=PROJECT_ID.svc.id.goog
Exemple:
gcloud container clusters update mon-cluster \
--workload-pool=mon-projet-123456.svc.id.goog
Activer Workload Identity sur le node-pool :
gcloud container node-pools update NODE_POOL \
--workload-metadata=GKE_METADATA \
--cluster CLUSTER_NAME
Exemple :
gcloud container node-pools update default-pool \
--workload-metadata=GKE_METADATA \
--cluster mon-cluster
Configuration de ConfigConnector
L’objet suivant est automatiquement créé et configure par défaut le mode namespaced
qui permet d’utiliser config connector au sein de namespaces.
apiVersion: core.cnrm.cloud.google.com/v1beta1
kind: ConfigConnector
metadata:
name: configconnector.core.cnrm.cloud.google.com
...
spec:
mode: namespaced
...
L’autre mode possible est cluster
.
Créer un namespace Kubernetes
Comme nous utilisons le mode namespaced
, nous avons besoin de créer un namespace. Les ressources GCP gérées par Config Connector seront déclarées dans ce namespace.
kubectl create ns mon-namespace
Ajouter une annotation sur le namespace pour définir le projet gcp dans lequel seront créées le resources GCP gérées par config connector :
kubectl annotate ns mon-namespace cnrm.cloud.google.com/project-id=mon-projet-123456
namespace/mon-namespace annotated
Créer un service account GCP
Nous créons un service account GCP avec lequel les différentes ressources GCP seront gérées :
gcloud iam service-accounts create NAMESPACE_GSA --project HOST_PROJECT_ID
Remplacer l’élément suivant :
NAMESPACE_GSA
par le nom du compte de service Google associé à l’espace de nomsHOST_PROJECT_ID
par l’ID du projet hôte
Exemple :
gcloud iam service-accounts create configconnector-test --project mon-projet-123456
Created service account [configconnector-test].
Donner au service account GCP les droits Owner sur le projet
Afin que le service account GCP puisse créer des ressources GCP dans le projet, il faut lui attribuer des droits forts, par exemple owner
du projet :
gcloud projects add-iam-policy-binding MANAGED_PROJECT_ID \
--member="serviceAccount:NAMESPACE_GSA@HOST_PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/owner"
Remplacer l’élément suivant :
MANAGED_PROJECT_ID
par l’ID du projet géréNAMESPACE_GSA
par le nom du compte de service Google associé à l’espace de nomsHOST_PROJECT_ID
par l’ID du projet hôte
Exemple :
gcloud projects add-iam-policy-binding mon-projet-123456 \
--member="serviceAccount:configconnector-test@mon-projet-123456.iam.gserviceaccount.com" \
--role="roles/owner"
Impersonnification via Workload Identity
Cette étape permet de lier le service account GCP (IAM) avec le service account Kubernetes de Config Connector (SA cnrm-controller-manager-mon-namespace dans le du namespace cnrm-system).
Ainsi, le service account Kubernetes pourra obtenir les droits du service account GCP.
gcloud iam service-accounts add-iam-policy-binding \
NAMESPACE_GSA@HOST_PROJECT_ID.iam.gserviceaccount.com \
--member="serviceAccount:HOST_PROJECT_ID.svc.id.goog[cnrm-system/cnrm-controller-manager-NAMESPACE]" \
--role="roles/iam.workloadIdentityUser" \
--project HOST_PROJECT_ID
Remplacer l’élément suivant :
HOST_PROJECT_ID
par l’ID du projet hôteNAMESPACE_GSA
par le nom du compte de service Google associé à l’espace de nomsNAMESPACE
par l’espace de noms
Exemple :
gcloud iam service-accounts add-iam-policy-binding \
configconnector-test@mon-projet-123456.iam.gserviceaccount.com \
--member="serviceAccount:mon-projet-123456.svc.id.goog[cnrm-system/cnrm-controller-manager-mon-namespace]" \
--role="roles/iam.workloadIdentityUser" \
--project mon-projet-123456
Le namespace cnrm-system est le namespace dans lequel config connector créé le service account.
Création du contexte pour Config Connector
Copier le fichier YAML suivant dans un fichier nommé configconnectorcontext.yaml
:
apiVersion: core.cnrm.cloud.google.com/v1beta1
kind: ConfigConnectorContext
metadata:
# you can only have one ConfigConnectorContext per namespace
name: configconnectorcontext.core.cnrm.cloud.google.com
namespace: NAMESPACE
spec:
googleServiceAccount: "NAMESPACE_GSA@HOST_PROJECT_ID.iam.gserviceaccount.com"
Remplacer l’élément suivant :
NAMESPACE
par le nom de l’espace de noms.NAMESPACE_GSA
par le nom du compte de service Google associé à l’espace de nomsHOST_PROJECT_ID
par l’ID du projet hôte
Exemple :
apiVersion: core.cnrm.cloud.google.com/v1beta1
kind: ConfigConnectorContext
metadata:
# you can only have one ConfigConnectorContext per namespace
name: configconnectorcontext.core.cnrm.cloud.google.com
namespace: mon-namespace
spec:
googleServiceAccount: "configconnector-test@mon-projet-123456.iam.gserviceaccount.com"
Appliquer le fichier sur le cluster à l’aide de la commande kubectl suivante :
kubectl apply -f configconnectorcontext.yaml
Créer une ressource avec Config Connector
Voici un exemple de manifeste pour créer un bucket GCS :
Copier le fichier YAML suivant dans un fichier nommé bucket.yaml
:
apiVersion: storage.cnrm.cloud.google.com/v1beta1
kind: StorageBucket
metadata:
annotations:
cnrm.cloud.google.com/force-destroy: "false"
labels:
label-one: "value-one"
# StorageBucket names must be globally unique
name: mon-bucket
namespace: mon-namespace
spec:
lifecycleRule:
- action:
type: Delete
condition:
age: 7
versioning:
enabled: true
cors:
- origin: ["http://example.appspot.com"]
responseHeader: ["Content-Type"]
method: ["GET", "HEAD", "DELETE"]
maxAgeSeconds: 3600
/!\ Ne pas oublier de mentionner le namespace !
Appliquer le fichier sur le cluster à l’aide de la commande kubectl suivante :
kubectl apply -f bucket.yaml
Au bout de quelques secondes un bucket doit être créé dans le projet.
Lister les ressources GCP managées par Config Connector
kubectl -n mon-namespace get gcp
NAME AGE READY STATUS STATUS AGE
storagebucket.storage.cnrm.cloud.google.com/mon-bucket 79m True UpToDate 79m
Empecher la suppression accidentelle d’une ressource gérée par Config Connector
Il suffit de mettre l’annotation suivante sur la ressource :
Annotations:
cnrm.cloud.google.com/deletion-policy: abandon
“Adopter” une resource existante
On installe la ligne de commande config connector
$ gcloud components install config-connector
Dans cet exemple on “adopte” une instance de VM :
$ config-connector export //compute.googleapis.com/compute/v1/projects/mon-projet-123456/zones/europe-west1-b/instances/mon-cluster-default-pool-5b5018b9-qp4n > mon-instance.yaml
pour obtenir le link à exporter :
$ gcloud compute instances describe mon-cluster-default-pool-5b5018b9-qp4n --format "value(selfLink)"
https://www.googleapis.com/compute/v1/projects/mon-projet-123456/zones/europe-west1-b/instances/mon-cluster-default-pool-5b5018b9-qp4n
puis enlever https://www
et remplacer par compute
Enfin, adopter la ressouce :
kubectl apply -f mon-instance.yaml
La ressource doit maintenant apparaître :
$ kubectl -n mon-namespace get gcp
NAME AGE READY STATUS STATUS AGE
computeinstance.compute.cnrm.cloud.google.com/ma-vm 52m True UpToDate 52m
NAME AGE READY STATUS STATUS AGE
storagebucket.storage.cnrm.cloud.google.com/mon-bucket 79m True UpToDate 79m