SPINNAKER : Cluster Kubernetes Façonnable. Concevoir son Lab en 10min avec YaKEL

SPINNAKER : Cluster Kubernetes Façonnable. Concevoir son Lab en 10min avec YaKEL

kubernetes

Dans un précédent article "Spinnaker : Cloud native continuous delivery pipeline" j’avais présenté une vue d’ensemble du déploiement continu dans le cloud selon Spinnaker. Nous allons maintenant passer à la mise en pratique dans une série de billets qui nous mèneront de l’installation en local de Spinnaker, jusqu’au déploiement multi-cloud. Le focus du présent billet concerne l’installation du cluster. Kubernetes sera notre terrain de jeu, et afin de partir du même pied, je vous propose "YaKEL". YaKEL (Yet Another Kubernetes Environment Lab) est un projet à base de playbook Ansible léger pour l’installation rapide (moins de 10 minutes) d’un lab Kubernetes de 3 noeuds pouvant tenir sur un laptop, que j’ai réalisé pour mes propres besoins d’expérimentation. Le cluster est simple à “customiser” et nécessite les pré-requis suivants :

✓ système d’exploitation : MacOS / Linux

✓ virtualbox : 5.2.8

✓ Vagrant : 2.0.3

✓ Ansible : 2.5.0 sera installé de manière isolé en utilisant python virtualenv afin de ne pas perturber votre version courante d’Ansible si vous l’avez sur votre machine

✓ Visual Studio code (optionnel) : ou tout autre éditeur de code supportant la coloration syntaxique yaml pour plus de lisibilité.

infos1-1

caution1

A la fin de l’installation, 5 à 10 minutes selon votre connexion internet et la capacité de votre laptop, nous obtiendrons le cluster tel que décrit sur le schéma ci-dessous.

warning1

Schéma

Ci-dessous le schéma de principe représentant la cinématique d'élaboration du cluster kube.
schemakube

La stack YaKEL est composée de :

Traefik : Traefik assure le routage du flux http entrant dans le cluster vers les pods applicatifs

CoreDNS : assure le service dns

Calico : notre cni network driver, pour la connectivité réseaux et eventuellement les network policies

Docker : le "container runtime" qu'on ne présente plus

Kubernetes : l'orchestrateur "prod ready" pour les environnements conteneurisés.

Configuration :

Pour la configuration, j’ai regroupé dans le fichier clustervars.yml l’ensemble des paramètres Vagrant, Ansible et Kubernetes qui nous serviront lors des phases de provisioning vagrant up, playbook run Ansible et bootstrap de Kubernetes pour que le tout soit plus "DRY" (Don’t Repeat Yourself) et sans tomber dans l’effet "WET" (Waste Everyone’s Time) y compris pour moi :). Je vais vous décrire les blocs de configuration qui ont leur importance pour la suite des actions.

Pour accéder aux applications du cluster via un domaine personnalisable, il vous faudra renseigner la variable ci-dessous.

vagrant:
  domain_tld: "roklab.ops" 

Puis dans le bloc de configuration qui suit, c’est la définition des noeuds (instance de vm) de notre cluster et les rôles que chacun se voit attribuer. Indiquez ici également ce même nom de domaine "fictif" utilisé pour la variable précédente "domain_tld" accessible uniquement de manière locale sur votre machine (laptop).

ingress:                                     <1>
    edge:
      route: apps.roklab.ops 
      address: 192.168.32.8
      nodename: node02

