samedi , 21 juillet 2018
Home » Tutoriel » Comment créer un cluster Kubernetes 1.10 à l’aide de Kubeadm sur Ubuntu 16.04 ? Partie 1

Comment créer un cluster Kubernetes 1.10 à l’aide de Kubeadm sur Ubuntu 16.04 ? Partie 1

Introduction

Kubernetes est un système d’orchestration de conteneur qui gère les conteneurs à l’échelle. Initialement développé par Google et basé sur son expérience dans la production de conteneurs en production, Kubernetes est open source et activement développé par une communauté autour du monde.

Kubeadm automatise l’installation et la configuration des composants de Kubernetes tels que le serveur API, le gestionnaire de contrôleurs et le Kube DNS. Cependant, il ne crée pas d’utilisateurs et ne gère pas l’installation des dépendances au niveau du système d’exploitation et leur configuration. Pour ces tâches préliminaires, il est possible d’utiliser un outil de gestion de configuration comme Ansible ou SaltStack. L’utilisation de ces outils permet de créer des clusters supplémentaires ou de recréer des clusters existants de manière plus simple et moins sujette aux erreurs.

Dans ce guide, vous allez créer un cluster Kubernetes à partir de zéro en utilisant Ansible et Kubeadm, puis déployer une application Nginx conteneurisée.

Les buts

Votre cluster comprendra les ressources physiques suivantes :

  • Un nœud maître

Le nœud maître (un nœud de Kubernetes fait référence à un serveur) est responsable de la gestion de l’état du cluster. Il exécute Etcd, qui stocke les données de cluster parmi les composants qui planifient les workloads sur les nœuds de travail.

  • Deux nœuds de travail

Les nœuds de travail sont les serveurs sur lesquels s’exécutent vos charges de travail (c’est-à-dire les applications et les services conteneurisés). Un travailleur (worker) continuera d’exécuter votre charge de travail (workload) une fois qu’elle lui aura été affectée, même si le maître s’arrête une fois la planification terminée. La capacité d’un cluster peut être augmentée en ajoutant des travailleurs.

Après avoir terminé ce guide, vous disposerez d’un cluster prêt à exécuter des applications conteneurisées, à condition que les serveurs du cluster disposent de ressources CPU et RAM suffisantes pour vos applications. Presque toutes les applications Unix traditionnelles, y compris les applications Web, les bases de données, les démons et les outils de ligne de commande, peuvent être conteneurisées et exécutées sur le cluster. Le cluster consomme environ 300-500 Mo de mémoire et 10% de CPU sur chaque nœud.

Une fois le cluster configuré, vous allez déployer le serveur Web Nginx pour vous assurer qu’il exécute correctement les charges de travail.

Les conditions préalables

  • Une paire de clés SSH sur votre machine Linux/Mac OS/BSD locale. Si vous n’avez jamais utilisé de clés SSH auparavant, vous pouvez apprendre à les configurer en suivant cette explication sur la configuration des clés SSH sur votre machine locale.
  • Trois serveurs exécutant Ubuntu 16.04 avec au moins 1 Go de RAM. Vous devriez être en mesure d’ouvrir une session SSH sur chaque serveur en tant qu’utilisateur root avec votre paire de clés SSH.
  • Ansible installé sur votre machine locale. Si vous utilisez Ubuntu 16.04 comme système d’exploitation, vous devez installer Ansible. Pour les instructions d’installation sur d’autres plates-formes comme Mac OS X ou CentOS, suivez la documentation d’installation officielle d’Ansible.
  • Être familier avec les playbooks Ansible. Pour cela, vous devez connaître comment écrire des Playbooks Ansible.
  • Connaissance de la façon de lancer un conteneur à partir d’une image Docker.

Étape 1 – Configuration du répertoire de l’espace de travail et du fichier d’inventaire Ansible

