Tutoriel : Comment déployer Kubernetes chez Exoscale avec Packer et Terraform ? Préparation du dépôt (1/3)

Publié le

Exoscale est un cloud-provider européen basé en Suisse. Ce provider propose une qualité de service et un support excellent. En prime, la sécurité et la confidentialité des données sont largement mises en avant, ce qui facilite grandement la conformité avec la GDPR (General Data Protection Regulation). En effet, Exoscale propose des centres de données en Suisse, en Allemagne, en Autriche et en Bulgarie.

Exoscale met à notre disposition un provider Terraform et un provider Packer, ce qui permet de mettre en œuvre le concept d’Infrastructure as Code facilement.

Installation des pré-requis

Nous utiliserons git pour gérer le code. Nous avons aussi besoin de la commande make.

Nous aurons aussi besoin de Terraform et de Packer ; ici nous faisons le choix d’utiliser Docker pour exécuter ces outils. Ça nous permet de fixer les versions utilisées et de rendre le dépôt fonctionnel sur toutes les plateformes supportées par Docker.

Pour installer Docker :

Sous macOS : https://hub.docker.com/editions/community/docker-ce-desktop-mac/

Sous windows 10 : https://hub.docker.com/editions/community/docker-ce-desktop-windows/

Sous Linux, la procédure varie en fonction de la distribution :

Organisation du dépôt

Nous commençons par initialiser le dépôt avec la commande git init.

Notre dépôt contiendra deux sous-dossiers principaux :

  • packer contiendra la définition d’une image de machine virtuelle pour déployer Kubernetes.
  • terraform contiendra les définitions nécessaires pour créer l’infrastructure Kubernetes chez Exoscale.

Nous allons créer un Makefile à la racine du projet pour piloter Packer et Terraform.

Nous ajoutons un fichier .gitignore avec ce contenu :

# Packer
packer/.packer.d

# Terraform
terraform/.terraform
terraform/.terraform.d
terraform/terraform.tfvars
terraform/terraform.tfstate*
terraform/.terraform.tfstate.lock.info

# Temporary (secret) files
.ssh

Préparation du Makefile

Nous préparons un Makefile pour exécuter les containers Packer et Terraform.

Règles de base

Nous commençons par définir quelques variables qui vont permettre d’utiliser ceux-ci. Ces variables définissent les commandes pour exécuter Packer et Terraform au travers d’un container.

# Packer
PACKER_IMAGE = hashicorp/packer:1.6.6

PACKER = docker run -it --rm \
	-v $(PWD)/packer/:/root \
	--workdir /root \
	$(PACKER_IMAGE)


# Terraform
TERRAFORM_IMAGE = hashicorp/terraform:0.14.5

TERRAFORM = docker run -it --rm \
	-v $(PWD)/terraform/:/root \
	--workdir /root \
	$(TERRAFORM_IMAGE)

Nous pouvons ensuite définir des règles dans le Makefile en appelant $(PACKER) ou $(TERRAFORM).

Nous voulons que Packer et Terraform interagissent avec l’API d’Exoscale qui nécessite une paire clé et un secret. Ces informations sont contenues dans deux variables d'environnement. Nous allons donc définir une règle qui va vérifier la présence de celles-ci :

.PHONY: check-env
check-env:
ifndef EXOSCALE_API_KEY
	$(error EXOSCALE_API_KEY environment variable must be set)
endif
ifndef EXOSCALE_API_SECRET
	$(error EXOSCALE_API_SECRET environment variable must be set)
endif

Les valeurs de ces variables sont disponibles dans l’interface de gestion d’Exoscale. Il existe des clés par défaut, mais il est recommandé d'en générer d'autres.

Dans l'interface d'Exoscale, il faut aller dans "IAM", puis cliquer sur "ADD" :
2021-02-05-Exoscale-Add-APIKeys.jpg

Il faut ensuite nommer la clé, puis cliquer sur "CREATE" :
2021-02-05-Exoscale-Save-APIKeys.jpg

L'écran suivant affichera une paire clé/secret.

Règles pour Packer

Nous avons besoin d’une cible pour construire l’image de machine virtuelle. Nous lançons la commande packer build en spécifiant les deux variables pour les accès à l’API d’Exoscale. La définition de ces variables est vérifiée grâce à une dépendance à check-env. La cible packer.build nécessite que dans notre dépôt, nous ayons un fichier packer/kubernetes.pkr.hcl. Voici la définition de cette cible :

.PHONY: packer.build
packer.build: check-env
	@$(PACKER) build -var api_key="$(EXOSCALE_API_KEY)" -var api_secret="$(EXOSCALE_API_SECRET)" -var zone=$(ZONE) kubernetes.pkr.hcl

Le plugin pour créer des images chez Exoscale doit pouvoir être téléchargé rapidement. Cette règle va s’en charger :

.PHONY: packer.deps
packer.deps:
	mkdir -p $(PWD)/packer/.packer.d/plugins && wget -qO - https://github.com/exoscale/packer-builder-exoscale/releases/download/v0.2.3/packer-builder-exoscale_0.2.2_linux_amd64.tar.gz | tar -xvzf - -C $(PWD)/packer/.packer.d/plugins packer-builder-exoscale

Le plugin est extrait dans notre dépôt dans packer/.packer.d/plugins.

Règles pour Terraform

Du côté de Terraform, les commandes terraform init, terraform apply et terraform destroy seront disponibles avec les règles suivantes :

.PHONY: terraform.init
terraform.init: check-env
	@$(TERRAFORM) init -var api_key="$(EXOSCALE_API_KEY)" -var api_secret="$(EXOSCALE_API_SECRET)" -var zone=$(ZONE)

.PHONY: terraform.apply
terraform.apply: check-env
	@$(TERRAFORM) apply -var api_key="$(EXOSCALE_API_KEY)" -var api_secret="$(EXOSCALE_API_SECRET)" -var zone=$(ZONE)

.PHONY: terraform.destroy
terraform.destroy: check-env
	@$(TERRAFORM) destroy -var api_key="$(EXOSCALE_API_KEY)" -var api_secret="$(EXOSCALE_API_SECRET)" -var zone=$(ZONE)

Ici rien de particulier, comme pour Packer, nous définissons des variables contenant les clés d’API d’Exoscale. Nous ajoutons une variable ZONE qui permettra de définir dans quel datacenter déployer notre infrastructure.

Cette variable a une valeur par défaut (ici la zone est Zurich) :

ZONE ?= "ch-dk-2"

Règles pour se connecter au control-plane Kubernetes

Pour faciliter l’accès au control-plane Kubernetes, une cible va être créée :

.PHONY: ssh-cp
ssh-cp: check-env
	@$(TERRAFORM) output -raw provisioning_private_key > .ssh
	@chmod 0600 .ssh
	@ssh -i .ssh ubuntu@$(shell $(TERRAFORM) output control_plane_public_ip)
	@rm .ssh

Terraform va afficher l’output provisioning_private_key qui est défini dans le code de notre infrastructure. Le contenu de cet output est redirigé vers un fichier .ssh. Grâce à cette clé, la connexion au serveur d’API s'effectue par son IP publique (à travers l’output control_plane_public_ip, qui lui aussi est défini dans le code de l’infrastructure).

A suivre

Dans la prochaine partie, nous verrons comment préparer une image de machine virtuelle pour faciliter les déploiements des nœuds de notre cluster Kubernetes.

PHILIPPE CHEPY

Administrateur Système et Développeur