17 mars 2022

Test de Kapsule de Scaleway, une offre Kubernetes européenne

Kubernetes est un outil qui répond à de nombreux besoins mais qui peut être assez difficile à administrer soit même. Que vaut l’offre Kubernetes de Scaleway ?

Pourquoi acheter une offre Kubernetes ?

Mon article sur Kubernetes explique je pense assez bien l’intérêt de l’outil.
Mais Kubernetes n’est pas si simple que ça à administrer. De nombreux détails d’implémentation demandent une certaine expertise et c’est pour ça que la majorité des cloud providers proposent une offre Kubernetes. C’est du gagnant-gagnant: les clients ont accès facilement à un produit très intéressant tout en bénéficiant de l’expertise et de l’intégration du cloud provider.

J’ai personnellement commencé à sérieusement analyser les offres du marché Français pour un projet personnel où j’ai besoin de Kubernetes.

SLA, prix et type instances

Le control plane a un SLA de 99.95% et est gratuit.

La plus petite instance disponible avec SLA est la GP1-XS (16 GB, 4 CPU) à 0.084€/heure. Il est aussi possible d’utiliser des instances sans SLA, la plus petite étant la DEV1-M (4 GB, 3 CPU, mais beaucoup de surallocation d’après certains retours) à 0.02€/heure.
Une instance GPU (RENDER-S, 45GB, 10 CPU, une carte GPU Tesla P100 qui est une carte vieillissante) est aussi disponible à 1€/heure, et dans certaines zones on peut avoir des instancs Enterprises jusqu’à 384 GB et 94 GPU.

Première remarque de ma part: j’ai toujours été surpris de la taille minimale des instances avec SLA chez Scaleway (même hors offre Kubernetes). Là où tous les cloud provider proposent de petites instances avec SLA, on est obligé chez Scaleway de prendre des instances consommant beaucoup de ressources (et donc chers), ce qui est assez dommage.

Le control plane est gratuit ce qui est appréciable. L’offre supporte le block storage (PersistentVolumeClaim). Le prix des instances est correct.

Version de Kubernetes

La version la plus récente de Kubernetes (1.23.4) est disponible à l’heure où j’écris cet article, ce qui est cool.

Temps de création

Il est temps de créer un cluster. J’ai créé un cluster Kubernetes ayant 3 noeuds de 16 GB et 4 CPU.

Le temps de création est mesuré entre le moment où l’action de création est déclenchée et le moment où tous les noeuds sont marqués Ready au retour de kubectl get node.

J’arrive à un temps de 6 minutes 30. C’est acceptable, bien mieux qu’AWS par exemple mais assez loin d’Exoscale par exemple dont le temps de création sera vers les 2 minutes 30.

Authentification

Maintenant que le cluster est créé, il faut pouvoir y accéder.

Scaleway propose de télécharger le fichier kubeconfig pour s’authentifier au cluster une fois ce dernier créé.
La partie qui m’intéresse ici est le choix de la méthode d’authentification. Scaleway semble utiliser des tokens statiques (--token-auth-file dans l’API server) ayant des permissions administrateur:

users:
- name: test-admin
  user:
    token: <token>

Dommage, le concensus dans la communauté Kubernetes étant que cette méthode d’authentification doit être évitée. Pourquoi ne pas proposer au moins une authentification par certificat ce qui permettrait de gérer les permissions de l’utilisateur dans le cluster (via le sujet du certificat) et la durée de validité (via le TTL) très facilement ?
Scaleway propose la rotation de ces tokens ce qui invalidera tout ceux générés. A noter que quand j’ai testé la rotation mon cluster était injoignable pendant un très long moment (message votre cluster n’est pas encore prêt à être utilisé, API server injoignable…​ pendant plus de 15 minutes).

Il est par contre également possible de configurer un provider OpenID pour s’authentifier au cluster.

Réseau et TLS

Réseau

