Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Kubernetes et gestion des secrets dans le cloud : Partie 2

By Alexei LedenevMay 7, 20205 min read

Cette page est également disponible en English, Deutsch, Español, Italiano, 日本語 et Português.

1 2vmdytkvuqf4gosqpgyjka

Stockez clés d'API, mots de passe, certificats et autres données sensibles dans des services cloud-native de gestion des secrets, et accédez-y depuis vos clusters K8s.

Introduction

Les secrets sont essentiels au fonctionnement de nombreux systèmes en production. Leur exposition involontaire figure parmi les principaux risques à traiter en priorité. Les développeurs doivent tout mettre en œuvre pour protéger les secrets de leurs applications.

Le problème se complique encore lorsqu'une entreprise migre vers une architecture en microservices : plusieurs services ont alors besoin d'accéder à différents secrets pour fonctionner correctement. De nouveaux défis émergent : comment distribuer, gérer, surveiller et faire tourner les secrets applicatifs tout en évitant toute exposition involontaire ?

Dans l'article précédent ( Partie I), j'ai présenté une méthode d'intégration des services de gestion des secrets d'AWS et de Google Cloud ( AWS Secrets Manager, AWS SSM Parameter Store et Google Cloud Secret Manager) avec Kubernetes, en ajoutant manuellement l'initContainer doitintl/secrets-init dans un Pod cible.

Dans cet article, je vais présenter une approche Kubernetes-native pour intégrer les services de gestion des secrets cloud évoqués ci-dessus.

Injection automatique des secrets cloud

Il est certes possible de modifier manuellement les fichiers YAML des Deployments Kubernetes pour utiliser secret-init comme système init du conteneur, mais l'idéal serait que cette opération soit prise en charge automatiquement, et uniquement pour les Pods Kubernetes qui référencent des secrets cloud. Heureusement, Kubernetes permet d'inspecter et de modifier n'importe quel Pod avant la création du conteneur, grâce à un mécanisme appelé mutating admission webhook.

doitintl/kube-secrets-init est un projet open source de DoiT International qui implémente un mutating admission webhook Kubernetes dédié à l'injection de secrets cloud, prenant en charge à la fois les secrets gérés AWS et Google Cloud.

kube-secrets-init surveille les clusters Kubernetes pour détecter les Pods nouvellement créés ou mis à jour, et ajoute un initContainer avec l'utilitaire doitintl/secrets-init aux Pods qui référencent des secrets cloud, soit directement (via des variables d'environnement), soit indirectement (via les ressources Kubernetes Secret et ConfigMap).

0 hvfcvwhqc bmz8jd

Intégration avec AWS Secrets Manager

Il suffit de renseigner une référence ARN de secret AWS comme valeur de variable d'environnement. secrets-init résoudra alors cette variable à partir de l'ARN spécifié et récupérera la valeur du secret référencé.

https://gist.github.com/930c9ea733557f9715f976df042bf361

Intégration avec AWS Systems Manager Parameter Store

AWS Systems Manager Parameter Store peut également servir à stocker les paramètres et secrets applicatifs.

Il suffit de renseigner une référence ARN d'AWS Parameter Store comme variable d'environnement. secrets-init résoudra cette variable à partir de l'ARN spécifié et récupérera la valeur du paramètre référencé.

https://gist.github.com/f7d9a81d5e239cdd734989a689d46f82

Intégration avec Google Secret Manager

Il suffit de renseigner un nom de secret Google (préfixé par gcp:secretmanager:) comme valeur de variable d'environnement. secrets-init résoudra cette variable à partir du nom spécifié et récupérera la valeur du secret référencé. Le nom du secret peut inclure une version, afin de cibler une version précise du secret.

https://gist.github.com/d121cce3a9d4664a876deb95f18493d7

Prérequis

AWS

Pour résoudre les secrets AWS depuis AWS Secrets Manager et Parameter Store, l'application secrets-init doit s'exécuter sous un rôle IAM AWS auquel l'une des politiques IAM suivantes est attachée.

Pour AWS Secrets Manager :

https://gist.github.com/7348301b4882a564cbd9644d6697c3eb

Pour AWS Systems Manager Parameter Store :

