Deep dive: Cloud-Hybrid ou Multi-Cloud avec ISTIO en faisant une installation Multi-cluster

Dans l’article précédent, nous avons vu en détails comment effectuer une installation d’Istio en mode mono-cluster et  control plane unique en prod, et comment l’intégrer avec des outils de monitoring, de tracing ainsi que des outils de visualisation. Nous avons  aussi fait un tour des méthodes de déploiement d’Istio.

En production, pour assurer la  haute disponibilité des workloads, il est préférable d’utiliser un mode multi-cluster. Nous allons donc voir comment Istio peut fonctionner sur plusieurs clusters avec plusieurs control planes comme on le voit sur l’image suivante:

source: https://istio.io/docs/ops/deployment/deployment-models/multi-control.svg

Istio en mode Control plane répliqué sur deux clusters

Le mode control plane répliqué d’istio est un mode où Istio est installé sur chaque cluster avec une configuration identique, et chaque cluster  est soumis à une même gestion en terme de policies et de sécurité. De plus, une autorité de certification commune aux clusters doit être utilisée pour gérer le chiffrement des communications inter-clusters via des passerelles.

source: https://istio.io/docs/setup/install/multicluster/gateways/multicluster-with-gateways.svg

Ce modèle de déploiement est aussi appelé modèle à gateways connectées. C’est un mode où chaque control plane Istio utilise un server CoreDNS, qui permet aux services d’un cluster de communiquer avec les services de l’autre cluster comme  s’ils faisaient partie du même mesh. Ainsi un service du cluster 1 peut appeler un service du cluster 2 avec un nom dns au format svc-nom.cluster-2-namespace.global. Le DNS Kubernetes et le CoreDNS d’Istio sont configurés pour fonctionner ensemble et résoudre le suffixe DNS global.

Installation

Pour effectuer l’installation d’Istio et la configuration du mode multi-cluster, il est important de disposer des éléments suivants:

  • Deux clusters Kubernetes avec des versions: 1.14 ou plus.
  • Les Droits Administrateurs de déployer le control plane d’Istio sur chacun des cluster Kubernetes.
  • L’adresse IP du service istio-ingressgateway dans chaque cluster doit être accessible à partir de tous les autres clusters. Dans notre cas nous sommes sur GKE qui fournit un service de Network Load Balancing (NLB). Ce service nous fournit une adresse ip publique accessible pour chaque cluster..
  • Une autorité de certification. La communication entre clusters nécessite une connexion TLS mutuelle entre les services. Pour activer la communication TLS mutuelle entre les clusters, le composant d’Istio Citadel de chaque cluster sera configuré avec des informations d’identification d’autorité de certification intermédiaire générées par une autorité de certification racine commune.
  • La commande istioctl version 1.4.6 installée avec les différents fichiers d’Istio. 

Pour des informations sur l’installation de cette commande, se référer au lien suivant: 

Déploiement du control plane d’Istio dans chaque cluster

Note: Les actions suivantes sont à effectuer sur chaque cluster

Pour le déploiement d’Istio, nous allons commencer par créer  un secret kubernetes dans chaque cluster. Ce secret va contenir le root certificate, la clé de l’autorité de certification ainsi que les certificats intermédiaires, qui serviront pour la génération de certificats utilisés pour le chiffrement TLS des communications entre microservices des deux clusters gérés par Istio.

Note: le lien suivant décrit comment générer des certificats: https://kubernetes.io/fr/docs/concepts/cluster-administration/certificates/ 

Pour cela  nous utilisons la commande suivante:

Copy to Clipboard

 

Maintenant que nous avons les certificats pour le TLS, nous allons lancer l’installation d’Istio sur chaque cluster.

Nous allons créer un fichier values-istio-multicluster-gateways.yaml avec le contenu suivant:

Copy to Clipboard

 

Il suffit maintenant d’installer Istio sur chaque cluster avec une configuration identique.

