Installer Istio avec Kind

Photo by Pixabay from Pexels

TL;DR: Installer Istio sur un cluster Kubernetes in Docker ou Kind, connectez la gateway à l'extérieur, déployez 2 versions d'un même service et répartissez la charge entre les 2 versions du service.

Avant de lire cet article, n'hésitez pas à consulter Introduction au Service Mesh et Kind et build Kubernetes.

Dans ce qui suit vous trouverez:

  • Comment créer un cluster avec Kind pour connecter la Gateway Istio au host
  • Comment installer le profile defaukt d'Istio sur le cluster
  • Comment connecter le controller de la gateway Istio sur le host
  • Comment déployer et répartir l'accès vers 2 versions d'une application

Créer un cluster avec Kind

On supposera que vous avez déjà installé Kind, Kubectl, Docker et Git. Pour utiliser Istio, vous allez créer un cluster Kubernetes avec un noeud Control Plane et deux workers.

Pour cela, vous aller utiliser un fichier de configuration kind-cluster.yaml avec les paramètres suivants comme décrit dans Setting Up An Ingress Controller. Cette configuration indique que le noeud qui sert de control plane aura ses ports 80 et 443 connectés aux ports 80 et 443 de votre machine. Il permet également de créer un label sur le noeuds en question ce qui permettra de s'assurer que le controller de la gateway Istio fonctionnera sur ce noeud.

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  kubeadmConfigPatches:
  - |
    apiVersion: kubeadm.k8s.io/v1beta2
    kind: InitConfiguration
    nodeRegistration:
      kubeletExtraArgs:
        node-labels: "ingress-ready=true"
        authorization-mode: "AlwaysAllow"
  extraPortMappings:
  - containerPort: 80
    hostPort: 80
  - containerPort: 443
    hostPort: 443
- role: worker
- role: worker

Note: Vérifiez que les ports 80 et 443 sont bien libres sur votre machine.

On peut lancer le cluster à l'aide de la commande ci-dessous:

kind create cluster \
   --config=kind-cluster.yaml \
   --image kindest/node:v1.16.3

On pourra vérifier le fonctionnement du cluster à l'aide de la commande ci-dessous:

kubectl get nodes
NAME                 STATUS   ROLES    AGE    VERSION
kind-control-plane   Ready    master   2m4s   v1.16.3
kind-worker          Ready    <none>   90s    v1.16.3
kind-worker2         Ready    <none>   90s    v1.16.3

Installer Istio sur le cluster

Pour installer Istio, vous pouvez vous reporter à la section Getting Started de la documentation Istio. En particulier, vous pouvez, télécharger Istio et ajouter le répertoire qui contient istioctl à votre variable PATH:

curl -L https://istio.io/downloadIstio | sh -
cd istio-*
export PATH=$PWD/bin:$PATH

Pour installer Istio avec le profile default et la sécurité activé sur le cluster, lancez la commande ci-dessous puis activez l'injection automatique des sidecars dans le namespace default en ajoutant un label:

istioctl manifest apply --set profile=default \
  --set values.global.mtls.enabled=true \
  --set values.global.controlPlaneSecurityEnabled=true

kubectl label namespace default istio-injection=enabled

Vous pouvez vérifier que Istio est correctement installé:

istioctl experimental analyze -k

Vous pouvez également vérifier que les services Istio sont démarrés:

kubectl get pod -n istio-system

Connecter le controller de la gateway Istio sur le host

Si vous essayer de vous connecter à votre machine sur le port 80, vous devez avoir un message indiquant que celui-ci n'est pas ouvert:

curl -v http://localhost
curl -v https://localhost

Vous allez modifier le déploiement istio-ingressgateway, connecter les ports associés au pod du controller sur les port 80 et 443 de sorte que le noeud associés utilise ses ports. Vous allez également modifier ses paramètre pour assurer que le pod utilise bien le noeud avec le label ingress-ready à true soit, du fait de l'installation, le control plane du cluster:

kubectl patch deployments -n istio-system istio-ingressgateway \
  -p '{
  "spec": {
    "template": {
      "spec": {
        "containers": [
          {
            "name": "istio-proxy",
            "ports": [
              {
                "containerPort": 80,
                "hostPort": 80
              },
              {
                "containerPort": 443,
                "hostPort": 443
              }
            ]
          }
        ],
        "nodeSelector": {
          "ingress-ready": "true"
        },
        "tolerations": [
          {
            "key": "node-role.kubernetes.io/master",
            "operator": "Equal",
            "effect": "NoSchedule"
          }
        ]
      }
    }
  }
}' 

Si vous vérifiez que vous accédez aux ports 80 et 443, vous devez constater que les ports sont accessibles. Le service renvoie le status HTTP-404 pour le port 80 et n'a pas de certificat SSL pour le port 443:

curl -v http://localhost
curl -v https://localhost

Note: Si vous lanvez la commande ci-dessous, vous verrez que l'adresse externe du controller de la gateway reste en état pending. C'est attendu du fait que Kind n'intégre pas de Loadbalancer.

kubectl get svc/istio-ingressgateway -n istio-system

Déployer et répartir l'accès vers 2 versions d'une application

La suite de la configuration consiste à créer 2 applications nommées helloworld-v1 et helloworld-v2 lesquelles sont managées par des deployment et des service kubernetes.

Pour récupérer le code de cet exemple, vous pouvez créer un fork ou un clone de easyteam-fr/side-effects. L'exemple associé est dans le répertoire blog/istio-traffic-shifting

Créez les 2 applications, vous constaterez qu'un sidecar est ajouté à chacune d'entre-elle:

kubectl apply -f helloworld-v1.yaml
kubectl apply -f helloworld-v2.yaml

kubectl get pods
NAME                             READY   STATUS    RESTARTS   AGE
helloworld-v1-7695cb4556-dbm6w   2/2     Running   0          2m14s
helloworld-v2-58b576ddf4-86t4p   2/2     Running   0          7s

kubectl get svc
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
helloworld-v1   ClusterIP   10.110.12.220   <none>        5000/TCP   2m34s
helloworld-v2   ClusterIP   10.97.220.209   <none>        5000/TCP   27s

Vous pouvez ensuite ajouter, une Gateway Istio ainsi qu'un VirtualService avec une règle de répartition 80/20 entre les 2 applications

kubectl apply -f loadbalancing.yaml

Vous pouvez alors tester le loadbalancing

for i in $(seq 100); do curl --silent localhost/hello; done | sort | uniq -c
     81 Hello version: v1, instance: helloworld-v1-7695cb4556-dbm6w
     19 Hello version: v2, instance: helloworld-v2-58b576ddf4-86t4p

Note: Kubernetes ne permet pas de choisir la répartition de la charge entre des pods; pour arriver au même résultat, il faudrait déployer 4 pods en v1 et 1 pod en v2.

Continuer

Dans cet article, vous avez pu voir comment créer un cluster Kind pour Istio, comment installer Istio, comment exposer la gateway Istio sur le host et comment utiliser la gestion du trafic des VirtualService pour répartir la charge entre 2 services. Istio est un outil qui permet de faire beaucoup, beaucoup plus... Vous le découvrirez dans les prochains articles.

Published under ,  on .

Easyteam DevOps

Easyteam DevOps