https://gist.github.com/3f3dd3d015a4c000341491c18ac2c4b7

Dans un cluster EKS, il est recommandé de recourir aux AWS IAM Roles for Service Account. Il est aussi possible d'attribuer un rôle IAM à l'instance EC2 sur laquelle le conteneur s'exécute, mais cette option est considérée comme moins sécurisée.

Google Cloud

Pour résoudre les secrets Google depuis Google Secret Manager, l'application secrets-init doit s'exécuter sous un rôle IAM disposant des permissions nécessaires pour accéder aux secrets souhaités. Vous pouvez par exemple attribuer les deux rôles IAM Google prédéfinis suivants à un compte de service Google : Secret Manager Viewer et Secret Manager Secret Accessor.

Dans un cluster GKE, il est possible d'attribuer un rôle IAM à un Pod Kubernetes via Workload Identity. On peut aussi attribuer un rôle IAM à l'instance GCE sur laquelle le conteneur s'exécute, mais cette option est considérée comme moins sécurisée.

Décommentez le flag --provider=google dans le fichier deployment.yaml.

Déploiement du webhook

  1. Pour déployer le serveur webhook kube-secrets-init, il faut créer un service webhook et un déploiement dans notre cluster Kubernetes. L'opération est plutôt simple, à un détail près : la configuration TLS du serveur. En examinant le fichier deployment.yaml, vous constaterez que les fichiers du certificat et de la clé privée correspondante sont lus depuis les arguments en ligne de commande, et que leur chemin provient d'un volume monté pointant vers un secret Kubernetes :

https://gist.github.com/b861984a2be2f2f63596f089f417cefc

Le point essentiel à retenir : il faut définir le certificat CA correspondant plus tard dans la configuration du webhook, afin que l'apiserver sache qu'il doit l'accepter. Pour l'instant, nous allons réutiliser le script initialement écrit par l'équipe Istio pour générer une demande de signature de certificat. Nous enverrons ensuite la requête à l'API Kubernetes, récupérerons le certificat, puis créerons le secret requis à partir du résultat.

Lancez d'abord le script webhook-create-signed-cert.sh et vérifiez que le secret contenant le certificat et la clé a bien été créé :

https://gist.github.com/43135c6af29328bcd74a37b0df5188f8

Une fois le secret créé, nous pouvons créer le déploiement et le service. Il s'agit de ressources Kubernetes standard. À ce stade, nous n'avons produit qu'un serveur HTTP qui accepte les requêtes via le service sur le port 443 :

https://gist.github.com/3971cf1f46f5a57d11d922ed84b0543f

Configurer le Mutating Admission Webhook

Maintenant que notre serveur webhook tourne, il peut accepter les requêtes de l'apiserver. Il faut toutefois créer au préalable quelques ressources de configuration dans Kubernetes. Commençons par notre validating webhook, puis nous configurerons le mutating webhook. En examinant la configuration du webhook, vous remarquerez qu'elle contient un emplacement réservé pour CA_BUNDLE :

https://gist.github.com/fcafa7ed3b3c3b951b7fad3c0d5fbdb6

Un petit script permet de remplacer l'emplacement CA_BUNDLE dans la configuration par cette CA. Exécutez cette commande avant de créer la configuration du validating webhook :

https://gist.github.com/6d5bb7724cef04e9e6a2af12da917a21

Créez ensuite une configuration de mutating webhook :

https://gist.github.com/f946d6046cc1a76a21526c346ca403c1

Configurer le RBAC pour secrets-init-webhook

Créez un Service Account Kubernetes à utiliser avec secrets-init-webhook :

https://gist.github.com/0cda887b586609cbdbb700f7412e70ad

Définissez les permissions RBAC pour le service account du webhook :

https://gist.github.com/1205f1a5d2f449cc3340a404ea474b77

Conclusion

J'espère que cet article vous sera utile. Vos commentaires et questions sont les bienvenus.

N'hésitez pas non plus à contribuer (Issues, Features, PRs) au projet GitHub doitintl/kube-secrets-init.

Envie de lire d'autres articles d'Alexei ? Consultez notre blog ou suivez Alexei sur Twitter.