Déploiement d’un cluster Flink sécurisé sur Kubernetes

Le déploiement sécurisée d’une application Flink dans Kubernetes offre deux options. En supposant que votre Kubernetes est sécurisé, vous pouvez compter sur la plateforme sous-jacente ou utiliser les solutions natives de Flink pour sécuriser votre application de l’intérieur. Notez que ces deux solutions ne sont pas mutuellement exclusive.

Utilisation de la sécurité native à Kubernetes

Des modèles de définition Kubernetes adaptés à Flink sont disponibles en ligne et constituent un point de départ fiable. Le déploiement du JobManager gère 1 réplica. Kubernetes est en charge du redéploiement en cas d’échec.

Isolation du réseau

Par défaut, tous les Pods d’un cluster peuvent communiquer librement entre eux. Autrement dit, lorsqu’un Pod est démarré, il lui est attribué une adresse IP unique accessible depuis les autres Pods. En utilisant les Network Policies, il est possible d’isoler les services exécutés dans des Pods les uns des autres. Les Network Policies sont un ensemble de règles de trafic réseau appliquées à un groupe donné de Pods dans un cluster Kubernetes. Il est possible de restreindre l’accès à un namespace Kubernetes ou aux Pods constituant une application. Une fois les Network Policies appliquées, l’application sera isolée du monde extérieur.

Chiffrement et authentification

Cependant, les communications internes au cluster seront envoyées telles quelles, il en va de même avec le monde extérieur, et aucune stratégie d’authentification n’est en place. Pour chiffrer toutes les communications avec SSL, vous pouvez  introduire une solution de Service Mesh (maillage de service) comme Istio qui se déploiera de manière transparente tout en offrant des fonctionnalités supplémentaires: équilibrage de charge, surveillance ou résilience (réessai, délai, temps limite, …). L’utilisation d’une solution de type Service Mesh est particulièrement intéressante lorsque votre application s’exécute sur un réseau dans lequel vous n’avez pas confiance.

L’accès à l’application depuis l’extérieur ne bénéficie d’aucune authentification. Vous devez fournir un service pour authentifier les accès, qui peut également être implémenté avec une solution de Service Mesh, ou refuser tout accès externe et direct à votre application en déployant un Pod de confiance en charge de la transmission par proxy des communications.

Cette dernière approche est similaire à celle décrite par Marc Rooding et Niels Dennissen d’ING dans leur exposé intitulé «Automating Flink Deployments to Kubernetes». Ils y décrivent leur chaîne de CI/CD qui pousse les instructions de déploiement et les ressources vers un Pod sécurisé ayant accès à leur application Flink.

Utilisation des fonctionnalités sécurité natives de Flink

Concernant la seconde approche, Edward Alexander Rojas Clavijo présente dans la session intitulée «Deploying a secured Flink cluster on Kubernetes» comment intégrer les solutions natives de Flink. Bien que relativement simple dans un environnement Hadoop YARN, SSL et Kerberos présentent tous deux des difficultés en raison de la nature dynamique de l’attribution des IP et de la résolution DNS dans un cluster Kubernetes.

Architecture

L’architecture décrite ci-dessous utilise Kafka en tant que source et destination ainsi que HDFS et ElasticSearch en tant que destination.

Le service JobManager utilise un hostname dédié qui peut être référencé par les instances des TaskManagers ainsi que les scripts de soumission de jobs. Un Pod est assigné à chaque TaskManager. Le nombre de conteneurs est aligné sur le nombre de jobs. Les jobs sont de nature “endless” et “stateful”. Lors de la mise à jour, le TaskManager déploie un checkpoint.

L’utilisation des ConfigMap Kubernetes permet de générer la configuration de Flink, y compris pour la gestion de la mémoire et des checkpoints.

Communication sécurisée avec SSL

Par défaut, chaque communication Flink entre le JobManager et les TaskManagers effectue une validation du hostname. L’approche traditionnelle impliquant la génération de certificats publics et privés pour chaque composant est difficile à intégrer avec une adresse IP et des hostnames dynamiques. Cela nécessite de contacter un serveur PKI pour générer le certificat au démarrage du conteneur avant le démarrage du composant Flink.

