k0s: Kubernetes dans un seul binaire

Dans notre nouvel article traduit, nous donnons un aperçu rapide de la nouvelle distribution Kubernetes. Nous espérons que l'article sera intéressant pour les lecteurs de Habr.


Il y a quelques jours, un ami m'a parlé d'une nouvelle distribution Kubernetes de Mirantis appelée k0s . Nous connaissons et aimons tous les K8, non? Nous avons également été séduits par les K3 , un Kubernetes léger développé par Rancher Labs et remis à la CNCF il y a quelque temps. Il est temps de découvrir la nouvelle distribution k0s!







Après une brève introduction à k0s, nous allons créer un cluster de trois nœuds en suivant ces étapes:



  • Préparation de trois machines virtuelles ( Multipass en action)
  • Installer des k0 sur chacun d'eux
  • Configuration d'un simple fichier de configuration de cluster k0s
  • Initialisation du cluster
  • Accéder au cluster
  • Ajout de nœuds de travail
  • Ajouter un utilisateur


Qu'est-ce que k0s?



k0s est la dernière distribution Kubernetes. La version actuelle est la 0.8.0. Il a été publié en décembre 2020 et le premier commit de l'ensemble du projet a eu lieu en juin 2020.



k0s est livré sous forme de fichier binaire unique sans dépendances du système d'exploitation. Ainsi, il est défini comme une distribution Kubernetes avec des caractéristiques zéro friction / zéro profondeur / coût nul (facile à configurer / pas de dépendances / gratuit).



Dernière version de k0s:



  • Fournit Kubernetes 1.19 certifié (certifié Internet Security Center)
  • Utilise containerd comme runtime de conteneur par défaut
  • Prend en charge les architectures Intel (x86-64) et ARM (ARM64)
  • Utilise intra- cluster etcd
  • Utilise le plugin réseau Calico par défaut (activant ainsi les politiques réseau)
  • Comprend un contrôleur d'accès à la politique de sécurité du pod
  • Utilise DNS avec CoreDNS
  • Fournit des métriques de cluster via Metrics Server
  • Active la mise à l'échelle automatique du pod horizontal (HPA).