Dans cette section, vous allez créer un répertoire sur votre machine locale qui servira d’espace de travail. Vous allez également configurer localement Ansible pour qu’il puisse communiquer et exécuter des commandes sur vos serveurs distants. Pour ce faire, vous allez créer un fichier hosts contenant des informations d’inventaire telles que les adresses IP de vos serveurs et les groupes auxquels appartient chaque serveur.

Sur vos trois serveurs, l’un sera le maître avec une adresse IP affichée en tant que master_ip. Les deux autres serveurs seront des travailleurs et auront les IP worker_1_ip et worker_2_ip.

Créez un répertoire nommé ~/kube-cluster dans le répertoire personnel de votre machine locale et cd dedans :

mkdir ~/kube-cluster
cd ~/kube-cluster

Ce répertoire sera votre espace de travail pour le reste du tutoriel et contiendra tous vos playbooks Ansible. Ce sera également le répertoire dans lequel vous exécuterez toutes les commandes locales.

Créez un fichier nommé ~/kube-cluster/ osts en utilisant nano ou votre éditeur de texte favori :

nano ~/kube-cluster/hosts

Ajoutez le texte suivant au fichier, qui spécifiera des informations sur la structure logique de votre cluster :

~/kube-cluster/hosts

[masters]
master ansible_host=master_ip ansible_user=root

[workers]
worker1 ansible_host=worker_1_ip ansible_user=root
worker2 ansible_host=worker_2_ip ansible_user=root

[all:vars]
ansible_python_interpreter=/usr/bin/python3

Rappelez-vous que les fichiers d’inventaire dans Ansible sont utilisés pour spécifier des informations sur le serveur telles que les adresses IP, les utilisateurs distants et les groupes de serveurs à cibler en tant qu’unité unique pour l’exécution des commandes. ~/kube-cluster/hosts sera votre fichier d’inventaire et vous avez ajouté deux groupes Ansible (masters et workers) à celui-ci en spécifiant la structure logique de votre cluster.

Dans le groupe de maîtres (masters), il y a une entrée de serveur nommée « master » qui liste l’IP du maître (master_ip) et spécifie que Ansible doit exécuter les commandes à distance en tant qu’utilisateur root.

De même, dans le groupe des travailleurs (workers), il existe deux entrées pour les serveurs de travail (worker_1_ip et worker_2_ip) qui spécifient également l’utilisateur Ansible (ansible_user) en tant qu’utilisateur root.

La dernière ligne du fichier indique à Ansible d’utiliser les interpréteurs Python 3 des serveurs distants pour ses opérations de gestion.

Enregistrez et fermez le fichier après avoir ajouté le texte.

Après avoir configuré l’inventaire du serveur avec des groupes, passons à l’installation des dépendances au niveau du système d’exploitation et à la création des paramètres de configuration.

Étape 2 – Création d’un utilisateur non root sur tous les serveurs distants

Dans cette section, vous allez créer un utilisateur non root avec des privilèges sudo sur tous les serveurs afin de pouvoir y accéder manuellement en tant qu’utilisateur non privilégié. Cela peut être utile si, par exemple, vous souhaitez voir des informations système avec des commandes telles que top/htop, afficher une liste de conteneurs en cours d’exécution ou modifier les fichiers de configuration appartenant à root. Ces opérations sont effectuées régulièrement pendant la maintenance d’un cluster, et l’utilisation d’un utilisateur non root pour de telles tâches minimise le risque de modifier ou de supprimer des fichiers importants ou d’effectuer involontairement d’autres opérations dangereuses.

Créez un fichier nommé ~/kube-cluster/initial.yml dans l’espace de travail :

nano ~/kube-cluster/initial.yml

Ensuite, ajoutez la lecture suivante au fichier pour créer un utilisateur non root avec des privilèges sudo sur tous les serveurs. Une lecture dans Ansible est un ensemble d’étapes à effectuer pour cibler des groupes et des serveurs spécifiques. La lecture suivante créera un utilisateur sudo non root :

~/kube-cluster/initial.yml