Scaleway propose le déploiement de plusieurs plugins CNI à la création du cluster: Cilium, Calico, Weave, Flannel. Il n’est pas possible de configurer un réseau privé sur le cluster.

Scaleway déploie Konnectivity dans son cluster. Konnectivity est un outil permettant d’ouvrir un tunnel entre l’API server et les workers, l’agent ouvrant le tunnel vers un serveur tournant à côté de l’API server de Kubernetes. L’API server emprunte ensuite ce tunnel pour communiquer avec le cluster.
L’énorme avantage de Konnectivity est de pouvoir faire tourner le control plane Kubernetes et les workers sans problème sur deux réseaux différents de manière sécurisée.

Sauf que…​ Surprise, malgré l’utilisation de Konnectivity Scaleway laisse ouvert et expose sur internet un grand nombre des services du worker. On retrouve donc exposé:

  • Kubelet (port 10250): bien que protégé par du mTLS exposer Kubelet sur internet est très dangereux et n’a aucun intérêt surtout si on utilise Konnectivity (je rappelle que Konnectivity a été exactement conçu pour résoudre ce problème).

  • Cilium Agent (port 4240): semble être utilisé pour des health checks dans Cilium.

  • Le healthz de kube-proxy (port 10256).

  • Un autre port lié à Cilium (42257).

  • Le port SSH (22).

  • Le /healthz et /metrics de Konnectivity agent (port 8134). Cela expose notamment toutes les métriques de l’agent.

  • Le port 56665, le process étant OpenVPN sur la machine ?

  • Le port 111 qui semble lié à rpcbind (?)

Cela est surprenant.
A la première erreur de configuration, CVE sur un service (et vu les machins exposés c’est possible), mise à jour ratée…​ le risque d’avoir des problèmes est énormément élevé.
Pourquoi exposer cela par défault alors que je le répète, il n’y a aucun intérêt d’un point de vue technique à le faire ?

Est-il possible de corriger la situation côté utilisateur ? Je pense qu’en théorie oui.

Il faudrait configurer un security group sur les noeuds ne permettant le passage du trafic qu’entre les noeuds pour les ports liés au cluster (Cilium, Kubelet) et fermer tout le reste. En effet le plugin CNI n’a besoin d’être ouvert qu’entre les noeuds (et le control plane mais nous pouvons laisser tout le trafic sortant ouvert par défaut) et côté Kubelet le port 10250 n’a également besoin que d’être ouvert entre les noeuds, Konnectivity se chargeant de rediriger le trafic entre workers.

Le fonctionnement de Konnectivity

On voit dans ce schema que Konnectivity agent ouvre un tunnel vers Konnectivity server. L’API server emprunte ce tunnel pour parler aux noeuds. Il n’y a donc pas à exposer de services comme Kubelet sur internet.

Malheureusement les nodepools Scaleway ne semblent pas pouvoir prendre un security group en paramètre à la création.
De plus, il semble toujours impossible chez Scaleway de définir des ouvertures réseaux en référençant d’autres security groups. En effet, sur le cloud et plus particulièrement sur des services comme Kubernetes il est commun de rajouter ou supprimer régulièrement des machines, on ouvre donc des règles entres groupes de machines (du genre: toutes mes machines du groupe "application" peuvent parler aux machines du groupe "base de données").
Cette fonctionnalité permet également de n’ouvrir le trafic qu’au sein d’un même groupe de machine (ce qu’on veut exactement ici).
C’est une fonctionnalité de base du cloud qui ne semble pas disponible ici.

Une solution serait de rajouter les règles IP par IP pour tous vos workers mais vous allez y passer 2 ans et à chaque ajout ou suppression de nouvelles machines (que ce soit dans votre cluster ou ou une machine distante dont vous êtes client) il faudra refaire une mise à jour.

J’ai tenté cette configuration en autorisant tout le trafic entre mes noeuds (tous les ports, TCP et UDP) et en bloquant tout le reste par défaut (mais en laissant le trafic sortant ouvert) mals malheureusement mon cluster ne marchait plus (kubectl log en timeout par exemple alors qu’en théorie je devrais emprunter le tunnel de Konnectivity) et je n’ai pas plus creusé.