### -- kubernetes / ansible extra vars / vagrant box variables
server:
    etcd: ## etcd is for ansible only. etcd is on same vm as master    <2>
        nodes:
        - nodename: wakanda
          fqdn: 'wakanda.roklab.ops'
          vagrant_enabled: false # no need to create the etcd vm
          ip: 192.168.32.7
    controlplane:                            <3>
        nodes:
        - nodename: wakanda
          fqdn: 'wakanda.roklab.ops' 
          aliases: 'wakanda'
          vagrant_enabled: true
          ip: 192.168.32.7
          cpu: 2
          ram: 2048
    worker:                                  <4>
        nodes:
        - nodename: node02
          fqdn: 'node02.roklab.ops' 
          aliases: node02
          vagrant_enabled: true
          ip: 192.168.32.8
          cpu: 1
          ram: 1024
        - nodename: node03
          fqdn: 'node03.roklab.ops'
          aliases: node03
          vagrant_enabled: true
          ip: 192.168.32.9
          cpu: 1
          ram: 1024
  • <1> Ingress : permet l’accès à l'applicatif via des urls du type *.apps.roklab.ops ( *.apps.votrefake.domain.local). Il faut savoir que n’importe quel noeud peut assumer le role d’ingress (même le master) grâce aux directives “toleration” et “affinity”. Ici j'ai choisi le node02 pour le déploiement de l'ingress controler (Traefik), mais pour votre propre lab il n'y a aucune contre indication de le mettre sur le master par exemple.

  • <2> Etcd : pour le "cluster state" déployé sur le même noeud que le master, à cet effet, notez la présence du paramètre "vagrant_enabled: false". J’ai implémenté une logique de "skip" dans le fichier Vagrantfile. Lorsque ce paramètre est à "false" cela indique à Vagrant de ne pas créer de vm pour cette instance.

  • <3> Controlplane : l'instance de déploiement de l’apiserver, scheduler, controller manager. "vagrant_enabled: true" indique la création d’une vm Vagrant.

  • <4> Worker : ces noeuds auront principalement le rôle de worker et au choix le rôle d’ingress.

Dans ce deuxième bloc, le provisionner Ansible Vagrant est défini pour l'exécution des playbooks :

provisioner:
    type: 'ansible'
    limit: "ROK8LABZ:localhost"
    extra_vars: 'clustervars.yml'       
    verbose: "vv"
    config_file: 'provisioning/ansible.cfg'
    play:
      clusterplan: 'provisioning/clusterplan.yml'     <1>
      clusterkube: 'provisioning/clusterkube.yml'     <2>
      clusterapps: 'provisioning/clusterapps.yml'     <3>
    tags:
      plan: ["nmcli", "ipvs", "ntp", "hosts", "repo", "sysctl", "yum"]
      kube: ["controlplane", "certs", "certs_upload", "worker", "network", "dns", "kubeconfig"]
      apps: ["heapster", "dashboard", "traefik"]
  • Vagrant passera le fichier clustervars.yml sous forme d’extra_vars au provisionner Ansible

  • <1> Clusterplan : installe des packages et configure l’OS de sorte à améliorer l’experience Vagrant + Kube + CentOS 7

  • <2> Clusterkube : lance l’installation de tous les composants kube : controlplane, worker, network, dns

  • <3> Clusterapps : installe des applications dans le cluster kube telles que : Traefik, heapster, dashboard.

Ce troisième bloc, permet de définir les éléments d'inventory classiques d’Ansible:

ansible_groups: {                           
    ROK8LABZ: ["wakanda", "node02", "node03"],
    'ROK8LABZ:children': ["cluster", "etcd", "storage", "ingress"],
    'ROK8LABZ:vars': { ansible_become: true, ansible_user: 'vagrant' },
    'cluster:children': ["controlplane", "worker"],
    'cluster:vars': { docker_version:  '18.03.0', authorization_modes: ['RBAC', 'Node'] },
    controlplane: ["wakanda"],
    'controlplane:vars': { secure_port: '6443', insecure_port: '8080' },
    worker: ["node02", "node03"],
    etcd: ["wakanda"],
    storage: ["wakanda"],
    ingress: ["node02"]
}
ansible_host_vars: {                        
            wakanda: { prefered_iface: '192.168.32.7', prefered_device: 'eth1'},
            node02: { prefered_iface: '192.168.32.8', prefered_device: 'eth1'},
            node03: { prefered_iface: '192.168.32.9', prefered_device: 'eth1'}
}
  • ansible_groups : pas la peine de présenter ce paramètre qui définit les group_vars d’Ansible ; c'est-à-dire les variables inventory attachées à un même groupe logique d'instances.

  • ansible_host_vars : de même, ici le paramètre parle de lui-même, avec les host_vars d’Ansible. Il rassemble des variables attachées specifiquement à une instance particulière.