- hosts: all
  become: yes
  tasks:
    - name: create the 'ubuntu' user
      user: name=ubuntu append=yes state=present createhome=yes shell=/bin/bash

    - name: allow 'ubuntu' to have passwordless sudo
      lineinfile:
        dest: /etc/sudoers
        line: 'ubuntu ALL=(ALL) NOPASSWD: ALL'
        validate: 'visudo -cf %s'

    - name: set up authorized keys for the ubuntu user
      authorized_key: user=ubuntu key="{{item}}"
      with_file:
        - ~/.ssh/id_rsa.pub

Voici une répartition de ce que fait ce playbook :

  • Crée l’utilisateur non root ubuntu.
  • Configure le fichier sudoers pour permettre à l’utilisateur ubuntu d’exécuter des commandes sudo sans invite de mot de passe.
  • Ajoute la clé publique dans votre machine locale (habituellement ~/ .ssh/id_rsa.pub) à la liste des clés autorisées de l’utilisateur distant d’ubuntu. Cela vous permettra d’ouvrir une session SSH sur chaque serveur en tant qu’utilisateur ubuntu.

Enregistrez et fermez le fichier après avoir ajouté le texte.

Ensuite, exécutez le playbook localement en exécutant :

ansible-playbook -i hosts ~/kube-cluster/initial.yml

La commande se terminera dans deux à cinq minutes. À la fin, vous verrez une sortie semblable à celle-ci :

Output
PLAY [all] ****

TASK [Gathering Facts] ****
ok: [master]
ok: [worker1]
ok: [worker2]

TASK [create the 'ubuntu' user] ****
changed: [master]
changed: [worker1]
changed: [worker2]

TASK [allow 'ubuntu' user to have passwordless sudo] ****
changed: [master]
changed: [worker1]
changed: [worker2]

