KubeCon/CloudNativeCon 2019 Barcelone

J’avais eu la chance d’assister à la KubeCon Europe de Barcelone. En quelques années l’évenement est devenu  un évènement majeur du cloud européen, par la taille de l’événement, nombre de participants, nombre de sessions et de workshop

Ouverture de la Keynote - Photo Aymeric Weinbach

La keynote d’ouverture rendait hommage à la communauté des développeurs opensource qui travaillent sur la solution avec certains contributeurs qui sont montés sur scène. Également aux autres solutions puisque la présentation à démarré en rappelant que les bonnes idées et les bonnes solutions démarrent souvent en même temps en rappelant la quantité de solutions existantes dont le but est d’orchestrer le cloud azure service fabric ou borg étaient donc cités

Observability - Photo Aymeric Weinbach

Pour rentrer directement dans le technique la kubecon en plus des sessions principales de l’évenement c’est aussi une foule d’événements dont beaucoup de workshops

Voila quelques solutions opensource qui sont à un stade maturité suffisant dans l’écosysteme Kubernetes au sein du CNCF et plutôt dans l’univers Microsoft que j’ai trouvé intéressantes et qui mérite que vous vous intéressiez

At the tiller, Fiskardo, Kefalonia, Greece, June 2019
Helm - Photo by Frank Eiffert / Unsplash

Helm

Helm fait partie des projets qui sont maintenus par la CNCF (Cloud Native Computing Foundation) l’organisme qui organise également la Kubecon

Mais qu’est ce que c’est Helm ? Et bien c’est un package manager pour Kubernetes, l’équivalent de Homebrew pour les mac ou npm pour le node mais pour Kubernetes.

Avec Helm vous installez des « Chart » qui sont les package Helm. Les « Charts » contiennent toutes les définitions de ressource nécessaire pour démarrer une application, un outil ou un service à l’intérieur d’un cluster Kubernetes.

Et il existe des repository de package pour kubernetes comme dans tout bon package manager où vous pourrez trouver des package à installer.

Dans votre cluster Kubernetes vous aller donc installer des « charts »  et il est fort probable que vous alliez installer plusieurs instances du même « chart »  Dans Helm on apppelle ça des « releases ». Par exemple vous avez besoin de plusieurs serveur de base de données vous allez installer plusieurs « releases » du « chart » MySql dans votre cluster Kubernetes, chacun avec son nom propre.

Passons maintenant à un peu de pratique avec un cas concret, je veux installer un serveur mariadb dans mon cluster Kubernetes

La commande  helm search hub mariadb  permettra de faire une recherche en ligne et de trouver les « charts » correspondants

Vous avez aussi la possibilité d’installer les repos en local pour faire des recherche de charts sans avoir besoin de connexion réseau.
helm repo list vous donnera la liste des repo préalablement installé

helm repo add dev https://example.com/dev-charts pour installer un repo

helm search repo mariadb pour faire la même recherche en local

Une fois qu’on sait le « chart » qu’on veut installer et si vous avez tout compris
helm install mon-super-serveur-de-db stable/mariadb  permettra d’installer l’instance nommée « mon-super-serveur-de-db » du « chart » stable/mariadb dans mon cluster Kubernetes

helm uninstall mon-super-serveur-de-db permettra de désinstaller le « chart »

Mais vous me direz tout ça c’est bien joli pour la démo mais dans la vrai vie j’ai plein de configuration à donner à mon serveur pour l’installer. Pas de souci tout est prévu.

helm show values stable/mariadb va vous donner toutes les variables que vous pouvez configurer  il suffit de les mettre dans un beau fichier yaml
echo '{mariadbUser: user0, mariadbDatabase: user0db}' > config.yaml

et de passer le fichier yaml en paramètre
helm install -f config.yaml -n mon-super-serveur-de-db stable/mariadb

Sans rentrer  dans le détail de toutes les commandes il est aussi possible de faire des « rollbacks » .

Et bien sûr vous pouvez faire vos propres « charts » et les intégrer dans votre CI/CD ou les partager sur Github. Helm simplifie vraiment la vie pour installer son serveur Kubernetes.

Virtual Kubelet

Virtual Kubelet est à présent un sandbox project du CNCF à l’origine le projet à été mis en opensource par Microsoft en 2017.

Si vous connaissez un peu Kubernetes vous avez surement entendu parler des Kubelets, mais qu’est ce que c’est un Kubelet ? Kubernetes est composé de nœuds, Un nœud est une machine de travail dans Kubernetes. Un Kubelet est le « node agent » primaire qui tourne sur chaque nœud. Le plus significatif et important controleur dans kubernetes c’est lui qui est responsable d’implémenter le Pod et l’API Node qui gére la couche d’execution du container.