Lors de la première itération, l’équipe a utilisé des certificats à base de “*” (Wildcard Certificate).

Le JobManager était configuré en tant que ressource de service. Les services dans Kubernetes obtenaient un nom hostname et les communications étaient acheminées vers le Pod par Kubernetes.

Les taskManagers reposaient sur des définitions de type Stateful Set. Les Stateful Set obtenaient des nom d’hôte prédiqués. Par exemple, le nom de domaine complet “flink-tm-0.flink-tm-svc.namesapce.cluster.local” définissait l’instance TaskManager “flink-tm-0” à l’intérieur du service “flink-tm-svc” dans le namespace. L’isolation de tous les TaskManagers à l’intérieur d’un seul nom de domaine permettait de générer un certificat générique disponible pour le TaskManager.

Dans les Pods effectuant les soumissions, l’interface de ligne de commande n’etait pas configurée pour effectuer la validation du hostname. L’autorité de certification devait être approuvée par le JobManager.

Une limitation rencontré dans l’utilisation de certificats génériques est que le déploiement de l’application Flink est restreint à un seul namespace. Le déploiement dans un nouveau namespace signifie la génération d’un nouveau certificat.

La solution finale sélectionnée consiste à générer un certificat unique envoyé aux Truststores et Keystores avec la validation du hostname et des certificats désactivée.

À partir de la version 1.6, Flink peut effectuer une validation mutuelle, qui est désormais l’approche recommandée pour Kubernetes. Le contenu et le mot de passe des Truststores et Keystores sont exposés en tant que secret Kubernetes, encodés en base64 et montés dans les Pods.

Communication avec les sources et les destinations

Dans l’architecture présentée, l’application Flink communique avec Kafka, HDFS, et Elasticsearch.

Pour activer l’authentification Kerberos entre les composants Flink, il est nécessaire de fournir un accès aux fichiers Keytab à partir de chaque composant. Un secret Kubernetes contient le fichier encodé en base64 qui est exposé à chaque Pod. Une ConfigMap est utilisée pour envoyer les propriétés Kerberos telles que les principaux de service.

Le protocole de sécurité Kafka est “SASL_PLAINTEXT” et requiert le nom du service Kerberos fourni par la ConfigMap.

Les divers certificats SSL des services sources et destinataires sont exposés en tant que secrets montés dans les Pods. Le fichier de définition DockerFile monte et garantit un droit d’accès au dossier “$JAVA_HOME/lib/security/cacerts” qui contient les autorités de certification requises.

ElasticSearch est accessible par requête REST. L’équipe a développé un Pod de communication personnalisé car les versions de Flink pré-1.6 sont incompatibles avec ElasticSearch dans la version 6. Dans leur client HTTP, la vérification de nom d’hôte SSL est invalidée.

Communication entre le TaskManager Flink et le volume physique Kubernetes

L’état de l’application Flink est persisté au travers d’un volume physique exposant un serveur NFS. L’application gère le chiffrement des états, le NFS n’en étant pas capable. Cela permet de répondre à l’exigence de chiffrement en vol et au repos (non pris en charge nativement par NFS).

Les prochaines actions à mener

L’exposé s’est terminé sur les actions futures pour améliorer la sécurité du système, y compris mettre en oeuvre les configurations de sécurité Kubernetes :

  • Utiliser les règles d’accès RBAC
  • Restreindre l’accès à kubectl
  • Utiliser les Network Policies
  • Appliquer les règles de sécurité de Pods (Pods security Policies)

Il est aussi anticipé d’utiliser le Job Cluster Container Entrypoint présent dans Flink 1.6 qui incorpore à la fois le runtime Flink et l’application utilisateur dans un conteneur.


Also published on Medium.

Par |2018-10-09T11:25:39+00:00October 8th, 2018|Big Data, Cyber security|0 commentaire

À propos de l'auteur :

Passionné de programmation, de données et d'entrepreneuriat, je participe à façonner Adaltas pour qu'elle soit une équipe d'ingénieurs talentueux partageant leurs savoir-faire et leurs expériences.

Laisser un commentaire