De nombreuses fonctionnalités intéressantes viendront dans les prochaines versions, notamment:



  • Runtime de VM compact (j'ai vraiment hâte de tester cette fonctionnalité)
  • Mise à niveau du cluster sans temps d'arrêt
  • Sauvegarde et restauration de cluster


Impressionnant, non? Ensuite, nous verrons comment utiliser k0s pour déployer un cluster à 3 nœuds.



Préparation des machines virtuelles



Tout d'abord, nous allons créer trois machines virtuelles, dont chacune sera un nœud dans notre cluster. Dans cet article, je vais emprunter un chemin rapide et facile et utiliser l'excellent outil Multipass (j'adore) pour préparer des machines virtuelles locales sur MacOS.



Les commandes suivantes créent trois instances d'Ubuntu sur xhyve. Chaque machine virtuelle dispose de 5 Go de disque, 2 Go de RAM et 2 processeurs virtuels (vCPU):



for i in 1 2 3; do 
  multipass launch -n node$i -c 2 -m 2G
done
      
      





Nous pouvons ensuite afficher une liste de machines virtuelles pour nous assurer qu'elles fonctionnent toutes correctement:



$ multipass list
Name      State       IPv4             Image
node1     Running     192.168.64.11    Ubuntu 20.04 LTS
node2     Running     192.168.64.12    Ubuntu 20.04 LTS
node3     Running     192.168.64.13    Ubuntu 20.04 LTS
      
      





Ensuite, nous installerons k0s sur chacun de ces nœuds.



Installation de la dernière version de k0s



La dernière version de k0s peut être téléchargée à partir du référentiel GitHub .



Il a un script d'installation pratique:



curl -sSLf get.k0s.sh | sudo sh
      
      





Nous utilisons ce script pour installer k0s sur tous nos nœuds:



for i in 1 2 3; do 
  multipass exec node$i --bash -c "curl -sSLf get.k0s.sh | sudo sh"
done
      
      





Le script ci-dessus installe k0s dans / user / bin / k0 . Pour obtenir toutes les commandes disponibles, vous exécutez le binaire sans arguments.





Commandes k0s disponibles Nous



pouvons vérifier la version actuelle:



$ k0s version
v0.8.0
      
      





Nous utiliserons certaines des commandes dans les prochaines étapes.



Créer un fichier de configuration



Tout d'abord, vous devez définir un fichier de configuration contenant les informations dont k0s a besoin pour créer un cluster. Sur node1, nous pouvons exécuter la commande default-config pour obtenir la configuration par défaut complète. Entre autres, cela nous permet de déterminer:



ubuntu@node1:~$ k0s default-config

apiVersion: k0s.k0sproject.io/v1beta1

kind: Cluster

metadata:

  name: k0s

spec:

  api:

    address: 192.168.64.11

    sans:

    - 192.168.64.11

    - 192.168.64.11

    extraArgs: {}

  controllerManager:

    extraArgs: {}

  scheduler:

    extraArgs: {}

  storage:

    type: etcd

    kine: null

    etcd:

      peerAddress: 192.168.64.11

  network:

    podCIDR: 10.244.0.0/16

    serviceCIDR: 10.96.0.0/12

    provider: calico

    calico:

      mode: vxlan

      vxlanPort: 4789

      vxlanVNI: 4096

      mtu: 1450

      wireguard: false

  podSecurityPolicy:

    defaultPolicy: 00-k0s-privileged

  workerProfiles: []

extensions: null

images:

  konnectivity:

    image: us.gcr.io/k8s-artifacts-prod/kas-network-proxy/proxy-agent

    version: v0.0.13

  metricsserver:

    image: gcr.io/k8s-staging-metrics-server/metrics-server

    version: v0.3.7

  kubeproxy:

    image: k8s.gcr.io/kube-proxy

    version: v1.19.4

  coredns:

    image: docker.io/coredns/coredns

    version: 1.7.0

  calico:

    cni:

      image: calico/cni

      version: v3.16.2

    flexvolume:

      image: calico/pod2daemon-flexvol

      version: v3.16.2

    node:

      image: calico/node

      version: v3.16.2

    kubecontrollers:

      image: calico/kube-controllers

      version: v3.16.2

  repository: ""

telemetry:

  interval: 10m0s

  enabled: true













  • Options de lancement du serveur API, du Controller Manager et du planificateur
  • Stockage pouvant être utilisé pour stocker les informations du cluster ( etcd )
  • Plugin réseau et sa configuration ( Calico )
  • Version des images de conteneurs avec des composants de gestion
  • Quelques schémas de gestion supplémentaires à déployer lors du démarrage d'un cluster


Nous pourrions enregistrer cette configuration dans un fichier et l'adapter à nos besoins. Mais pour cet article, nous allons utiliser une configuration très simple et la sauvegarder dans /etc/k0s/k0s.yaml . Remarque : puisque nous initialisons le cluster sur node1 , ce nœud servira le serveur API. L'adresse IP de ce nœud est utilisée dans api.address et api.sans (noms alternatifs du sujet) dans le fichier de configuration ci-dessus. Si nous avions des nœuds maîtres supplémentaires et un équilibreur de charge au-dessus d'eux, nous utiliserions également api.sans dans les paramètres



apiVersion: k0s.k0sproject.io/v1beta1

kind: Cluster

metadata:

  name: k0s

spec:

  api:

    address: 192.168.64.11

    sans:

    - 192.168.64.11

  network:

    podCIDR: 10.244.0.0/16

    serviceCIDR: 10.96.0.0/12









L'adresse IP de chaque hôte et équilibreur de charge (ou nom de domaine correspondant).



Initialisation du cluster



Tout d'abord, nous créons une unité systemd sur node1 pour gérer les k0.



[Unit]
Description="k0s server"
After=network-online.target
Wants=network-online.target
 
[Service]
Type=simple
ExecStart=/usr/bin/k0s server -c /etc/k0s/k0s.yaml --enable-worker
Restart=always
      
      





La commande principale est répertoriée ici dans ExecStart ; il démarre le serveur k0s avec la configuration que nous avons enregistrée dans notre fichier à l'étape précédente. Nous spécifions également le paramètre --enable-worker afin que ce premier nœud maître fonctionne également en tant que worker.



Ensuite, nous copions ce fichier dans /lib/systemd/system/k0s.service , redémarrons systemd et démarrons le service nouvellement créé.



ubuntu@node1:~$ sudo systemctl daemon-reload
ubuntu@node1:~$ sudo systemctl start k0s.service
      
      





Par curiosité, vous pouvez vérifier les processus lancés par le serveur k0s:



ubuntu@node1:~$ sudo ps aux | awk ‘{print $11}’ | grep k0s
/usr/bin/k0s
/var/lib/k0s/bin/etcd
/var/lib/k0s/bin/konnectivity-server
/var/lib/k0s/bin/kube-controller-manager
/var/lib/k0s/bin/kube-scheduler
/var/lib/k0s/bin/kube-apiserver
/var/lib/k0s/bin/containerd
/var/lib/k0s/bin/kubelet
      
      





À partir de la sortie ci-dessus, nous pouvons voir que tous les composants principaux sont en cours d'exécution ( kube-apiserver , kube-controller-manager , kube-scheduler , etc.), ainsi que les composants communs aux nœuds master et worker ( containerd , kubelet ). k0s est responsable de la gestion de tous ces composants.



Nous avons maintenant un cluster de 1 nœud. Dans la prochaine étape, nous verrons comment y accéder.



Accéder au cluster



Tout d'abord, nous devons obtenir le fichier kubeconfig généré lors de la création du cluster; il a été créé sur node1 à /var/lib/k0s/pki/admin.conf . Ce fichier doit être utilisé pour configurer kubectl sur la machine locale.



Tout d'abord, nous obtenons le kubeconfig du cluster à partir de node1 :



# Get kubeconfig file
$ multipass exec node1 cat /var/lib/k0s/pki/admin.conf > k0s.cfg
      
      





Ensuite, nous remplaçons l'adresse IP interne par l'adresse IP externe node1 :



# Replace IP address
$ NODE1_IP=$(multipass info node1 | grep IP | awk '{print $2}')
sed -i '' "s/localhost/$NODE1_IP/" k0s.cfg
      
      





Ensuite, nous configurons notre client kubectl local pour communiquer avec le serveur API k0s:



export KUBECONFIG=$PWD/k0s.cfg
      
      





L'une des premières commandes que nous exécutons lorsque nous entrons dans un nouveau cluster est sûrement celle qui affiche une liste de tous les nœuds disponibles - essayons:



$ kubectl get no
NAME    STATUS   ROLES    AGE   VERSION
node1   Ready    <none>   78s   v1.19.4
      
      





Il n'y a rien de surprenant ici. Après tout, node1 n'est pas seulement le nœud principal, mais aussi le nœud de travail de notre premier cluster grâce à l'indicateur --enable-worker , que nous avons spécifié dans la commande start. Sans cet indicateur, node1 ne fonctionnerait que et n'apparaîtrait pas dans la liste des nœuds ici.



Ajout de nœuds de travail



Pour ajouter node2 et node3 au cluster , nous devons d'abord créer un jeton de connexion à partir de node1 (il s'agit d'une étape assez courante car elle est utilisée dans les clusters Docker Swarm et Kubernetes créés avec kubeadm).



$ TOKEN=$(k0s token create --role=worker)
      
      





La commande ci-dessus génère un jeton long (très long). En l'utilisant, nous pouvons joindre node2 et node3 au cluster :



ubuntu@node2:~$ k0s worker $TOKEN
ubuntu@node3:~$ k0s worker $TOKEN
      
      





Remarque: Dans un vrai cluster, nous utiliserions systemd (ou un autre superviseur) pour gérer les processus k0s pour les nœuds worker, comme nous l'avons fait pour le nœud maître.



Notre cluster à trois nœuds est opérationnel, comme nous pouvons le vérifier en affichant la liste des nœuds et en répertoriant à nouveau les nœuds:



$ kubectl get no
NAME    STATUS  ROLES    AGE   VERSION
node1   Ready   <none>   30m   v1.19.4
node2   Ready   <none>   35s   v1.19.4
node3   Ready   <none>   32s   v1.19.4
      
      





Nous pouvons également vérifier les pods s'exécutant dans tous les espaces de noms:





Liste des pods s'exécutant dans le cluster dans tous les espaces de noms



Il y a quelques points à noter ici:



  • Comme d'habitude, nous voyons les pods kube -proxy , les pods de plugins réseau (basés sur Calico), ainsi que les pods CoreDNS.
  • api-server, scheduler controller-manager , , .




K0s version 0.8.0 contient la sous-commande utilisateur . Cela vous permet de créer un kubeconfig pour un utilisateur / groupe supplémentaire. Par exemple, la commande suivante crée un fichier kubeconfig nommé demo pour un nouvel utilisateur , qui se trouve à l'intérieur d'un groupe imaginaire nommé development .



Remarque: dans Kubernetes, les utilisateurs et les groupes sont gérés par un administrateur en dehors du cluster, ce qui signifie qu'il n'y a pas de ressource utilisateur non groupe dans K8.



$ sudo k0s user create demo --groups development > demo.kubeconfig
      
      





Pour une meilleure compréhension, nous allons extraire le certificat client de ce fichier kubeconfig et le décoder à partir de la représentation base64:



$ cat demo.kubeconfig | grep client-certificate-data | awk '{print $2}' | base64 --decode > demo.crt
      
      





Ensuite, nous utilisons la commande openssl pour obtenir le contenu du certificat:



ubuntu@node1:~$ openssl x509 -in demo.crt -noout -text

Certificate:

    Data:

        Version: 3 (0x2)

        Serial Number:

            71:8b:a4:4d:be:76:70:8a:...:07:60:67:c1:2d:51:94

        Signature Algorithm: sha256WithRSAEncryption

        Issuer: CN = kubernetes-ca

        Validity

            Not Before: Dec  2 13:50:00 2020 GMT

            Not After : Dec  2 13:50:00 2021 GMT

        Subject: O = development, CN = demo

        Subject Public Key Info:

            Public Key Algorithm: rsaEncryption

                RSA Public-Key: (2048 bit)

                Modulus:

                    00:be:87:dd:15:46:91:98:eb:b8:38:34:77:a4:99:

                    da:4b:d6:ca:09:92:f3:29:28:2d:db:7a:0b:9f:91:

                    65:f3:11:bb:6c:88:b1:8f:46:6e:38:71:97:b7:b5:

                    9b:8d:32:86:1f:0b:f8:4e:57:4f:1c:5f:9f:c5:ee:

                    40:23:80:99:a1:77:30:a3:46:c1:5b:3e:1c:fa:5c:









  • La propriété de l' émetteur est kubernetes-ca , qui est l'autorité de certification de notre cluster k0s.
  • Le sujet est O = développement, CN = démo ; cette partie est importante car c'est là qu'interviennent le nom et le groupe de l'utilisateur. Étant donné que le certificat est signé par l'autorité de certification du cluster, le plugin sur le serveur api peut authentifier l'utilisateur / le groupe par le nom commun (CN) et l'organisation (O) dans le sujet du certificat.


Tout d'abord, nous demandons à kubectl d'utiliser le contexte défini dans ce nouveau fichier kubeconfig :



$ export KUBECONFIG=$PWD/demo.kubeconfig
      
      





Ensuite, nous affichons à nouveau la liste des nœuds et énumérons les nœuds du cluster:



$ kubectl get no
Error from server (Forbidden): nodes is forbidden: User “demo” cannot list resource “nodes” in API group “” at the cluster scope
      
      





Ce message d'erreur était attendu. Même si api-server



l'utilisateur est identifié (le certificat envoyé avec la demande de l'utilisateur a été signé par l'autorité de certification du cluster), il n'est pas autorisé à effectuer des actions sur le cluster.



Des autorisations supplémentaires peuvent être facilement ajoutées en les créant Role/ClusterRole



et en les attribuant à un utilisateur avec RoleBinding/ClusterRoleBinding



, mais je laisse cette tâche comme un exercice pour le lecteur.



Conclusion



k0s vaut vraiment la peine d'être considéré. Cette approche, lorsqu'un seul fichier binaire gère tous les processus, est très intéressante.



Cet article ne fournit qu'un bref aperçu de k0s, mais je vais certainement suivre son développement et consacrer de futurs articles à cette nouvelle et prometteuse distribution Kubernetes. Certaines des fonctionnalités futures semblent vraiment prometteuses et j'ai hâte de les tester.



All Articles