K8s on vSphere with Cluster API === > [name=Alexandre CAUSSIGNAC] > [time=Dimanche 12 Avril 2020] Préambule --- Ce post est le second d'une série de quatre articles axés autour du moteur d'orchestration Kubernetes (K8s) et qui ont pour objectif d'expliquer comment passer d'un mode *Do It Yourself* (DIY) à une plateforme de conteneurs pleinement fonctionnelle, supportée et scalable. 1. [K8s on vSphere (DIY)](https://hackmd.io/@ac09081979/K8s_on_vSphere) 1. **[K8s on vSphere with Cluster API (DIY)](https://hackmd.io/@ac09081979/K8s_on_vSphere_with_Cluster_API)** 1. [Tanzu Kubernetes Grid (TKG) on vSphere](https://hackmd.io/@ac09081979/TKG) 1. [vSphere with K8s (Pacific)](https://hackmd.io/@ac09081979/vSphere_with_K8s) Introduction --- Kubernetes (K8s) a été pensé pour changer radicalement la façon dont les applications sont créées et déployées dans le Cloud. Il a été conçu pour donner aux développeurs plus de rapidité, d’efficacité et d’agilité. Les avantages qui incitent les entreprises à utiliser des conteneurs et des orchestrateurs de conteneurs comme K8s sont : * Vitesse * Évolution du logiciel et des équipes * Abstraction de l’infrastructure * Efficacité * Portabilité Mais avant de pouvoir bénéficier de tous ces avantages, il est nécessaire de mettre à disposition des clusters production ready répondant aux standards de la [CNCF](https://www.cncf.io/) (Day1) ainsi que de faire évoluer régulièrement ces composants au regard d’une roadmap soutenue (Day2). Car il ne faut pas perdre de vue que K8s est un orchestrateur dit évolutif capable d’apprendre de nouvelles choses via les *Custom Resources Definition* et de s’intégrer à un large écosystème via les interfaces mais qui s’appuient au final sur des ressources calcul, réseau et stockage. Historiquement, il s’est vite posé la question d’avoir un outil capable de démarrer un cluster K8s respectant les bonnes pratiques de la CNCF. De là est né le projet Kubeadm qui a pour unique vocation d’amorcer (bootstrapping) un cluster et être éventuellement appelé par d’autres installateurs (Terraform, Ansible, …). Mais au-delà d’un manque d’uniformité des modes d’installation, un certain nombre de questions restaient en suspens : * Comment provisionner le reste de l’infrastructure (Load Balancer, Resources Pools, VPC, …) ? * Comment gérer le cycle de vie (mise à jour, destruction, …) ? * Comment déclarer le tout via une API centrale ? * … Et c’est là qu’intervient le projet Open Source [Cluster API](https://github.com/kubernetes-sigs/cluster-api). Cluster API gère de manière homogène des clusters K8s tout comme K8s gère des conteneurs (immutabilité et état déclaratif). Pour en savoir plus sur la genèse de ce projet, je vous renvoie vers le [blog](https://blog.heptio.com/the-kubernetes-cluster-api-de5a1ff870a5) de Kris Nova. ![](https://i.imgur.com/kfPO85A.png) Tout comme K8s, Cluster API a été pensée selon les principes de la philosophie d’Unix, à savoir faire une chose mais la faire bien. Chercher à être le meilleur dans sa spécialité plutôt que moyen partout. Cluster API est donc une boîte à outils spécialisée dans la construction, la mise à jour et la destruction de clusters K8s avec pour vocation d'être invoquée par d'autres outils. Il reste un projet de K8s mais n'a pas vocation à être intégré dans l'API Core de K8s. A ce jour, les principales infrastructures ([Provider](https://cluster-api.sigs.k8s.io/reference/providers.html) prises en charge par Cluster API sont AWS, Azure, Digital Ocean, GCP, IBM Cloud, OpenStack et [vSphere](https://github.com/kubernetes-sigs/cluster-api-provider-vsphere). L'équivalent de Cluster API chez Red Hat se nomme Machine API qui se base sur Cluster API et y ajoute des composants spécifiques à la plateforme OpenShift (*The Machine API is a combination of primary resources that are based on the upstream Cluster API project and custom OpenShift Container Platform resources*). ![](https://i.imgur.com/iAamqMI.png) Environnement de Lab --- Ce lab est un environnement dit *nested*. Il y a quatre serveurs physiques sur lesquels j'ai déployé quatre hyperviseurs vSphere (en machines virtuelles) et un vCenter Server Appliance (VCSA). Pour faire ça, j'ai utilisé un super outil appelé [cPodFactory](https://github.com/bdereims/cPodFactory) qui a été créé et est maintenu par mon collègue [Brice DEREIMS](https://fr.linkedin.com/in/brice-dereims-65a3a4). Même s'il n'est pas possible de l'utiliser en production pour des raisons de support, il reste très utile pour tous types de tests. > Si vous disposez déjà d'un environnement vSphere équivalent, vous pouvez vous rendre directement à la section suivante. Voici les produits et versions utilisés durant ce lab: | Product | Version | | -------------------------------- | ------------------------------------- | | VMware vSphere Hypervisor (ESXi) | 6.7 Update 3 (Build Number: 14320388) | | VMware vCenter Server Appliance | 6.7 Update 3 (Build Number: 14367737) | | Ubuntu | 18.04.4 LTS | | govc | 0.22.1 | | Docker | version 19.03.6, build 369ce74a3c | | kubectl | 1.18.0 | | Kind | 0.7.0 | | Clusterctl | 0.3.0-rc.3 | | CAPV image | photon-3-kube-v1.17.3 | | HAProxy image | capv-haproxy-v0.6.3 | Ainsi que les détails réseaux sur les composants installés: | IP | FQDN | | ----------- | ---------------------------------------- | | 172.20.6.3 | vcsa.cpod-aca-k8s.az-lab.shwrfr.com | | 172.20.6.21 | esx-01.cpod-aca-k8s.az-lab.shwrfr.com | | 172.20.6.22 | esx-02.cpod-aca-k8s.az-lab.shwrfr.com | | 172.20.6.23 | esx-03.cpod-aca-k8s.az-lab.shwrfr.com | | 172.20.6.24 | esx-04.cpod-aca-k8s.az-lab.shwrfr.com | | 172.20.6.30 | admcli.cpod-aca-k8s.az-lab.shwrfr.com | | Range/Subnet | Function | | ------------------------- | ------------ | | 172.20.6.100-172.20.6.199 | K8s services | | 172.20.6.200-172.20.6.254 | DHCP | Préparation du Lab --- - [ ] Créer un cPod (appelé ACA-K8S dans ce tutoriel) - [ ] Déployer un VCSA - [ ] Récupérer le mot de passe généré - [ ] Se connecter au vCenter et mettre à jour les licences - [ ] Mettre à jour la table host du cPod router > Le cPod router (basé sur PhotonOS) offre ces différents services: BGP, DHCP, DNS, L3 gateway, NFS server, routing. ``` root@cpodrouter-aca-k8s [ ~ ]# cat /etc/hosts # Begin /etc/hosts (network card version) ::1 localhost ipv6-localhost ipv6-loopback 127.0.0.1 localhost.localdomain 127.0.0.1 localhost 172.20.6.1 cpodrouter cpod # End /etc/hosts (network card version) 172.20.6.2 cpodfiler 172.20.6.24 esx-04 172.20.6.23 esx-03 172.20.6.22 esx-02 172.20.6.21 esx-01 172.20.6.3 vcsa 172.20.6.30 admcli ``` - [ ] Ajouter un *wildcard* DNS pour tous les services K8s de type Ingress (dernière ligne) ``` root@cpodrouter-aca-k8s [ ~ ]# cat /etc/dnsmasq.conf listen-address=127.0.0.1,172.20.6.1,172.16.2.16 interface=lo,eth0,eth1 bind-interfaces expand-hosts bogus-priv #dns-forward-max=150 #cache-size=1000 domain=cpod-aca-k8s.az-lab.shwrfr.com local=/cpod-aca-k8s.az-lab.shwrfr.com/ server=/az-lab.shwrfr.com/172.16.2.1 server=172.16.2.1 no-dhcp-interface=lo,eth1 dhcp-range=172.20.6.200,172.20.6.254,255.255.255.0,12h dhcp-option=option:router,172.20.6.1 dhcp-option=option:ntp-server,172.20.6.1 dhcp-option=option:domain-search,cpod-aca-k8s.az-lab.shwrfr.com address=/.apps.cpod-aca-k8s.az-lab.shwrfr.com/172.20.6.100 root@cpodrouter-aca-k8s [ ~ ]# systemctl restart dnsmasq.service ``` - [ ] Ajouter les *neighbors* (futurs worker nodes provisionnés par Cluster API) à la configuration BGP du cPod router (cf section sur metallb) -> cette partie sera réalisée plus tard si vous utilisez BGP > Vous n'êtes pas obligé d'utiliser BGP mais vous pouvez utiliser du routage statique. ``` root@cpodrouter-aca-k8s [ ~ ]# cat /etc/quagga/bgpd.conf ! -*- bgp -*- ! ! BGPd sample configuratin file ! ! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $ ! hostname bgpd password VMware1! enable password VMware1! ! !bgp mulitple-instance ! router bgp 65216 bgp router-id 172.16.2.16 neighbor 172.16.2.1 remote-as 65200 neighbor 172.20.6.249 remote-as 65261 neighbor 172.20.6.227 remote-as 65261 neighbor 172.20.6.245 remote-as 65261 neighbor 172.20.6.229 remote-as 65261 neighbor 172.20.6.212 remote-as 65261 !neighbor 172.16.66.10 default-originate !redistribute kernel !redistribute static redistribute connected ! neighbor 10.0.0.2 route-map set-nexthop out ! neighbor 172.16.0.2 ebgp-multihop ! neighbor 10.0.0.2 next-hop-self ! access-list all permit any ! !route-map set-nexthop permit 10 ! match ip address all ! set ip next-hop 10.0.0.1 ! log file bgpd.log ! log stdout root@cpodrouter-aca-k8s [ ~ ]# systemctl restart bgpd.service ``` - [ ] Activer les fonctionnalités DRS et HA (en ajoutant les options ci-dessous) sur le cluster vSphere | Option | Value | | --------------------------------- | ----- | | das.ignoreInsufficientHbDatastore | TRUE | | das.ignoreRedundantNetWarning | TRUE | - [ ] Créer un Resource Pool et un répertoire nommé CAPV Installation de la machines virtuelle (administration) basée sur Ubuntu 18.04.4 LTS --- - [ ] Déployer la machine virtuelle ADMCLI ![](https://i.imgur.com/rssWXPS.png) - [ ] Fixer l'adresse IP de la machine virtuelle ``` root@admcli:~# cat /etc/netplan/01-netcfg.yaml # This file describes the network interfaces available on your system # For more information, see netplan(5). network: version: 2 renderer: networkd ethernets: ens160: addresses: [172.20.6.30/24] gateway4: 172.20.6.1 nameservers: addresses: [172.20.6.1] search: [cpod-aca-k8s.az-lab.shwrfr.com] dhcp4: no root@admcli:~# cat /etc/hosts 127.0.0.1 localhost 172.20.6.30 admcli # The following lines are desirable for IPv6 capable hosts ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters ``` - [ ] Installer jq et govc sur ADMCLI ``` root@admcli:~# apt install -y jq root@admcli:~# curl -L https://github.com/vmware/govmomi/releases/download/v0.22.1/govc_linux_amd64.gz | gunzip > /usr/local/bin/govc root@admcli:~# chmod +x /usr/local/bin/govc root@admcli:~# exit acaussignac@admcli:~$ cat .govc export GOVC_INSECURE=true export GOVC_URL="https://vcsa.cpod-aca-k8s.az-lab.shwrfr.com" export GOVC_USERNAME="administrator@cpod-aca-k8s.az-lab.shwrfr.com" export GOVC_PASSWORD="password" acaussignac@admcli:~$ source .govc acaussignac@admcli:~$ govc ls /cPod-ACA-K8S/vm /cPod-ACA-K8S/network /cPod-ACA-K8S/host /cPod-ACA-K8S/datastore ``` - [ ] Installer Docker sur ADMCLI ``` root@admcli:~# apt install -y docker.io root@admcli:~# cat /etc/docker/daemon.json { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2" } root@admcli:~# systemctl restart docker root@admcli:~# systemctl enable docker root@admcli:~$ usermod -aG docker acaussignac ``` > Il est nécessaire de se reconnecter avec l'utilisateur concerné pour pouvoir utiliser le démon docker ou exécuter la commande suivante ```exec su -l acaussignac``` - [ ] Installer kubectl sur ADMCLI ``` root@admcli:~# apt install -y apt-transport-https curl root@admcli:~# curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - root@admcli:~# cat /etc/apt/sources.list.d/kubernetes.list deb https://apt.kubernetes.io/ kubernetes-xenial main root@admcli:~# apt update root@admcli:~# apt install -y kubectl root@admcli:~# apt-mark hold kubectl ``` - [ ] Installer Kind sur ADMCLI ``` acaussignac@admcli:~$ wget https://github.com/kubernetes-sigs/kind/releases/download/v0.7.0/kind-linux-amd64 acaussignac@admcli:~$ chmod +x ./kind-linux-amd64 acaussignac@admcli:~$ sudo mv ./kind-linux-amd64 /usr/local/bin/kind && sudo chown root:root /usr/local/bin/kind ``` > Kind est un utilitaire très pratique pour créer des clusters K8s dans des conteneurs Docker (K8s in Docker). - [ ] Installer Clusterctl sur ADMCLI ``` acaussignac@admcli:~$ wget https://github.com/kubernetes-sigs/cluster-api/releases/download/v0.3.0-rc.3/clusterctl-linux-amd64 acaussignac@admcli:~$ chmod +x ./clusterctl-linux-amd64 acaussignac@admcli:~$ sudo mv ./clusterctl-linux-amd64 /usr/local/bin/clusterctl && sudo chown root:root /usr/local/bin/clusterctl ``` Import des OVA dans le vCenter --- - [ ] Importer l’image OVA en tant que Template dans le vCenter (soit via l’interface graphique soit via la ligne de commande) qui servira de control plane ``` acaussignac@admcli:~$ wget http://storage.googleapis.com/capv-images/release/v1.17.3/photon-3-kube-v1.17.3.ova --2020-03-30 18:09:03-- http://storage.googleapis.com/capv-images/release/v1.17.3/photon-3-kube-v1.17.3.ova Résolution de storage.googleapis.com (storage.googleapis.com)… 216.58.215.48, 2a00:1450:4007:808::2010 Connexion à storage.googleapis.com (storage.googleapis.com)|216.58.215.48|:80… connecté. requête HTTP transmise, en attente de la réponse… 200 OK Taille : 983377920 (938M) [application/octet-stream] Enregistre : «photon-3-kube-v1.17.3.ova» photon-3-kube-v1.17 100%[===================>] 937,82M 55,5MB/s ds 15s 2020-03-30 18:09:19 (62,9 MB/s) - «photon-3-kube-v1.17.3.ova» enregistré [983377920/983377920] acaussignac@admcli:~$ wget http://storage.googleapis.com/capv-images/release/v1.17.3/photon-3-kube-v1.17.3.ova.sha256 --2020-03-30 18:11:09-- http://storage.googleapis.com/capv-images/release/v1.17.3/photon-3-kube-v1.17.3.ova.sha256 Résolution de storage.googleapis.com (storage.googleapis.com)… 216.58.215.48, 2a00:1450:4007:808::2010 Connexion à storage.googleapis.com (storage.googleapis.com)|216.58.215.48|:80… connecté. requête HTTP transmise, en attente de la réponse… 200 OK Taille : 64 [application/octet-stream] Enregistre : «photon-3-kube-v1.17.3.ova.sha256» photon-3-kube-v1.17 100%[===================>] 64 --.-KB/s ds 0s 2020-03-30 18:11:09 (7,74 MB/s) - «photon-3-kube-v1.17.3.ova.sha256» enregistré [64/64] acaussignac@admcli:~$ shasum -a 256 photon-3-kube-v1.17.3.ova d146cc3056913d370e7d8545fbd956da1627be50b988c097b842dd63140f7982 photon-3-kube-v1.17.3.ova acaussignac@admcli:~$ cat photon-3-kube-v1.17.3.ova.sha256 d146cc3056913d370e7d8545fbd956da1627be50b988c097b842dd63140f7982 acaussignac@admcli:~$ govc import.ova -ds=Datastore -folder=CAPV -name=photon-3-kube-v1.17.3 photon-3-kube-v1.17.3.ova ``` - [ ] Importer l’image OVA en tant que Template dans le vCenter (soit via l’interface graphique soit via la ligne de commande) qui servira de Load Balancer ``` acaussignac@admcli:~$ wget https://storage.googleapis.com/capv-images/extra/haproxy/release/v0.6.3/capv-haproxy-v0.6.3.ova --2020-03-30 20:13:38-- https://storage.googleapis.com/capv-images/extra/haproxy/release/v0.6.3/capv-haproxy-v0.6.3.ova Résolution de storage.googleapis.com (storage.googleapis.com)… 216.58.215.48, 2a00:1450:4007:808::2010 Connexion à storage.googleapis.com (storage.googleapis.com)|216.58.215.48|:443… connecté. requête HTTP transmise, en attente de la réponse… 200 OK Taille : 290529280 (277M) [application/octet-stream] Enregistre : «capv-haproxy-v0.6.3.ova» capv-haproxy-v0.6.3 100%[===================>] 277,07M 55,4MB/s ds 5,4s 2020-03-30 20:13:44 (51,0 MB/s) - «capv-haproxy-v0.6.3.ova» enregistré [290529280/290529280] acaussignac@admcli:~$ govc import.ova -ds=Datastore -folder=CAPV -name=capv-haproxy-v0.6.3 capv-haproxy-v0.6.3.ova ``` ![](https://i.imgur.com/53KXYOo.png) > Le lien vers les images OVA se trouve dans la [documentation](https://github.com/kubernetes-sigs/cluster-api-provider-vsphere/blob/master/docs/getting_started.md) de Cluster API for vSphere (CAPV). - [ ] Utiliser le mode Linked Clone pour accélérer les opérations de clonage ``` acaussignac@admcli:~$ govc vm.upgrade -version=15 -vm photon-3-kube-v1.17.3 acaussignac@admcli:~$ govc snapshot.create -vm photon-3-kube-v1.17.3 root acaussignac@admcli:~$ govc vm.markastemplate photon-3-kube-v1.17.3 acaussignac@admcli:~$ govc vm.upgrade -version=15 -vm capv-haproxy-v0.6.3 acaussignac@admcli:~$ govc snapshot.create -vm capv-haproxy-v0.6.3 root acaussignac@admcli:~$ govc vm.markastemplate capv-haproxy-v0.6.3 ``` > Pour information, sur vSphere, les images supportant les worker/master nodes sont à base de CentOS, Ubuntu ou PhotonOS mais il est possible de fabriquer ses propres images via le projet [Image Builder](https://github.com/kubernetes-sigs/image-builder). Déploiement du cluster K8s sur vSphere --- - [ ] Générer une paire de clés SSH sur ADMCLI ``` acaussignac@admcli:~$ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/acaussignac/.ssh/id_rsa): Created directory '/home/acaussignac/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/acaussignac/.ssh/id_rsa. Your public key has been saved in /home/acaussignac/.ssh/id_rsa.pub. The key fingerprint is: SHA256:Xh2QQLfeoVw3BEw89q2+SlSJ22JgF7fgEk60D1Yk2d0 acaussignac@admcli The key's randomart image is: +---[RSA 2048]----+ | .ooBOBoo. | | +oO**.oE| | X.Bo*. | | = @ B...| | S = O .. | | . . o .. | | . .. | | . . | | .... | +----[SHA256]-----+ acaussignac@admcli:~$ eval "$(ssh-agent -s)" Agent pid 6747 acaussignac@admcli:~$ ssh-add ~/.ssh/id_rsa Identity added: /home/acaussignac/.ssh/id_rsa (/home/acaussignac/.ssh/id_rsa) ``` > La clé publique sera ajoutée dans chaque cluster K8s déployé pour pouvoir y accéder en ssh avec l'utilisateur capv. - [ ] Créer un cluster Kind qui nous servira de pivot pour la création du control plane ``` acaussignac@admcli:~$ kind create cluster Creating cluster "kind" ... ✓ Ensuring node image (kindest/node:v1.17.0) 🖼 ✓ Preparing nodes 📦 ✓ Writing configuration 📜 ✓ Starting control-plane 🕹️ ✓ Installing CNI 🔌 ✓ Installing StorageClass 💾 Set kubectl context to "kind-kind" You can now use your cluster with: kubectl cluster-info --context kind-kind Not sure what to do next? 😅 Check out https://kind.sigs.k8s.io/docs/user/quick-start/ acaussignac@admcli:~$ kubectl cluster-info --context kind-kind Kubernetes master is running at https://127.0.0.1:32768 KubeDNS is running at https://127.0.0.1:32768/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. ``` - [ ] Déployer le cluster de management sur vSphere ``` acaussignac@admcli:~$ mkdir ~/.cluster-api acaussignac@admcli:~$ cat .cluster-api/clusterctl.yaml VSPHERE_USERNAME: "administrator@cpod-aca-k8s.az-lab.shwrfr.com" VSPHERE_PASSWORD: "password" VSPHERE_SERVER: "vcsa.cpod-aca-k8s.az-lab.shwrfr.com" VSPHERE_DATACENTER: "cPod-ACA-K8S" VSPHERE_DATASTORE: "Datastore" VSPHERE_NETWORK: "VM Network" VSPHERE_RESOURCE_POOL: "*/Resources/CAPV" VSPHERE_FOLDER: "CAPV" VSPHERE_TEMPLATE: "photon-3-kube-v1.17.3" VSPHERE_HAPROXY_TEMPLATE: "capv-haproxy-v0.6.3" VSPHERE_SSH_AUTHORIZED_KEY: "ssh-rsa AAAAB3Nz..." acaussignac@admcli:~$ clusterctl init --infrastructure vsphere Fetching providers Installing cert-manager Waiting for cert-manager to be available... Installing Provider="cluster-api" Version="v0.3.3" TargetNamespace="capi-system" Installing Provider="bootstrap-kubeadm" Version="v0.3.3" TargetNamespace="capi-kubeadm-bootstrap-system" Installing Provider="control-plane-kubeadm" Version="v0.3.3" TargetNamespace="capi-kubeadm-control-plane-system" Installing Provider="infrastructure-vsphere" Version="v0.6.3" TargetNamespace="capv-system" Your management cluster has been initialized successfully! You can now create your first workload cluster by running the following: clusterctl config cluster [name] --kubernetes-version [version] | kubectl apply -f - ``` > Il est possible que vous rencontriez ce [problème](https://github.com/kubernetes-sigs/cluster-api/issues/2450). Pour le contourner, il vous suffit de générer un nouveau token via la commande ```export GITHUB_TOKEN=<new_token>``` ``` acaussignac@admcli:~$ clusterctl config cluster vsphere-quickstart --infrastructure vsphere --kubernetes-version v1.17.3 --control-plane-machine-count 3 --worker-machine-count 5 > cluster.yaml ```` > Il peut être intéressant de créer un namespace par cluster K8s déployé via la commande ```clusterctl config cluster vsphere-quickstart --infrastructure vsphere --kubernetes-version v1.17.3 --control-plane-machine-count 3 --worker-machine-count 5 --target-namespace vsphere-quickstart > cluster.yaml``` en ayant pris soin d'avoir créé le namespace au préalable ```kubectl create ns vsphere-quickstart``` - [ ] Deployer le cluster K8s (environ 5 minutes pour un cluster 3 masters/5 workers) ``` acaussignac@admcli:~$ kubectl apply -f cluster.yaml cluster.cluster.x-k8s.io/vsphere-quickstart created haproxyloadbalancer.infrastructure.cluster.x-k8s.io/vsphere-quickstart created vspherecluster.infrastructure.cluster.x-k8s.io/vsphere-quickstart created vspheremachinetemplate.infrastructure.cluster.x-k8s.io/vsphere-quickstart created kubeadmcontrolplane.controlplane.cluster.x-k8s.io/vsphere-quickstart created kubeadmconfigtemplate.bootstrap.cluster.x-k8s.io/vsphere-quickstart-md-0 created machinedeployment.cluster.x-k8s.io/vsphere-quickstart-md-0 created acaussignac@admcli:~$ kubectl get po -A NAMESPACE NAME READY STATUS RESTARTS AGE capi-kubeadm-bootstrap-system capi-kubeadm-bootstrap-controller-manager-5bb9bfdc46-t5qwb 2/2 Running 0 69m capi-kubeadm-control-plane-system capi-kubeadm-control-plane-controller-manager-77466c7666-fc977 2/2 Running 0 69m capi-system capi-controller-manager-5798474d9f-672vh 2/2 Running 1 69m capi-webhook-system capi-controller-manager-5d64dd9dfb-fttz5 2/2 Running 0 69m capi-webhook-system capi-kubeadm-bootstrap-controller-manager-7c78fff45-9xrz7 2/2 Running 0 69m capi-webhook-system capi-kubeadm-control-plane-controller-manager-58465bb88f-hsv6l 2/2 Running 0 69m capi-webhook-system capv-controller-manager-6bbbc59845-pm694 2/2 Running 0 68m capv-system capv-controller-manager-5c8648757b-7kmt4 2/2 Running 0 68m cert-manager cert-manager-69b4f77ffc-prhb5 1/1 Running 0 70m cert-manager cert-manager-cainjector-576978ffc8-fkplj 1/1 Running 1 70m cert-manager cert-manager-webhook-c67fbc858-kph77 1/1 Running 0 70m kube-system coredns-6955765f44-2c82m 1/1 Running 0 70m kube-system coredns-6955765f44-xvvvk 1/1 Running 0 70m kube-system etcd-kind-control-plane 1/1 Running 0 70m kube-system kindnet-xlxbz 1/1 Running 0 70m kube-system kube-apiserver-kind-control-plane 1/1 Running 0 70m kube-system kube-controller-manager-kind-control-plane 1/1 Running 1 70m kube-system kube-proxy-qdgfj 1/1 Running 0 70m kube-system kube-scheduler-kind-control-plane 1/1 Running 1 70m local-path-storage local-path-provisioner-7745554f7f-4dwnl 1/1 Running 0 70m acaussignac@admcli:~$ kubectl logs -f -n capv-system capv-controller-manager-5c8648757b-7kmt4 manager ```` > Adapter le nom du pod en fonction de votre configuration ``` acaussignac@admcli:~$ watch -n 1 kubectl get machines -A NAMESPACE NAME PROVIDERID PHASE default vsphere-quickstart-99rwb vsphere://4236247d-9886-6bf1-88df-4b8f19cc8ef2 Running default vsphere-quickstart-blkm6 vsphere://42365692-3db4-4dae-f25f-7839e645ac2d Running default vsphere-quickstart-h6nr2 vsphere://4236dd2f-91af-270f-b27e-db6c26497507 Running default vsphere-quickstart-md-0-76675f574-2gkvg vsphere://42364106-19e4-ffab-68e9-b810a6d4dc6c Running default vsphere-quickstart-md-0-76675f574-6z4q7 vsphere://42364475-c869-2aba-88f0-6a428bc3fc26 Running default vsphere-quickstart-md-0-76675f574-8cvxs vsphere://42365144-5ee2-2889-926f-2a87af8fbb90 Running default vsphere-quickstart-md-0-76675f574-dmrrp vsphere://423634d9-b979-5c7c-1ed6-af66f7473ce3 Running default vsphere-quickstart-md-0-76675f574-gqcp7 vsphere://4236cdfa-baab-f2c2-e282-8af233b407b8 Running ``` - [ ] Récupérer le fichier kubeconfig ``` acaussignac@admcli:~$ kubectl get secret/vsphere-quickstart-kubeconfig -o json | jq -r .data.value | base64 --decode > ./vsphere-quickstart.kubeconfig acaussignac@admcli:~$ kubectl --kubeconfig ./vsphere-quickstart.kubeconfig get nodes NAME STATUS ROLES AGE VERSION vsphere-quickstart-99rwb NotReady master 10m v1.17.3 vsphere-quickstart-blkm6 NotReady master 8m48s v1.17.3 vsphere-quickstart-h6nr2 NotReady master 12m v1.17.3 vsphere-quickstart-md-0-76675f574-2gkvg NotReady <none> 10m v1.17.3 vsphere-quickstart-md-0-76675f574-6z4q7 NotReady <none> 10m v1.17.3 vsphere-quickstart-md-0-76675f574-8cvxs NotReady <none> 10m v1.17.3 vsphere-quickstart-md-0-76675f574-dmrrp NotReady <none> 10m v1.17.3 vsphere-quickstart-md-0-76675f574-gqcp7 NotReady <none> 10m v1.17.3 acaussignac@admcli:~$ mv ./vsphere-quickstart.kubeconfig .kube/config ``` ![](https://i.imgur.com/rbxY7mC.png) Installer et configurer la partie réseau (*Container Network Interface*) --- - [ ] Installer le SDN Antrea pour disposer de la fonctionnalité overlay ``` acaussignac@admcli:~$ kubectl apply -f https://raw.githubusercontent.com/vmware-tanzu/antrea/master/build/yamls/antrea.yml acaussignac@admcli:~$ kubectl get nodes NAME STATUS ROLES AGE VERSION vsphere-quickstart-99rwb Ready master 37m v1.17.3 vsphere-quickstart-blkm6 Ready master 35m v1.17.3 vsphere-quickstart-h6nr2 Ready master 39m v1.17.3 vsphere-quickstart-md-0-76675f574-2gkvg Ready <none> 37m v1.17.3 vsphere-quickstart-md-0-76675f574-6z4q7 Ready <none> 37m v1.17.3 vsphere-quickstart-md-0-76675f574-8cvxs Ready <none> 37m v1.17.3 vsphere-quickstart-md-0-76675f574-dmrrp Ready <none> 37m v1.17.3 vsphere-quickstart-md-0-76675f574-gqcp7 Ready <none> 37m v1.17.3 ``` - [ ] Installer Metallb pour apporter à K8s la fonctionnalité de Load Balancer as a Service ``` acaussignac@admcli:~$ kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.8.3/manifests/metallb.yaml namespace/metallb-system created podsecuritypolicy.policy/speaker created serviceaccount/controller created serviceaccount/speaker created clusterrole.rbac.authorization.k8s.io/metallb-system:controller created clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created role.rbac.authorization.k8s.io/config-watcher created clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created rolebinding.rbac.authorization.k8s.io/config-watcher created daemonset.apps/speaker created deployment.apps/controller created acaussignac@admcli:~$ cat metallb-configmap.yaml apiVersion: v1 kind: ConfigMap metadata: namespace: metallb-system name: config data: config: | peers: - peer-address: 172.20.6.1 peer-asn: 65216 my-asn: 65261 address-pools: - name: default protocol: bgp addresses: - 172.20.6.100-172.20.6.199 acaussignac@admcli:~$ kubectl apply -f metallb-configmap.yaml configmap/config created ``` > Vous n'êtes pas obligé d'utiliser BGP avec metallb mais simplement configurer une plage IP. Voici un exemple de configuration sans utiliser BGP. ``` apiVersion: v1 kind: ConfigMap metadata: namespace: metallb-system name: config data: config: | address-pools: - name: default protocol: layer2 addresses: - 172.20.6.100-172.20.6.199 ``` >Penser à mettre à jour les neighbors (cf section Préparation du Lab) dans la configuration BGP du cPod router si vous utilisez BGP. Les adresses IP des workers nodes peuvent être récupérés via la commande ```kubectl get nodes -o wide```. - [ ] Vérifier la connectivité BGP sur le cPod router ``` cpodrouter-aca-k8s# show ip bgp summary BGP router identifier 172.16.2.16, local AS number 65216 RIB entries 173, using 19 KiB of memory Peers 6, using 53 KiB of memory Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/P fxRcd 172.16.2.1 4 65200 54 31 0 0 0 00:25:14 87 172.20.6.212 4 65261 23 54 0 0 0 00:11:41 0 172.20.6.227 4 65261 23 54 0 0 0 00:11:42 0 172.20.6.229 4 65261 23 54 0 0 0 00:11:48 0 172.20.6.245 4 65261 23 54 0 0 0 00:11:33 0 172.20.6.249 4 65261 23 54 0 0 0 00:11:48 0 Total number of neighbors 6 Total num. Established sessions 6 Total num. of routes received 87 ``` - [ ] Déployer Contour afin d'offrir à K8s un Ingress controller (voir plus avec un objet de type HTTPProxy) ``` acaussignac@admcli:~$ kubectl apply -f https://projectcontour.io/quickstart/contour.yaml acaussignac@admcli:~$ kubectl apply -f https://projectcontour.io/examples/proxydemo/01-prereq.yaml ```` - [ ] Déployer une première application sans persistance de données pour tester les règles d'Ingress ``` acaussignac@admcli:~$ cat contour-httpproxy.yaml apiVersion: projectcontour.io/v1 kind: HTTPProxy metadata: name: root namespace: projectcontour-roots spec: virtualhost: fqdn: rootapp.apps.cpod-aca-k8s.az-lab.shwrfr.com routes: - services: - name: rootapp port: 80 conditions: - prefix: / - services: - name: secureapp port: 80 conditions: - prefix: /secure - services: - name: secureapp-default port: 80 conditions: - prefix: /securedefault acaussignac@admcli:~$ kubectl apply -f contour-httpproxy.yaml acaussignac@admcli:~$ kubectl get HTTPProxy -n projectcontour-roots NAME FQDN TLS SECRET STATUS STATUS DESCRIPTION root rootapp.apps.cpod-aca-k8s.az-lab.shwrfr.com valid valid HTTPProxy ``` ![](https://i.imgur.com/OU5LNNe.png) --- ![](https://i.imgur.com/Yc8saay.png) --- ![](https://i.imgur.com/w4LbOh6.png) Installer et configurer la partie stockage (*Container Storage Interface*) --- > L'installation du vSphere Cloud Controller Manager et du vSphere Cloud Storage Interface Driver est déjà intégrée dans CAPV. - [ ] Créer un tag vSphere nommé K8s et l'assigner au datastore adéquat ![](https://i.imgur.com/whLB4Iu.png) --- ![](https://i.imgur.com/y6AAlD0.png) - [ ] Créer une vSphere Storage Policy basée sur le tag créé précédemment ![](https://i.imgur.com/6iMZP1F.png) --- ![](https://i.imgur.com/QRZbLSI.png) --- ![](https://i.imgur.com/bK3oIv7.png) --- ![](https://i.imgur.com/snoFOUs.png) --- ![](https://i.imgur.com/Fjt3O8p.png) - [ ] Créer une K8s Storage Class basée sur la Storage Policy vSphere ``` acaussignac@admcli:~$ cat k8s-storageclass.yaml kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: k8s-sc annotations: storageclass.kubernetes.io/is-default-class: "true" provisioner: csi.vsphere.vmware.com parameters: storagepolicyname: "K8s" fstype: ext4 acaussignac@admcli:~$ kubectl create -f k8s-storageclass.yaml acaussignac@admcli:~$ kubectl get sc k8s-sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE k8s-sc (default) csi.vsphere.vmware.com Delete Immediate false 86s ``` Installer l'application Rocketchat (avec persistance de données) afin de tester notre configuration --- - [ ] Installer helm (packager d'applications basé sur des *marketplace*) ``` acaussignac@admcli:~$ wget https://get.helm.sh/helm-v3.1.2-linux-amd64.tar.gz --2020-03-28 19:25:59-- https://get.helm.sh/helm-v3.1.2-linux-amd64.tar.gz Résolution de get.helm.sh (get.helm.sh)… 152.199.21.175, 2606:2800:233:1cb7:261b:1f9c:2074:3c Connexion à get.helm.sh (get.helm.sh)|152.199.21.175|:443… connecté. requête HTTP transmise, en attente de la réponse… 200 OK Taille : 12269190 (12M) [application/x-tar] Enregistre : «helm-v3.1.2-linux-amd64.tar.gz» helm-v3.1.2-linux-amd64.tar.g 100%[===============================================>] 11,70M 70,2MB/s ds 0,2s 2020-03-28 19:25:59 (70,2 MB/s) - «helm-v3.1.2-linux-amd64.tar.gz» enregistré [12269190/12269190] acaussignac@admcli:~$ tar zxvf helm-v3.1.2-linux-amd64.tar.gz acaussignac@admcli:~$ sudo mv linux-amd64/helm /usr/local/bin/ && sudo chown root:root /usr/local/bin/helm acaussignac@admcli:~$ helm repo add bitnami https://charts.bitnami.com/bitnami "bitnami" has been added to your repositories acaussignac@admcli:~$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/ "stable" has been added to your repositories acaussignac@admcli:~$ helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts "vmware-tanzu" has been added to your repositories ``` > L'ajout des trois repo permettra l'installation des outils/applications ci-dessous. - [ ] Installer l'application Rocketchat ``` acaussignac@admcli:~$ kubectl create ns rocketchat namespace/rocketchat created acaussignac@admcli:~$ cat rocketchat.yaml persistence: enabled: true service: type: LoadBalancer mongodb: mongodbPassword: password mongodbRootPassword: password acaussignac@admcli:~$ helm install rocketchat stable/rocketchat --namespace rocketchat -f rocketchat.yaml acaussignac@admcli:~$ kubectl get pods -n rocketchat NAME READY STATUS RESTARTS AGE rocketchat-mongodb-primary-0 1/1 Running 0 3m2s rocketchat-rocketchat-65589d77bd-f6vrq 1/1 Running 0 3m2s acaussignac@admcli:~$ kubectl get svc -n rocketchat NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE rocketchat-mongodb ClusterIP 10.100.53.123 <none> 27017/TCP 3m27s rocketchat-mongodb-headless ClusterIP None <none> 27017/TCP 3m27s rocketchat-rocketchat LoadBalancer 10.96.22.61 172.20.6.101 80:30346/TCP 3m27s acaussignac@admcli:~$ kubectl get pvc -n rocketchat NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE datadir-rocketchat-mongodb-primary-0 Bound pvc-f736fc42-dc04-4936-99c9-ada7911d846b 8Gi RWO k8s-sc 3m50s rocketchat-rocketchat Bound pvc-64c5616b-82e6-4529-881b-596d1298fd91 8Gi RWO k8s-sc 3m50s acaussignac@admcli:~$ kubectl annotate pod -n rocketchat --selector=release=rocketchat,app=mongodb backup.velero.io/backup-volumes=datadir --overwrite ``` > La dernière commande permet de labelliser les Persistent Volumes (PV) afin que ces derniers soient inclus dans la sauvegarde Velero. ![](https://i.imgur.com/AxkDk2y.png) --- ![](https://i.imgur.com/HcqwL0Q.png) --- ![](https://i.imgur.com/4NGJa8k.png) Installer l'outil Velero afin de sauvegarder et restaurer notre application --- - [ ] Installer un stockage de type objet nommé Minio qui permettra de stocker les backups créés par Velero ``` acaussignac@admcli:~$ cat minio.yaml image: tag: latest accessKey: minio secretKey: minio123 service: type: LoadBalancer defaultBucket: enabled: true name: velero persistence: size: 5G acaussignac@admcli:~$ kubectl create ns velero namespace/velero created acaussignac@admcli:~$ helm install minio stable/minio --namespace velero -f minio.yaml acaussignac@admcli:~$ kubectl get svc --namespace velero -l app=minio NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE minio LoadBalancer 10.101.131.98 172.20.6.102 9000:31811/TCP 2m26s ``` ![](https://i.imgur.com/xyrLyeQ.png) - [ ] Installer Velero server ``` acaussignac@admcli:~$ wget https://github.com/vmware-tanzu/velero/releases/download/v1.3.1/velero-v1.3.1-linux-amd64.tar.gz acaussignac@admcli:~$ tar zxvf velero-v1.3.1-linux-amd64.tar.gz acaussignac@admcli:~$ sudo mv velero-v1.3.1-linux-amd64/velero /usr/local/bin/velero && sudo chown root:root /usr/local/bin/velero acaussignac@admcli:~$ cat credentials-velero [default] aws_access_key_id = minio aws_secret_access_key = minio123 acaussignac@admcli:~$ velero install --use-restic --provider aws --plugins velero/velero-plugin-for-aws:v1.0.0 --bucket velero --secret-file ./credentials-velero --use-volume-snapshots=false --backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://minio.velero.svc:9000,publicUrl=http://172.20.6.102:9000 ``` - [ ] Installer Velero CLI sur votre poste de travail (MacOS dans ce tutoriel) ``` acaussignac@tokyo ~ % brew install kubectl acaussignac@tokyo ~ % mkdir .kube acaussignac@tokyo ~ % vi .kube/config acaussignac@tokyo ~ % kubectl get nodes NAME STATUS ROLES AGE VERSION vsphere-quickstart-99rwb Ready master 82m v1.17.3 vsphere-quickstart-blkm6 Ready master 80m v1.17.3 vsphere-quickstart-h6nr2 Ready master 84m v1.17.3 vsphere-quickstart-md-0-76675f574-2gkvg Ready <none> 82m v1.17.3 vsphere-quickstart-md-0-76675f574-6z4q7 Ready <none> 82m v1.17.3 vsphere-quickstart-md-0-76675f574-8cvxs Ready <none> 82m v1.17.3 vsphere-quickstart-md-0-76675f574-dmrrp Ready <none> 82m v1.17.3 vsphere-quickstart-md-0-76675f574-gqcp7 Ready <none> 82m v1.17.3 acaussignac@tokyo ~ % brew install velero ```` - [ ] Lancer un backup de l'application ``` acaussignac@tokyo ~ % velero backup create before-disaster --include-namespaces rocketchat Backup request "before-disaster" submitted successfully. Run `velero backup describe before-disaster` or `velero backup logs before-disaster` for more details. acaussignac@tokyo ~ % velero backup describe before-disaster Name: before-disaster Namespace: velero Labels: velero.io/storage-location=default Annotations: <none> Phase: Completed Namespaces: Included: rocketchat Excluded: <none> Resources: Included: * Excluded: <none> Cluster-scoped: auto Label selector: <none> Storage Location: default Snapshot PVs: auto TTL: 720h0m0s Hooks: <none> Backup Format Version: 1 Started: 2020-03-31 12:44:05 +0200 CEST Completed: 2020-03-31 12:44:27 +0200 CEST Expiration: 2020-04-30 12:44:05 +0200 CEST Persistent Volumes: <none included> Restic Backups (specify --details for more information): Completed: 1 acaussignac@tokyo ~ % velero get backups NAME STATUS CREATED EXPIRES STORAGE LOCATION SELECTOR before-disaster Completed 2020-03-31 12:44:05 +0200 CEST 29d default <none> ``` ![](https://i.imgur.com/LJHFSgN.png) - [ ] Supprimer entièrement l'application et la restaurer avec Velero ``` acaussignac@admcli:~$ kubectl delete ns rocketchat namespace "rocketchat" deleted ``` ![](https://i.imgur.com/Bo1Wk95.png) ``` acaussignac@tokyo ~ % velero restore create --from-backup before-disaster --include-namespaces rocketchat Restore request "before-disaster-20200331124738" submitted successfully. Run `velero restore describe before-disaster-20200331124738` or `velero restore logs before-disaster-20200331124738` for more details. acaussignac@tokyo ~ % velero restore describe before-disaster-20200331124738 Name: before-disaster-20200331124738 Namespace: velero Labels: <none> Annotations: <none> Phase: Completed Backup: before-disaster Namespaces: Included: rocketchat Excluded: <none> Resources: Included: * Excluded: nodes, events, events.events.k8s.io, backups.velero.io, restores.velero.io, resticrepositories.velero.io Cluster-scoped: auto Namespace mappings: <none> Label selector: <none> Restore PVs: auto Restic Restores (specify --details for more information): Completed: 1 ``` ![](https://i.imgur.com/MMQqM7q.png) Gérer la scalabilité du cluster K8s --- > Ce qui est génial avec Cluster API c'est la gestion du cycle de vie des clusters K8s, toutes les opérations Day1 et Day2 sont grandement facilitées. Voici un exemple pour simplement passer le nombre de workers nodes de 5 à 7. Le cluster Kind sert encore de pivot pour mettre à jour son cluster K8s. ``` acaussignac@admcli:~$ kind get kubeconfig --name kind > kindconfig acaussignac@admcli:~$ vi cluster.yaml ... spec: clusterName: vsphere-quickstart replicas: 7 selector: matchLabels: cluster.x-k8s.io/cluster-name: vsphere-quickstart acaussignac@admcli:~$ kubectl --kubeconfig ./kindconfig apply -f ./cluster.yaml cluster.cluster.x-k8s.io/vsphere-quickstart unchanged haproxyloadbalancer.infrastructure.cluster.x-k8s.io/vsphere-quickstart unchanged vspherecluster.infrastructure.cluster.x-k8s.io/vsphere-quickstart unchanged vspheremachinetemplate.infrastructure.cluster.x-k8s.io/vsphere-quickstart unchanged kubeadmcontrolplane.controlplane.cluster.x-k8s.io/vsphere-quickstart unchanged kubeadmconfigtemplate.bootstrap.cluster.x-k8s.io/vsphere-quickstart-md-0 unchanged machinedeployment.cluster.x-k8s.io/vsphere-quickstart-md-0 configured acaussignac@admcli:~$ kubectl get nodes NAME STATUS ROLES AGE VERSION vsphere-quickstart-99rwb Ready master 4h58m v1.17.3 vsphere-quickstart-blkm6 Ready master 4h56m v1.17.3 vsphere-quickstart-h6nr2 Ready master 5h v1.17.3 vsphere-quickstart-md-0-76675f574-2gkvg Ready <none> 4h58m v1.17.3 vsphere-quickstart-md-0-76675f574-6z4q7 Ready <none> 4h58m v1.17.3 vsphere-quickstart-md-0-76675f574-8cvxs Ready <none> 4h58m v1.17.3 vsphere-quickstart-md-0-76675f574-dmrrp Ready <none> 4h58m v1.17.3 vsphere-quickstart-md-0-76675f574-gqcp7 Ready <none> 4h58m v1.17.3 vsphere-quickstart-md-0-76675f574-qch6d Ready <none> 28s v1.17.3 vsphere-quickstart-md-0-76675f574-sgv2r Ready <none> 28s v1.17.3 ``` Supprimer le cluster K8s --- ``` acaussignac@admcli:~$ kubectl --kubeconfig ./kindconfig get cluster NAME PHASE vsphere-quickstart Provisioned acaussignac@admcli:~$ kubectl --kubeconfig ./kindconfig get machines NAME PROVIDERID PHASE vsphere-quickstart-99rwb vsphere://4236247d-9886-6bf1-88df-4b8f19cc8ef2 Running vsphere-quickstart-blkm6 vsphere://42365692-3db4-4dae-f25f-7839e645ac2d Running vsphere-quickstart-h6nr2 vsphere://4236dd2f-91af-270f-b27e-db6c26497507 Running vsphere-quickstart-md-0-76675f574-2gkvg vsphere://42364106-19e4-ffab-68e9-b810a6d4dc6c Running vsphere-quickstart-md-0-76675f574-6z4q7 vsphere://42364475-c869-2aba-88f0-6a428bc3fc26 Running vsphere-quickstart-md-0-76675f574-8cvxs vsphere://42365144-5ee2-2889-926f-2a87af8fbb90 Running vsphere-quickstart-md-0-76675f574-dmrrp vsphere://423634d9-b979-5c7c-1ed6-af66f7473ce3 Running vsphere-quickstart-md-0-76675f574-gqcp7 vsphere://4236cdfa-baab-f2c2-e282-8af233b407b8 Running vsphere-quickstart-md-0-76675f574-qch6d vsphere://42361ad7-e8f8-e5ec-e458-cf93533bfc1e Running vsphere-quickstart-md-0-76675f574-sgv2r vsphere://4236ee0e-ee2f-64f0-0531-1e1c8ca0e85d Running acaussignac@admcli:~$ kubectl --kubeconfig ./kindconfig delete -n default cluster vsphere-quickstart acaussignac@admcli:~$ kubectl --kubeconfig ./kindconfig get cluster No resources found in default namespace. acaussignac@admcli:~$ kubectl --kubeconfig ./kindconfig get machines No resources found in default namespace. ``` Conclusion --- Il n'est pas improbable que Cluster API devienne un standard de facto pour gérer des clusters K8s au même titre que les API de K8s sont le point de passage obligé pour l'ensemble de l'écosystème (Container Runtime/Network/Storage Interface). Après l’arrivée des opérateurs K8s comme moyen d’étendre son comportement interne, un faisceau de réflexions émergent autour d’une même idée : celle que l’API K8s pourrait finalement devenir la seule et unique API permettant de gérer intégralement son SI, venant abstraire tous les autres types de ressources qui le composent (extension de l'API via les Custom Resources Definition). Je vous invite à présent à suivre ce troisième article qui explique comment VMware a intégré Cluster API dans son offre supportée plus communément appelée Tanzu Kubernetes Grid. En synthèse --- J'ai essayé de dresser les points positifs et négatifs de cette solution: * **Points forts**: appréhender les concepts de K8s, disposer de clusters multi masters, bénéficier de la persistance des données pour les applications qui le nécessitent, opérations Day1 et Day2. * **Points faibles**: pas de support d'un éditeur, être contraint d'installer et de maintenir plusieurs produits pour disposer d'une stack réseau complète.