Copy to Clipboard

 

On attend que tous les pods soient running:

Copy to Clipboard

Configuration du DNS

Fournir la résolution DNS pour des services qui se trouvent dans un autre cluster, évite de rajouter des configurations supplémentaires aux applications existantes. Les applications s’attendent généralement à résoudre les services par leurs noms DNS et à accéder à l’IP correspondante. Les services locaux d’un cluster partagent un suffixe DNS commun (par exemple, svc.cluster.local). Kubernetes DNS fournit une résolution DNS pour ces services.

Pour fournir une configuration similaire pour les services du cluster distant, il faudra  nommer les services du cluster distant au format <name>. <namespace> .global. Istio est également livré avec un serveur CoreDNS qui fournit une résolution DNS pour ces services. Pour utiliser ce DNS, le DNS de Kubernetes doit être configuré pour bloquer un domaine pour .global.

Dans la liste de pods installés dans le paragraphe précédent, on retrouve istiocoredns. C’est le  serveur DNS qui va gérer la résolution DNS inter-clusters. Il nous faut donc configurer le serveur DNS de Kubernetes pour qu’il dialogue avec le CoreDNS d’Istio en tant que StubDomain.

Un StubDomain est une règle de transfert pour les adresses DNS avec un certain préfixe. Ce qui va permettre au DNS Kubernetes de déléguer la résolution des adresses en “.global” au DNS d’Istio.

Pour notre installation, le dns utilisé c’est KubeDNS. Nous allons donc l’éditer comme suit:

Copy to Clipboard


Communication inter-clusters

Dans cette partie, nous allons voir un exemple de mise en place d’une communication entre deux services se trouvant dans des clusters différents.

Pour accéder à un service se trouvant sur un cluster différent, il faudra configurer un ServiceEntry. L’hôte utilisé dans l’entrée de service doit être de la forme <nom>. <namespace> .global où le nom et le namespace correspondent respectivement au nom et au namespace  du service.

Pour plus d’informations sur les ServiceEntries, se référer à l’article suivant: 

Cluster 1:

On active l’injection sur le namespace default:

Copy to Clipboard

 

Ensuite on déploie l’application httpbin avec le yaml suivant httpbin.yaml:

Copy to Clipboard
Copy to Clipboard


Cluster 2:

On active l’injection sur le namespace default:

Copy to Clipboard

 

Nous allons déployer l’application Sleep dont le yaml sleep est le suivant:

Copy to Clipboard

 

On déploie l’application:

Copy to Clipboard

 

On crée un ServiceEntry pour accéder au service httpbin qui se trouve dans le cluster 1:

Chaque service (dans le domaine DNS .global) doit avoir une adresse IP unique au sein du cluster.

Si les services globaux ont de véritables VIP, comme une ip publique accessible depuis les différents clusters, on peut les utiliser, sinon il est recommandé d’utiliser des IPs de la plage d’adresses de classe E 240.0.0.0/4. Le trafic pour ces adresses IP sera capturé par le sidecar Envoy et acheminé vers le service distant approprié.

Copy to Clipboard

 

L’ip dans le bloc endpoints correspond à l’ip publique du  loadbalancer qui pointe sur la gateway istio du cluster 1.

Les configurations ci-dessus permettront d’acheminer tout le trafic du cluster2 pour httpbin.default.global sur n’importe quel port vers le point de terminaison 35.224.130.49:15443 via une connexion TLS mutuelle.

il ne reste plus qu’à vérifier que l’application sleep arrive bien  à contacter l’application httpbin:

Copy to Clipboard

Conclusion

Nous avons vu comment installer et configurer istio sur deux clusters, ainsi que comment on peut déployer et configurer deux applications sur deux clusters différents afin qu’elles puissent communiquer à travers les gateways d’Istio. Istio permet plusieurs autres modes de déploiements comme indiqué par le lien suivant:

https://istio.io/docs/ops/deployment/deployment-models/