Bref, allez voter pour les features qui concernent les security groups.

TLS

Une bonne pratique de Kubernetes est d’utiliser une autorité de certification (CA) pour chaque composant du cluster: control plane, workers, aggregation layer, clients externes (et une pour etcd mais c’est un autre sujet).

Le minimum du minimum est généralement deux CA par cluster. En effet, l’aggregation layer de Kubernetes demande une CA dédiée. C’est d’ailleurs impossible de louper cette information dans la documentation officielle de Kubernetes qui est présente à plusieurs endroits:

Caution: Reusing the same CA for different client types can negatively impact the cluster's ability to function. For more information, see CA Reusage and Conflicts.

Warning: Do not reuse a CA that is used in a different context unless you understand the risks and the mechanisms to protect the CA's usage."

Vu le contenu de la configmap extension-apiserver-authentication dans le namespace kube-system qui contient les CA trust par l’API server et celle de l’aggregation layer, le contenu de mon kubeconfig (partie certificate-authority-data), et le contenu du certificat utilisé par Kubelet (/var/lib/kubelet/pki/ca.crt sur les noeuds) il semble y avoir aussi un raté ici: on dirait bien que c’est la même partout, ce qui est problématique.

Dommage également que metrics-server tourne en --kubelet-insecure-tls (il suffit de passer l’autorité de certification de Kubelet en argument pour régler le problème).

Le sujet du TLS dans un cluster Kubernetes vous intéresse ? Regardez mon article sur le sujet qui explique les bonnes pratiques à implémenter.

Dernier point: Scaleway supporte la création de services LoadBalancer, ce qui permet de contrôler un load balancer Scaleway depuis votre cluster Kubernetes, ainsi que le déploiement d’un ingress controller (nginx) sur le cluster. J’avoue qu’un peu découragé je n’ai pas testé ces fonctionnalités mais pas de raisons que ça ne marche pas.

Personnalisation des noeuds

Scaleway permet de mettre les noeuds dans des Placement group pour éviter que les instances d’un même pool tournent sur le même hyperviseur.

les noeuds peuvent avoir des tags et taints directement configurés via l’API. Il est également possible de passer des arguments supplémentaires à Kubelet (qui est le daemon tournant sur les workers).
L’auto healing est également supporté: si votre noeud ne répond plus l’instance sera automatiquement cyclée. Un autoscaler pour gérer dynamiquement le nombre de noeud est également disponible.

Et on dirait que c’est à peu près tout malheureusement. Pas de réseaux privés, comme dit précédemment pas de firewalling. On est loin des fonctionnalités d’autres acteurs européens comme Exoscale ou de l’offre EKS d’AWS par exemple (pour en citer une autre que je connais bien).

La configuration sshd des noeuds autorise une clé Scaleway à se connecter aux machines (TrustedUserCAKeys /etc/ssh/scaleway.pub), je me demande à quoi ça sert: peut être pour les upgrades ?

Conclusion

Nous ne sommes malheureusement pas sur un produit utilisable en production pour l’instant selon moi.

Pour la petite histoire l’offre Kubernetes d’OVH a également un certain nombre des problèmes listés ici (et d’autres uniques à eux). Pour des entreprises de ce niveau et avec leurs prétentions de leaders européens je trouve cela dommage.

Cela pose aussi question sur la confiance à accorder aux cloud providers. Je suis un grand fan du cloud et de ces concepts mais on se rend compte qu’auditer rapidement les produits est toujours intéressant.

En conclusion, du Kubernetes sur le territoire Français aujourd’hui demande de l’administrer soit même ou bien de partir sur un acteur étranger.

Tags: devops cloud

Add a comment








If you have a bug/issue with the commenting system, please send me an email (my email is in the "About" section).

Top of page