Après ce rappel sur un Kubelet qu’est ce que Virtual Kubelet ? Virtual Kubelet est une implementation open source d’un Kubelet qui  va se faire passer pour un « Kubelet » dont le but est de connecter Kubernetes à d’autres API. Le but primaire est d’étendre l’API Kubernetes vers des plateformes de container serverless comme ACI (Azure Container Instance) ou Fargate. Pour autoriser les nœuds à être hébergé sur des services comme ACI, Aws Fargate, Azure Iot Edge etc…

Virtual Kubelet - Image Github Virtual Kubelet 

Concrètement Virtual Kubelet va s’enregistrer comme un nœud et autoriser à déployer des pod et des containers avec l’Api implémenté par le provider Virtual Kubelet

Passons à un peu de pratique avec un cas d’usage, par exemple utilisons Virtual Kubelet avec Azure AKS le cluster managé Kubernetes dans Azure.

Quand vous créez un cluster Azure Kubernetes Services dans Azure, de base il vous crée un certains nombre de choses dont 3 machines virtuelles. Les nœuds d’AKS sont exécutés dans ces VM sous jacentes. Outre le fait que cela fait une solution plus proche du IAAS, si vous dépassez la capacité des VM pour de nouveaux nœuds ce sera potentiellement assez lent de provisionner de nouvelles VM pour y mettre de nouveaux nœud.

Azure propose ACI  (Azure Container Instance ) une solution CAAS (container as a service ) qui permet de gérer et démarrer simplement des container avec une API .

Et Virtual Kubelet à un provider qui permet d’utiliser ACI, il permettra à votre cluster AKS de s’etendre sur ACI et vous pourrez ainsi utiliser la puissance des 2, les VM créés pour AKS et les container en mode CAAS d’ACI pour une montée en charge rapide

Pour cet exemple il vous faudra :

Le Cli Azure
le Cli Kubernetes Kubectl
le Cli Helm (mais si vous avez suivi l’article jusqu’ici vous l’avez déjà)
Et une souscription Azure

Si c’est la première fois que vous vous connectez avec le cli Azure

az login
az account list -o table
#copier coller l’id de souscritption que vous souhaitez utiliser

export AZURE_SUBSCRIPTION_ID="<SubscriptionId>" 
#Pour activer ACI avec le CLI
az provider register -n Microsoft.ContainerInstance

Première étape créer un cluster AKS :

Créér un ressource group
az group create --name myResourceGroup --locationwesteurope

créer un vnet

az network vnet create resource-groupmyResourceGroup \

--namemyVnet \

--address-prefixes 10.0.0.0/8 \

--subnet-name myAKSSubnet \

--subnet-prefix 10.240.0.0/16

Et son subnet
az network vnet subnet create -resource-group myResourceGroup \

--vnet-namemyVnet \

--namemyVirtualNodeSubnet \

--address-prefixes 10.241.0.0/16
Créer un service principal ( un commpte de service pour Azure AD qui servira à s’authentifier)
az ad sp create-for-rbac --skip-assignment

Prenez note de l’appid et du password qui vous serviront par la suite

az network vnet show --resource-group myResourceGroup --name myVnet --query id -o tsv
et prenez note du vnetid

En remplaçant les appid et vnetid précédemment noté authorizer votre vnet a votre service principal
az role assignment create --assignee <appId> --scope <vnetId> --role Contributor


az network vnet subnet show --resource-group myResourceGroup --vnet-name myVnet --name myAKSSubnet --query id -o tsv
Keda

Et maintenant créez votre cluster aks avec les paramètres créés précedemment

az aks create \

--resource-group myResourceGroup \

--namemyAKSCluster \

--node-count 1 \

--network-plugin azure \

--service-cidr 10.0.0.0/16 \

--dns-service-ip 10.0.0.10 \

--docker-bridge-address 172.17.0.1/16 \

--vnet-subnet-id <subnetId> \

--service-principal <appId> \

--client-secret <password>

activez le addon virtual node nécessaire pour la suite
az aks enable-addons \

--resource-group myResourceGroup \

--namemyAKSCluster \

--addonsvirtual-node \

--subnet-name myVirtualNodeSubnet

Et enfin testez que votre cluster fonctionne

az aks get-credentials --resource-groupmyResourceGroup --name myAKSCluster

kubectl get nodes


Récupérer la master URI de votre kubernetes kubectl cluster-info

export MASTER_URI=<Kubernetes Master>

Déployer Virtual Kubelet dans votre cluster AKS

export RELEASE_NAME=virtual-kubelet
export VK_RELEASE=virtual-kubelet-latest
export NODE_NAME=virtual-kubelet
export CHART_URL=https://github.com/virtual-kubelet/virtual-kubelet/raw/master/charts/$VK_RELEASE.tgz
helm install "$CHART_URL" --name "$RELEASE_NAME" \
  --set provider=azure \
  --set providers.azure.targetAKS=true \
  --set providers.azure.masterUri=$MASTER_URI