TASK [set up authorized keys for the ubuntu user] ****
changed: [worker1] => (item=ssh-rsa AAAAB3...
changed: [worker2] => (item=ssh-rsa AAAAB3...
changed: [master] => (item=ssh-rsa AAAAB3...

PLAY RECAP ****
master                     : ok=5    changed=4    unreachable=0    failed=0   
worker1                    : ok=5    changed=4    unreachable=0    failed=0   
worker2                    : ok=5    changed=4    unreachable=0    failed=0   

Maintenant que l’installation préliminaire est terminée, vous pouvez passer à l’installation de dépendances spécifiques à Kubernetes.

Étape 3 – Installation des dépendances de Kubernetes

Dans cette section, vous allez installer les paquets au niveau du système d’exploitation requis par Kubernetes avec le gestionnaire de paquets d’Ubuntu. Ces paquets sont :

  • Docker – un runtime de conteneur. C’est le composant qui gère vos conteneurs. La prise en charge d’autres runtimes tels que rkt est en cours de développement dans Kubernetes.
  • kubeadm – un outil CLI qui va installer et configurer les différents composants d’un cluster de manière standard.
  • kubelet – un service/programme système qui s’exécute sur tous les nœuds et gère les opérations au niveau du nœud.
  • kubectl – un outil CLI utilisé pour l’émission de commandes au cluster via son API Server.

Créez un fichier nommé ~/kube-cluster/kube-dependencies.yml dans l’espace de travail :

nano ~/kube-cluster/kube-dependencies.yml

Ajoutez les lectures suivantes au fichier pour installer ces paquets sur vos serveurs :

~/kube-cluster/kube-dependencies.yml

- hosts: all
  become: yes
  tasks:
   - name: install Docker
     apt:
       name: docker.io
       state: present
       update_cache: true

   - name: install APT Transport HTTPS
     apt:
       name: apt-transport-https
       state: present

   - name: add Kubernetes apt-key
     apt_key:
       url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
       state: present

   - name: add Kubernetes' APT repository
     apt_repository:
      repo: deb http://apt.kubernetes.io/ kubernetes-xenial main
      state: present
      filename: 'kubernetes'

   - name: install kubelet
     apt:
       name: kubelet
       state: present
       update_cache: true

   - name: install kubeadm
     apt:
       name: kubeadm
       state: present

- hosts: master
  become: yes
  tasks:
   - name: install kubectl
     apt:
       name: kubectl
       state: present

Le premier jeu dans le playbook fait ce qui suit :

  • Installe Docker, l’environnement d’exécution du conteneur.
  • Installe apt-transport-https, ce qui vous permet d’ajouter des sources HTTPS externes à votre liste de sources APT.
  • Ajoute la clé apt du référentiel APT de Kubernetes pour la vérification des clés.
  • Ajoute le référentiel APT Kubernetes à la liste des sources APT de vos serveurs distants.
  • Installe le kubelet et le kubeadm.

Le second jeu consiste en une seule tâche qui installe kubectl sur votre nœud maître.

Enregistrez et fermez le fichier lorsque vous avez terminé.

Ensuite, exécutez le playbook localement en exécutant :

ansible-playbook -i hosts ~/kube-cluster/kube-dependencies.yml

À la fin, vous verrez une sortie semblable à celle-ci :

Output
PLAY [all] ****

TASK [Gathering Facts] ****
ok: [worker1]
ok: [worker2]
ok: [master]

TASK [install Docker] ****
changed: [master]
changed: [worker1]
changed: [worker2]

TASK [install APT Transport HTTPS] *****
ok: [master]
ok: [worker1]
changed: [worker2]

TASK [add Kubernetes apt-key] *****
changed: [master]
changed: [worker1]
changed: [worker2]

TASK [add Kubernetes' APT repository] *****
changed: [master]
changed: [worker1]
changed: [worker2]

TASK [install kubelet] *****
changed: [master]
changed: [worker1]
changed: [worker2]

TASK [install kubeadm] *****
changed: [master]
changed: [worker1]
changed: [worker2]

PLAY [master] *****

TASK [Gathering Facts] *****
ok: [master]

TASK [install kubectl] ******
ok: [master]

PLAY RECAP ****
master                     : ok=9    changed=5    unreachable=0    failed=0   
worker1                    : ok=7    changed=5    unreachable=0    failed=0  
worker2                    : ok=7    changed=5    unreachable=0    failed=0  

Après l’exécution, Docker, kubeadm et kubelet seront installés sur tous les serveurs distants. kubectl n’est pas un composant requis et n’est nécessaire que pour l’exécution de commandes de cluster. L’installer uniquement sur le nœud maître est logique dans ce contexte, car vous ne lancerez des commandes kubectl qu’à partir du maître. Notez cependant que les commandes kubectl peuvent être exécutées à partir de l’un des nœuds de travail ou de toute machine sur laquelle elles peuvent être installées et configurées pour pointer vers un cluster.

Toutes les dépendances du système sont maintenant installées. Configurons le nœud maître et initialisons le cluster.

Étape 4 – Configuration du nœud maître

Dans cette section, vous allez configurer le nœud maître. Cependant, avant de créer des playbooks, il vaut la peine de maîtriser quelques concepts tels que Pods et les plugins Pod Network, car votre cluster inclura les deux.

Un pod est une unité atomique qui exécute un ou plusieurs conteneurs. Ces conteneurs partagent des ressources telles que les volumes de fichiers et les interfaces réseau en commun. Les pods sont l’unité de base de la planification dans Kubernetes : tous les conteneurs d’un pod sont garantis d’être exécutés sur le même nœud que celui sur lequel le pod est planifié.

Chaque pod a sa propre adresse IP, et un pod sur un nœud devrait pouvoir accéder à un pod sur un autre nœud en utilisant l’IP du pod. Les conteneurs sur un seul nœud peuvent communiquer facilement via une interface locale. Toutefois, la communication entre les modules est plus compliquée et nécessite un composant réseau distinct qui peut acheminer de manière transparente le trafic d’un module sur un nœud vers un module sur un autre.

Cette fonctionnalité est fournie par les plugins Pod network. Pour ce cluster, vous utiliserez Flannel, une option stable et performante.

Créez un classeur Ansible nommé master.yml sur votre ordinateur local :

nano ~/kube-cluster/master.yml

Ajoutez la lecture suivante au fichier pour initialiser le cluster et installer Flannel :

~/kube-cluster/master.yml

- hosts: master
  become: yes
  tasks:
    - name: initialize the cluster
      shell: kubeadm init --pod-network-cidr=10.244.0.0/16 >> cluster_initialized.txt
      args:
        chdir: $HOME
        creates: cluster_initialized.txt

    - name: create .kube directory
      become: yes
      become_user: ubuntu
      file:
        path: $HOME/.kube
        state: directory
        mode: 0755

    - name: copy admin.conf to user's kube config
      copy:
        src: /etc/kubernetes/admin.conf
        dest: /home/ubuntu/.kube/config
        remote_src: yes
        owner: ubuntu

    - name: install Pod network
      become: yes
      become_user: ubuntu
      shell: kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml >> pod_network_setup.txt
      args:
        chdir: $HOME
        creates: pod_network_setup.txt

Voici une répartition de cette pièce :

  • La première tâche initialise le cluster en exécutant kubeadm init. Passer l’argument –pod-network-cidr=10.244.0.0/16 spécifie le sous-réseau privé auquel les adresses IP de pod seront attribuées. Flannel utilise le sous-réseau ci-dessus par défaut ; nous disons kubeadm d’utiliser le même sous-réseau.
  • La deuxième tâche crée un répertoire .kube dans /home/ubuntu. Ce répertoire contient des informations de configuration telles que les fichiers de clés d’administration requis pour se connecter au cluster et l’adresse API du cluster.
  • La troisième tâche copie le fichier /etc/kubernetes/admin.conf généré à partir de kubeadm init vers le répertoire de base de l’utilisateur non-root. Cela vous permettra d’utiliser kubectl pour accéder au nouveau cluster.
  • La dernière tâche est exécutée par kubectl apply pour installer Flannel. kubectl apply -f descriptor.[yml|json] est la syntaxe pour indiquer à kubectl de créer les objets décrits dans le fichier descriptor. [yml|json]. Le fichier kube-flannel.yml contient les descriptions des objets nécessaires à la configuration de Flannel dans le cluster.

Enregistrez et fermez le fichier lorsque vous avez terminé.

Exécutez le playbook localement en exécutant :

ansible-playbook -i hosts ~/kube-cluster/master.yml

À la fin, vous verrez une sortie semblable à celle-ci :

Output

PLAY [master] ****

TASK [Gathering Facts] ****
ok: [master]

TASK [initialize the cluster] ****
changed: [master]

TASK [create .kube directory] ****
changed: [master]

TASK [copy admin.conf to user's kube config] *****
changed: [master]

TASK [install Pod network] *****
changed: [master]

PLAY RECAP ****
master                     : ok=5    changed=4    unreachable=0    failed=0  

Pour vérifier l’état du nœud maître, ouvrez une session SSH avec la commande suivante :

ssh ubuntu@master_ip

Une fois à l’intérieur du noeud maître, exécutez :

kubectl get nodes

Vous allez maintenant voir la sortie suivante :

Output
NAME      STATUS    ROLES     AGE       VERSION
master    Ready     master    1d        v1.10.1

La sortie indique que le nœud maître a terminé toutes les tâches d’initialisation et est dans un état Prêt (Ready) à partir duquel il peut commencer à accepter des nœuds de travailleur et à exécuter des tâches envoyées au serveur API. Vous pouvez maintenant ajouter les travailleurs depuis votre machine locale.

À lire aussi

Comment créer un cluster Kubernetes 1.10 à l’aide de Kubeadm sur Ubuntu 16.04 ? Partie 2

Étape 5 – Configuration des nœuds travailleurs L’ajout de travailleurs (workers) au cluster implique l’exécution …