Je termine avec ce bloc de configuration qui concerne Kubernetes. Ici je précise les éléments qui ont un impact global sur le cluster kube, tels que le range d’ip pour l’adressage des pods et des services, avec respectivement les variables "pod_cidr_address" et "service_cidr_address". J’indique également la version de Kubernetes à déployer et l’ip du service dns fournit dans cette configuration par coreDNS :

cluster:
    name: "local"
    domain: "cluster.local"
    kubernetes_version: 'v1.10.0'
    networking:
          pod_cidr_address: "172.16.0.0/16"
          service_cidr_address: "172.20.0.0/16"
          dns_service_ip: "172.20.0.2"

Hands-On :

Première étape : activé l'environnement virtualenv et installation d’Ansible. Pour ce faire, récupérer les sources depuis github comme indiqué ci-dessous ou à partir du lien suivant YaKEL.

Setup Environment
$ git clone "https://github.com/jamroks/yakel.git"
$ cd yakel
$ source setupenv.sh

Les trois noeuds de mon cluster, sont composé d’un master et deux workers. Dans la suite de ce tutoriel nous allons décomposé l’installation en trois parties, mais pour les impatients il suffit de lancer la commande Vagrant habituelle "vagrant up". Par souci de clarté je vais décomposer les étapes en trois commandes.

✓ clusterplan
✓ clusterkube
✓ clusterapps

ClusterPlan

Première étape, provisionner les 3 noeuds et configurer le système s'exploitation centOS 7.

$ vagrant up --provision-with clusterplan
ClusterKube

Deuxième étape, installation de Kubernetes. Lancer la commande Vagrant ci-dessous, afin de déclencher l'exécution du playbook Ansible d’installation de Kubernetes.

$ vagrant provision --provision-with clusterkube

Si tout s’est bien déroulé, vous devriez obtenir les fichiers supplémentaires ci-dessous en surbrillance :

tree -L 1
.
├── Vagrantfile
├── ansible-2.5.4
├── clustervars.yml
├── "*kubectl*"
├── "*kubectl.kubeconfig*"
├── provisioning
├── requirements.txt
└── setenv.sh

Vérifions que le cluster est opérationnel en tapant les commandes suivantes :

$ ./kubectl --kubeconfig kubectl.kubeconfig get cs 
  • Affiche le status du cluster, cs = componentstatuses

idea1-1

infos2

Vous devriez obtenir ceci :

NAME                 STATUS    MESSAGE              ERROR
scheduler            Healthy   ok
controller-manager   Healthy   ok
etcd-0               Healthy   {"health": "true"}

En entrant les commandes ci-dessous :

$ export KUBECONFIG=kubectl.kubeconfig
$ ./kubectl cluster-info 

Nous devrions obtenir ce qui suit :

Kubernetes master is running at https://192.168.32.7:6443
CoreDNS is running at https://192.168.32.7:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
ClusterApps

Troisième étape, installation des apps Kubernetes, ici Traefik (l’ingress controller) et le dashboard Kubernetes sont les deux apps que vous pouvez déployer optionnellement. Je vous recommande de déployer au moins Traefik ça rend les choses beaucoup plus simple pour l'accès aux applications.

$ vagrant provision --provision-with clusterapps

Après environ 1 minute, vous pourrez accéder aux interfaces web des kube apps :

  • Traefik : traefik.apps.roklab.ops

  • Dashboard : dashboard.apps.roklab.ops

Ce qui nous donne pour http://dashboard.apps.roklab.ops depuis votre navigateur :

Kubedash

Ce qui nous donne pour http://traefik.apps.roklab.ops :

Traefikdash

Conclusion :

Le cluster Kubernetes est opérationnel, nous sommes prêts à déployer Spinnaker, notre plateforme de continuous delivery multi-cloud. Dans le prochain épisode, nous aborderons la mise en place de la configuration des microservices Spinnaker ainsi que la création d’un premier pipeline de déploiement.

René Okouya

René est tourné vers les architectures haute disponibilité du SI et les plateformes Cloud. Domaines de prédilections : automatisation, monitoring, DevOps, Cloud. Son credo : Design, Operate, Optimize.