Pour valider que Virtual Kubelet est déployé dans votre cluster

kubectl get nodes

Et voila vous êtes prêt à tirer toute la puissance d’Azure et d’AKS

Le Workshop Keda Azure Functions - Photo Aymeric Weinbach

Keda

Keda signifie Kubernetes-based Event Driven Autoscaling

Keda va permettre de faire de l’autoscaling pour des charges kubernetes event driven. Le cas d’usage typique étant le serverless. Il est par exemple possible d’utiliser Keda pour scaler des Azure Functions.  Azure Functions V2 peut fonctionner de façon autonome dans un container Docker. Et vous pouvez ainsi utiliser le framework Azure Functions hors des plans d’hébergement Azure classique et les héberger dans un cluster Kubernetes.

Si tout est clair passons à la pratique avec un exemple sur comment utiliser KEDA pour faire le scaling d’Azure Functions déclenché par une queue de message Azure Storage

Pour cet exemple vous devez avoir :
La dernière version des Azure Function Core Tools V2 installé sur votre machine
Un cluster Kubernetes mais si vous avez suivi jusqu’ici vous devez avoir un cluster AKS
Docker et un docker registry

Démarrons le tutorial :
Commencer par créer un dossier pour notre projet

mkdir hello-keda
cd hello-keda

Initialisons un nouveau projet Azure Functions

func init . --docker

Choisissez Node et Javascript pour l’exemple

Créez une nouvelle fonction QueueTriggered

func new

Vous pouvez laisser le nom par défaut QueueTrigger

Créez un compte de stockage pour y créer la queue de stockage Azure que nous allons nommer js-queue-items

az group create -l westeurope -n hello-keda
az storage account create --sku Standard_LRS --location westus -g hello-keda -n <storage-name>

CONNECTION_STRING=$(az storage account show-connection-string --name <storage-name> --query connectionString)
az storage queue create -n js-queue-items --connection-string $CONNECTION_STRING


une fois le compte créé récupérer la clef du compte de stockage avec la commande

az storage account show-connection-string --name <storage-name> --query connectionString

Et remplacez dans le fichier localsettings.json la valeur de AzureWebJobsStorage

{  "IsEncrypted": false,  "Values": {    "FUNCTIONS_WORKER_RUNTIME": "node",    "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;EndpointSuffix=core.windows.net;AccountName=mystorageaccount;AccountKey=shhhh==="  }}

Remplacez la valeur du binding du QueueTrigger/function.json avec ce que vous avez créé

{  "bindings": [    {      "name": "myQueueItem",      "type": "queueTrigger",      "direction": "in",      "queueName": "js-queue-items",      "connection": "AzureWebJobsStorage"    }  ]}

Modifier le fichier host.json pour être sur que vous avez les bonnes extensions

{    "version": "2.0",    "extensionBundle": {        "id": "Microsoft.Azure.Functions.ExtensionBundle",        "version": "[1.*, 2.0.0)"    }}

Et testez votre projet en local

Func extensions install
func start


Pour testez aller ajouter un message dans la queue de stockage créé précédemment

Une fois que vous avez validé que votre code fonctionne il est temps de le déployer dans notre cluster AKS

Commencez par installer keda

func kubernetes install --namespace keda

Pour confirmer que c’est bien installé

kubectl get customresourcedefinition
NAME                        AGE
scaledobjects.keda.k8s.io   2h

Deux façon de déployer en une ligne avec le cli function

func kubernetes deploy --name hello-keda --registry <docker-user-id>

cela va lancer le build du container et le déployer dans le registry que vous avez donné

Si vous avez installé virtual node dans votre cluster AKS comme précédemment voila comment le déployer

func kubernetes deploy --name hello-keda --registry <docker-user-id> --javascript --dry-run > deploy.yaml

va générer un fichier yaml

modifiez le pour autoriser a être utilisé sur les virtual nodes

spec:      containers:      - name: hello-keda        image: <your-docker-user-id>/hello-keda        env:        - name: AzureFunctionsJobHost__functions__0          value: QueueTrigger        envFrom:        - secretRef:            name: hello-keda      tolerations:      - operator: Exists

Il ne reste plus qu’a lancer le build et le déploiement

docker build -t <your-docker-user-id>/hello-keda .
docker push <your-docker-user-id>/hello-keda
kubectl apply -f deploy.yaml

Normalement après le déploiement vous ne devriez voir aucun pod de déployé

kubectl get deploy

Maintenant testez poussez des messages dans la queue de stockage et regardez les pods augmentez

kubectl get pods -w
Les Cocktais Moléculaire Cloud de Mirantis à la Kubecon - Photo Aymeric Weinbach