
k0rdent sur Azure avec AKS : Premiers pas
Les organisations doivent aujourd’hui faire face à une complexité croissante dans la gestion de leurs infrastructures. La centralisation du contrôle et l’automatisation des tâches récurrentes deviennent des impératifs pour assurer la scalabilité, la sécurité et l’efficacité opérationnelle.
C’est ici qu’intervient k0rdent, en offrant :
- Un contrôle centralisé sur plusieurs clusters Kubernetes
- Une approche déclarative qui permet de réutiliser des templates pour une cohérence inter-environnements
- Une extensibilité facilitée grâce à des modules complémentaires (comme kcm pour la gestion du cycle de vie des clusters, ou kof pour l’observabilité)
Ce billet de blog détaille l’expérimentation de trois configurations de déploiement sur Azure en utilisant les templates préconçus par k0rdent.
1. Création d'un cluster d'administration
Pré-requis :
- Une VM sur Azure 22.04.5 LTS, Jammy Jellyfish
- Homebrew (
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
) - k0s (
curl --proto '=https' --tlsv1.2 -sSf https://get.k0s.sh | sudo sh
) - krew (
brew install krew
)) - kubectl (
brew install kubectl
) - helm (
brew install helm
) - azure CLI (az) (
brew install azure-cli
) - jq (
brew install jq
)
1.1 Création du cluster d'administration
# Création du cluster d'un seul noeud
sudo k0s install controller --single
# Démarrage du cluster
sudo k0s start
# Aliasing
echo 'source <(kubectl completion bash)' >>~/.bashrc
echo 'alias k=kubectl' >>~/.bashrc
echo 'complete -o default -F __start_kubectl k' >>~/.bashrc
source ~/.bashrc
# Copie du kubeconfig
mkdir ~/.kube
sudo cp /var/lib/k0s/pki/admin.conf ~/.kube/config
sudo chmod +r ~/.kube/config
sudo chown devops: /home/devops/.kube/config
# Installation des plugins krew
kubectl krew install ns
kubectl krew install ctx
kubectl krew install neat
kubectl krew install view-secret
kubectl krew install stern
kubectl get nodes
# Résultat :
NAME STATUS ROLES AGE VERSION
herlec-icdc Ready control-plane 6m11s v1.32.1+k0s
1.2 Installation de k0rdent
# Récupération des valeurs par défaut(au cas ou...)
helm inspect values oci://ghcr.io/k0rdent/kcm/charts/kcm > kcm-values.yaml
Interroge le chart Helm disponible dans le registre OCI (ici sur ghcr.io) pour récupérer les valeurs de configuration par défaut. Le résultat est ensuite redirigé vers le fichier kcm-values.yaml, que vous pourrez modifier si nécessaire.
# Installation du kcm
helm install kcm oci://ghcr.io/k0rdent/kcm/charts/kcm --version 0.1.0 -n kcm-system --create-namespace -f kcm-values.yaml
# Résultat :
Pulled: ghcr.io/k0rdent/kcm/charts/kcm:0.1.0
Digest: sha256:accb6d1f9035d3dd46abbd86e10a7cd2c8bf235f8a77d079edeab58dfa9d38e8
NAME: kcm
LAST DEPLOYED: Thu Feb 13 08:02:08 2025
NAMESPACE: kcm-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
Installe le chart Helm nommé kcm dans le namespace kcm-system (en créant le namespace si celui-ci n'existe pas) en utilisant la version 0.1.0 du chart. Elle applique également les configurations définies dans le fichier kcm-values.yaml pour personnaliser l'installation.
# Check du déploiement
kubectl get pods -n kcm-system
# Cela peut prendre du temps pour avoir tous les composants installés,
# car c'est le contrôleur qui les installe.
NAME READY STATUS RESTARTS AGE
azureserviceoperator-controller-manager-6b4dd86894-gvz8c 1/1 Running 0 109s
capa-controller-manager-64bbcb9f8-gx5qz 1/1 Running 0 94s
capi-controller-manager-66f8998ff5-tt9xd 1/1 Running 0 3m4s
capo-controller-manager-588f45c7cf-57tr2 1/1 Running 0 76s
capv-controller-manager-69f7fc65d8-pbgmt 1/1 Running 0 64s
capz-controller-manager-544845f786-q24nd 1/1 Running 0 109s
helm-controller-7644c4d5c4-98ff7 1/1 Running 0 6m
k0smotron-controller-manager-bootstrap-9fc48d76f-558fw 2/2 Running 0 2m40s
k0smotron-controller-manager-control-plane-7df9bc7bf-hzlfv 2/2 Running 0 2m37s
k0smotron-controller-manager-infrastructure-f7f94dd76-vpv8t 2/2 Running 0 84s
kcm-cert-manager-895954d88-pmwd4 1/1 Running 0 5m59s
kcm-cert-manager-cainjector-685ffdf549-kz2jn 1/1 Running 0 6m
kcm-cert-manager-webhook-59ddc6b56-4ld68 1/1 Running 0 6m
kcm-cluster-api-operator-8487958779-ln8qd 1/1 Running 0 3m48s
kcm-controller-manager-7998cdb69-l7ksk 1/1 Running 0 3m48s
kcm-velero-b68fd5957-xcnrs 1/1 Running 0 6m
source-controller-6cd7676f7f-25hnw 1/1 Running 0 6m
# Verification que projectsveltos est déployé et fonctionnement
kubectl get ns
# Résultat :
NAME STATUS AGE
default Active 18m
k0s-autopilot Active 17m
kcm-system Active 8m37s
kube-node-lease Active 18m
kube-public Active 18m
kube-system Active 18m
mgmt Active 4m49s
projectsveltos Active 5m16s
kubectl get po -n projectsveltos
# Résultat :
kubectl get pods -n projectsveltos
NAME READY STATUS RESTARTS AGE
access-manager-56696cc7f-plxns 1/1 Running 0 6m36s
addon-controller-7c98776c79-wqbjw 1/1 Running 0 6m36s
classifier-manager-7b85f96469-swwjk 1/1 Running 0 6m36s
event-manager-67f6db7f44-btvmj 1/1 Running 0 6m36s
hc-manager-6d579d675f-lnxvb 1/1 Running 0 6m36s
sc-manager-55c99d494b-7d5cx 1/1 Running 0 6m36s
shard-controller-5ff9cd796d-hsm48 1/1 Running 0 6m36s
sveltos-agent-manager-7467959f4f-vd2sb 1/1 Running 0 5m43s
Si Projectsveltos vous intéresse, vous pouvez consulter le blog d'Alter Way pour lire les articles à ce sujet.
- Créer une usine à clusters kubernetes - partie 1
- Créer une usine à clusters kubernetes - partie 2
- Créer une usine à clusters kubernetes - partie 3
1.3 Check des différents composant de k0rdent
Il faut que tout soit à true
kubectl get Management,providertemplate,clustertemplate -n kcm-system
# Résultats :
NAME READY RELEASE AGE
management.k0rdent.mirantis.com/kcm True kcm-0-1-0 21m
NAME VALID
providertemplate.k0rdent.mirantis.com/cluster-api-0-1-0 true
providertemplate.k0rdent.mirantis.com/cluster-api-provider-aws-0-1-0 true
providertemplate.k0rdent.mirantis.com/cluster-api-provider-azure-0-1-0 true
providertemplate.k0rdent.mirantis.com/cluster-api-provider-openstack-0-1-0 true
providertemplate.k0rdent.mirantis.com/cluster-api-provider-vsphere-0-1-0 true
providertemplate.k0rdent.mirantis.com/k0smotron-0-1-0 true
providertemplate.k0rdent.mirantis.com/kcm-0-1-0 true
providertemplate.k0rdent.mirantis.com/projectsveltos-0-45-0 true
NAME VALID
clustertemplate.k0rdent.mirantis.com/adopted-cluster-0-1-0 true
clustertemplate.k0rdent.mirantis.com/aws-eks-0-1-0 true
clustertemplate.k0rdent.mirantis.com/aws-hosted-cp-0-1-0 true
clustertemplate.k0rdent.mirantis.com/aws-standalone-cp-0-1-0 true
clustertemplate.k0rdent.mirantis.com/azure-aks-0-1-0 true
clustertemplate.k0rdent.mirantis.com/azure-hosted-cp-0-1-0 true
clustertemplate.k0rdent.mirantis.com/azure-standalone-cp-0-1-0 true
clustertemplate.k0rdent.mirantis.com/openstack-standalone-cp-0-1-0 true
clustertemplate.k0rdent.mirantis.com/vsphere-hosted-cp-0-1-0 true
clustertemplate.k0rdent.mirantis.com/vsphere-standalone-cp-0-1-0 true
2. Usage sur Azure
2.1 Connexion à votre compte Azure
az login
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code C9EQUM9SG to authenticate.
Retrieving tenants and subscriptions for the selection...
# Choisir le tenant sur lequel vous allez manager vos AKS
# Verifier les providers disponibles
az provider list --query "[?registrationState=='Registered']" --output table | \
grep -e "Microsoft.Compute" \
-e "Microsoft.Network" \
-e "Microsoft.ContainerService" \
-e "Microsoft.ManagedIdentity" \
-e "Microsoft.Authorization"
# Résultats
Microsoft.Compute Registered RegistrationRequired
Microsoft.Network Registered RegistrationRequired
Microsoft.ContainerService Registered RegistrationRequired
Microsoft.ManagedIdentity Registered RegistrationRequired
Microsoft.Authorization Registered RegistrationFree
Si vous avez déjà créé un cluster AKS sur Azure tout devrait être déjà enregistré
Si ce n'est pas le cas utiliser la commande az provider register --namespace [nom du service]
Par exemple az provider register --namespace Microsoft.ContainerService
2.2 Récupérer les information de la souscription courante
export SUBSCRIPTION_ID=$(az account show --query id -o tsv)
export TENANT_ID=$(az account show --query tenantId -o tsv)
2.3 Création d'un compte de service avec le role contributeur sur la souscription
SP_INFO=$(az ad sp create-for-rbac --role contributor --scopes="/subscriptions/$SUBSCRIPTION_ID" --output json)
export AZURE_CLIENT_ID=$(echo $SP_INFO | jq -r '.appId')
export AZURE_CLIENT_SECRET=$(echo $SP_INFO | jq -r '.password')
export AZURE_TENANT_ID=$(echo $SP_INFO | jq -r '.tenant')
echo $AZURE_CLIENT_ID
echo $AZURE_CLIENT_SECRET
echo $AZURE_TENANT_ID
2.4 Création du secret pour l'authentification de kcm
kubectl apply -f- <<EOF
apiVersion: v1
kind: Secret
metadata:
name: azure-cluster-identity-secret
namespace: kcm-system
labels:
k0rdent.mirantis.com/component: "kcm"
stringData:
clientSecret: $AZURE_CLIENT_SECRET # Password retrieved from the Service Principal
type: Opaque
EOF
2.5 Création du secret azure-aks-credential (pour le template AKS)
kubectl apply -f- <<EOF
apiVersion: v1
kind: Secret
metadata:
name: azure-aks-credential
namespace: kcm-system
labels:
k0rdent.mirantis.com/component: "kcm"
stringData:
AZURE_CLIENT_ID: "${AZURE_CLIENT_ID}"
AZURE_CLIENT_SECRET: "${AZURE_CLIENT_SECRET}"
AZURE_SUBSCRIPTION_ID: "${SUBSCRIPTION_ID}"
AZURE_TENANT_ID: "${AZURE_TENANT_ID}"
type: Opaque
EOF
# Résultat :
secret/azure-cluster-identity-secret created
# Vérifier le contenu du secret avec
kubectl view-secret azure-cluster-identity-secret -n kcm-system
# Résultat :
Viewing only available key: clientSecret
xxxxxxxxxx
2.6 Création des authentifications pour k0rdent et capz.
Tout est fait par références ce qui permet de ne pas avoir de mot de passe dans les manifestes
kubectl apply -f- <<EOF
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: AzureClusterIdentity
metadata:
name: azure-cluster-identity
namespace: kcm-system
labels:
clusterctl.cluster.x-k8s.io/move-hierarchy: "true"
k0rdent.mirantis.com/component: "kcm"
spec:
allowedNamespaces: {}
clientID: $AZURE_CLIENT_ID
clientSecret:
name: azure-cluster-identity-secret
namespace: kcm-system
tenantID: $AZURE_TENANT_ID
type: ServicePrincipal
EOF
# Résultat :
azureclusteridentity.infrastructure.cluster.x-k8s.io/azure-cluster-identity created
# Vérifier les informations
kubectl describe azureclusteridentity.infrastructure.cluster.x-k8s.io/azure-cluster-identity
2.7 Création des crédences pour kcm
Tout se fait par référence aussi
kubectl apply -f- <<EOF
apiVersion: k0rdent.mirantis.com/v1alpha1
kind: Credential
metadata:
name: azure-cluster-identity-cred
namespace: kcm-system
spec:
identityRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: AzureClusterIdentity
name: azure-cluster-identity
namespace: kcm-system
EOF
kubectl apply -f- <<EOF
apiVersion: k0rdent.mirantis.com/v1alpha1
kind: Credential
metadata:
name: azure-aks-credential
namespace: kcm-system
spec:
description: Azure AKS credentials
identityRef:
apiVersion: v1
kind: Secret
name: azure-aks-credential
namespace: kcm-system
EOF
# Résultat :
credential.k0rdent.mirantis.com/azure-cluster-identity-cred created
# Check
kubectl describe credential.k0rdent.mirantis.com/azure-cluster-identity-cred
# Regardez les informations du status
Status:
Conditions:
Last Transition Time: 2025-02-13T09:44:25Z
Message: Credential is ready
Reason: Succeeded
Status: True
Type: CredentialReady
Ready: true
2.8 Choix de la localisation du cluster
Nous prendons par exemple northeurope
. Prenez celle qui vous sied le mieux
2.9 Choix du template de cluster
kubectl get clustertemplate -n kcm-system | grep azure
# Résultat :
azure-aks-0-1-0 true
azure-hosted-cp-0-1-0 true
azure-standalone-cp-0-1-0 true
- azure-standalone-cp-0-1-0 : Permet de déployer un cluster k0s sur Azure
- azure-hosted-cp-0-1-0 : Permet de déployer un cluster kubernetes dont le control plane est géré dans le cluster d'administration (k0smotron)
- azure-aks-0-1-0 : Déploiement d'un cluster AKS classique
3. Test du template azure-aks-0-1-0
Objectif : Déployer un cluster Kubernetes managé via Azure Kubernetes Service (AKS). Cette approche tire parti de la robustesse d’AKS en termes de scalabilité, sécurité et intégration native avec les services Azure.
Points forts :
Simplicité de déploiement : Intégration directe avec le portail Azure et ses API. Gestion optimisée des ressources : Évolutivité automatique et surveillance native. Sécurité renforcée : Conformité aux standards Azure et mise à jour des correctifs gérée par Microsoft. Cas d’usage : Idéal pour des environnements de production nécessitant une haute disponibilité et une maintenance réduite, avec une prise en charge native par le cloud.
3.1 Création du déploiement du cluster
Notes : Faites bien attention au type des machines les nom sont sensible à la casse.
ex: standard_a4_v2 ne fonctionnera pas il faut avoir Standard_A4_v2
Pour connaitre tout les paramètres possible au niveau de l'attribut config il faut regarder le fichier values.yaml
situé dans le répertoire templates/cluster/azure-aks du repo https://github.com/k0rdent/kcm.git
kubectl apply -f- <<EOF
apiVersion: k0rdent.mirantis.com/v1alpha1
kind: ClusterDeployment
metadata:
name: aks-by-k0rdent
namespace: kcm-system
spec:
template: azure-aks-0-1-0
credential: azure-aks-credential
propagateCredentials: false
config:
clusterLabels: {}
location: "northeurope"
machinePools:
system:
count: 1
vmSize: Standard_A4_v2
user:
count: 1
vmSize: Standard_A4_v2
EOF
# Résultats :
clusterdeployment.k0rdent.mirantis.com/aks-by-k0rdent created
3.2 Suivi de la création du cluster
kubectl get clusterdeployment
# Résultat
NAME READY STATUS
aks-by-k0rdent False aks-by-k0rdent: Waiting for control plane provider to indicate the control plane has been initialized. aks-by-k0rdent. aks-by-k0rdent.
La clusterAPI crée l'insfrastructure Azure pour déployer l'AKS managé
kubectl get resourcegroups.resources.azure.com
# Résultat
NAME READY SEVERITY REASON MESSAGE
aks-by-k0rdent True Succeeded
On voit que le cluster AKS aks-by-k0rdent
a bien été créé
kubectl get managedclusters
NAME READY SEVERITY REASON MESSAGE
aks-by-k0rdent True Succeeded
- Node machinePools
kubectl get azureasomanagedmachinepools
# Résultat :
NAME AGE
aks-by-k0rdent-system 18m
aks-by-k0rdent-user 18m
Au final on a :
kubectl get clusterdeployment
# Résultat :
NAME READY STATUS
aks-by-k0rdent True ClusterDeployment is ready
3.3 Récupération du kubeconfig
az aks get-credentials --resource-group aks-by-k0rdent --name aks-by-k0rdent --overwrite-existing -f aks-by-k0rdent.conf
3.4 Test du cluster
KUBECONFIG=aks-by-k0rdent.conf kubectl get nodes
# Résultat :
NAME STATUS ROLES AGE VERSION
aks-systempool-34952453-vmss000000 Ready <none> 14m v1.31.1
aks-userpool-34952453-vmss000000 Ready <none> 14m v1.31.1
3.5 Nettoyage
kubectl delete clusterdeployments aks-by-k0rdent
Toutes les resources Azure créées sont supprimées
4. Test du Template azure-standalone-cp-0-1-0
Ce template permet de créer un cluster kubernetes standard le control plane et worker en VM.
Objectif : Déployer un cluster Kubernetes avec un control plane dédié, entièrement indépendant des services managés d’Azure. Cette configuration permet une personnalisation poussée et une isolation accrue des composants critiques.
Points forts :
Personnalisation avancée : Permet de définir des configurations spécifiques pour le control plane sans être limité par les contraintes d’un service managé. Isolation et sécurité : Un control plane autonome peut offrir une isolation renforcée, essentielle pour des environnements sensibles. Contrôle total sur la configuration : Les équipes peuvent affiner chaque aspect du déploiement pour répondre à des exigences précises. Cas d’usage : Particulièrement intéressant pour des scénarios où la personnalisation et l’optimisation fine du contrôle sont nécessaires, notamment dans des contextes de R&D ou d’infrastructures hybrides.
4.1 Création du manifeste de déploiement du cluster
export CLUSTER_DEPLOYMENT_NAME="standalone-cp-azure"
kubectl apply -f- <<EOF
apiVersion: k0rdent.mirantis.com/v1alpha1
kind: ClusterDeployment
metadata:
name: "${CLUSTER_DEPLOYMENT_NAME}"
namespace: kcm-system
spec:
template: azure-standalone-cp-0-1-0
credential: azure-cluster-identity-cred
propagateCredentials: true
config:
clusterLabels: {}
controlPlaneNumber: 1
workersNumber: 1
location: "northeurope"
subscriptionID: "${SUBSCRIPTION_ID}"
clusterIdentity:
name: "azure-cluster-identity"
controlPlane:
vmSize: Standard_A4_v2
worker:
vmSize: Standard_A4_v2
#tenantID: "${AZURE_TENANT_ID}"
#clientID: "${AZURE_CLIENT_ID}"
#clientSecret: "${AZURE_CLIENT_SECRET}"
EOF
Dans ce cas, nous allons avoir la création sur azure d'un esemble de resource permettant d'avoir une cluster kubernetes complet : noeuds de "control plane" et worker. Dans notre cas 1 noued de control plane et 1 noeud worker.
Composants créés :
Ressource | Type |
---|---|
pip-standalone-cp-azure-apiserver | Public IP address |
pip-standalone-cp-azure-node-natgw | Public IP address |
standalone-cp-azure-controlplane-nsg | Network security group |
standalone-cp-azure-cp-0 | Virtual machine |
standalone-cp-azure-cp-0-nic | Network Interface |
standalone-cp-azure-cp-0_OSDisk | Disk |
standalone-cp-azure-md-n5rsj-2kqvm | Virtual machine |
standalone-cp-azure-md-n5rsj-2kqvm-nic | Network Interface |
standalone-cp-azure-md-n5rsj-2kqvm_OSDisk | Disk |
standalone-cp-azure-node-natgw | NAT gateway |
standalone-cp-azure-node-nsg | Network security group |
standalone-cp-azure-node-routetable | Route table |
standalone-cp-azure-public-lb | Load balancer |
standalone-cp-azure-vnet | Virtual network |
4.2 Vérifications
kubectl get resourcegroups,virtualnetworks,virtualnetworkssubnets,natgateways
# Résultat :
NAME READY SEVERITY REASON MESSAGE
resourcegroup.resources.azure.com/standalone-cp-azure True Succeeded
NAME READY SEVERITY REASON MESSAGE
virtualnetwork.network.azure.com/standalone-cp-azure-vnet True Succeeded
NAME READY SEVERITY REASON MESSAGE
virtualnetworkssubnet.network.azure.com/standalone-cp-azure-vnet-standalone-cp-azure-controlplane-subnet True Succeeded
virtualnetworkssubnet.network.azure.com/standalone-cp-azure-vnet-standalone-cp-azure-node-subnet True Succeeded
NAME READY SEVERITY REASON MESSAGE
natgateway.network.azure.com/standalone-cp-azure-node-natgw True Succeeded
kubectl get azuremachines
# Résultat :
NAME READY SEVERITY REASON STATE AGE
standalone-cp-azure-cp-0 False Info Creating Succeeded 85s
standalone-cp-azure-md-jmnmx-qrqxt False Info WaitingForBootstrapData 67s
devops@herlec-icdc:~$ kubectl get azuremachines
# Résultat :
NAME READY SEVERITY REASON STATE AGE
standalone-cp-azure-cp-0 True Succeeded 3m3s
standalone-cp-azure-md-jmnmx-qrqxt False Info Creating Succeeded 2m45s
kubectl get azuremachines
# Résultat :
NAME READY SEVERITY REASON STATE AGE
standalone-cp-azure-cp-0 True Succeeded 21m
standalone-cp-azure-md-n5rsj-2kqvm True Succeeded 20m
kubectl get clusterdeployments
# Résultat :
NAME READY STATUS
standalone-cp-azure True ClusterDeployment is ready
4.3 Récupération du kubeconfig
kubectl get standalone-cp-azure-kubeconfig -n kcm-system
# Utilisation du plugin view-secret
kubectl view-secret standalone-cp-azure-kubeconfig -n kcm-system > kubeconfig.yaml
4.4 Test du cluster
KUBECONFIG=kubeconfig.yaml kubectl get nodes
# Résultat :
NAME STATUS ROLES AGE VERSION
standalone-cp-azure-cp-0 Ready control-plane 25m v1.31.5+k0s
standalone-cp-azure-md-n5rsj-2kqvm Ready <none> 25m v1.31.5+k0s
KUBECONFIG=kubeconfig.yaml kubectl get po -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-6cd7d8cc9f-bpfzh 1/1 Running 0 27m
kube-system calico-node-4cpmm 1/1 Running 0 27m
kube-system calico-node-ktjxt 1/1 Running 0 26m
kube-system cloud-controller-manager-765494fb6f-b67bb 0/1 CrashLoopBackOff 9 (58s ago) 27m
kube-system cloud-node-manager-8qpvz 1/1 Running 0 27m
kube-system cloud-node-manager-hvzc8 1/1 Running 0 26m
kube-system coredns-645c5d6f5b-m7jxq 1/1 Running 0 26m
kube-system coredns-645c5d6f5b-qnnzg 1/1 Running 0 26m
kube-system csi-azuredisk-controller-54ff6d4cb7-h4sg5 1/6 CrashLoopBackOff 21 (76s ago) 5m12s
kube-system csi-azuredisk-controller-54ff6d4cb7-ppggp 1/6 CrashLoopBackOff 21 (75s ago) 5m12s
kube-system csi-azuredisk-node-fz4x6 3/3 Running 0 5m12s
kube-system csi-azuredisk-node-q5pj8 3/3 Running 0 5m12s
kube-system kube-proxy-dbq2r 1/1 Running 0 26m
kube-system kube-proxy-hvtkv 1/1 Running 0 27m
kube-system metrics-server-78c4ccbc7f-6ng5r 1/1 Running 0 27m
projectsveltos sveltos-agent-manager-789964cb68-6vqtk 1/1 Running 0 27m
4.5 Gestion des erreurs
pour le cloud-controller-manager
Run: Cloud provider azure could not be initialized dynamically from secret kube-system/azure-cloud-
provider: NewCloudFromSecret: failed to get config from secret kube-system/azure-cloud-provider: secrets "azure-cloud-provider" not found
La doc n'est pas claire sur ce sujet : (https://docs.k0rdent.io/latest/admin-credentials/?h=cloud+controller+manager#cloud-provider-credentials-propagation)
4.6 Tentative de patching à la main
kubectl view-secret standalone-cp-azure-cp-mt-azure-json
J'ai créé sur le cluster le secret azure-cloud-provider
dans le ns kube-system
avec les information suivantes :
KUBECONFIG=kubeconfig.yaml kubectl apply -f- <<EOF
apiVersion: v1
kind: Secret
metadata:
name: azure-cloud-provider
namespace: kube-system
type: Opaque
stringData:
cloud-config: |-
{
"cloud": "AzurePublicCloud",
"tenantId": "${AZURE_TENANT_ID}",
"subscriptionId": "${AZURE_SUBSCRIPTION_ID}",
"aadClientId": "${AZURE_CLIENT_ID}",
"aadClientSecret": "${AZURE_CLIENT_SECRET}",
"resourceGroup": "${CLUSTER_DEPLOYMENT_NAME}",
"securityGroupName": "${CLUSTER_DEPLOYMENT_NAME}-node-nsg",
"securityGroupResourceGroup": "${CLUSTER_DEPLOYMENT_NAME}",
"location": "northeurope",
"vmType": "vmss",
"vnetName": "${CLUSTER_DEPLOYMENT_NAME}-vnet",
"vnetResourceGroup": "${CLUSTER_DEPLOYMENT_NAME}",
"subnetName": "${CLUSTER_DEPLOYMENT_NAME}-node-subnet",
"routeTableName": "${CLUSTER_DEPLOYMENT_NAME}-node-routetable",
"loadBalancerSku": "Standard",
"loadBalancerName": "",
"maximumLoadBalancerRuleCount": 250,
"useManagedIdentityExtension": false,
"useInstanceMetadata": true
}
EOF
KUBECONFIG=kubeconfig.yaml kubectl delete po -n kube-system -l component=cloud-controller-manager
KUBECONFIG=kubeconfig.yaml kubectl delete po -n kube-system -l app=csi-azuredisk-node
KUBECONFIG=kubeconfig.yaml kubectl get po -n kube-system
# Résultat
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-6cd7d8cc9f-ldl9q 1/1 Running 0 82m
calico-node-fwssw 1/1 Running 0 82m
calico-node-t5ppw 1/1 Running 0 81m
cloud-controller-manager-765494fb6f-5c5kk 1/1 Running 0 14m
cloud-node-manager-j4f4f 1/1 Running 0 81m
cloud-node-manager-kmkfn 1/1 Running 0 82m
coredns-645c5d6f5b-mnnfz 1/1 Running 0 81m
coredns-645c5d6f5b-wkfrb 1/1 Running 0 81m
csi-azuredisk-controller-54ff6d4cb7-6bfr5 6/6 Running 0 13m
csi-azuredisk-controller-54ff6d4cb7-jm2rj 6/6 Running 0 13m
csi-azuredisk-node-ckvd4 3/3 Running 0 30m
csi-azuredisk-node-ps79t 3/3 Running 0 30m
kube-proxy-fk7mt 1/1 Running 0 81m
kube-proxy-nqvcd 1/1 Running 0 82m
metrics-server-78c4ccbc7f-5hvpb 1/1 Running 0 82m
All Good !
Fin du test azure-standalone-cp-0-1-0
4.7 Cleaning
kubectl delete clusterdeployment standalone-cp-azure
# Résultat :
clusterdeployment.k0rdent.mirantis.com "standalone-cp-azure" deleted
# CA PREND DU TEMPS ! (Nettoyage de toutes les ressources Azure)
5. Test du template azure-hosted-cp-0-1-0
En pré-requis il faut du stockage sur le cluster de management
Je vais faire très simple et installer localpath-provisioner de rancher
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.31/deploy/local-path-storage.yaml
kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
Ce template permet de créer un cluster kubernetes dont le control plane est managé par k0smotron dans le cluster de management. Les workers sont déployés sous forme de VMs Azure.
Le cluster de management se trouve dans un resource group qui s'appelle aaaaa-herlec-icdc
J'ai :
- un vnet : herlec-icdc-vnet
- un subnet : default
- un nsg : herlec-icdc-nsg
- une route table herlec-icdc-routetable
5.1 Création du manifeste de déploiement du cluster
kubectl apply -f- <<EOF
apiVersion: k0rdent.mirantis.com/v1alpha1
kind: ClusterDeployment
metadata:
name: azure-hosted-cp
spec:
template: azure-hosted-cp-0-1-0
credential: azure-cluster-identity-cred
config:
clusterLabels: {}
location: "westeurope"
subscriptionID: "${AZURE_SUBSCRIPTION_ID}"
vmSize: Standard_A4_v2
workersNumber: 2
resourceGroup: aaaaa-herlec-icdc
network:
vnetName: herlec-icdc-vnet
nodeSubnetName: default
routeTableName: herlec-icdc-routetable
securityGroupName: herlec-icdc-nsg
k0smotron:
service:
type: ClusterIP
#apiPort: 30443
#konnectivityPort: 30132
EOF
J'ai une erreur concernant k0smotron qui n'a pas d'adresse IP sur son service loadbalancer. Il faudra que je regarde si au niveau du déploiement on peut gérer ce paramètre. Je vais la forcer avec l'adresse ip publique et privée de ma VM.
kubectl get svc mc-azure-hosted-cp-lb -n kcm-system
# Résultat :
mc-azure-hosted-cp-lb LoadBalancer 10.104.136.148 <pending> 6443:30661/TCP,8132:30619/TCP 58m
- Patching
kubectl patch svc kmc-azure-hosted-cp-lb --type='merge' -p '{"spec":{"externalIPs":["10.0.0.4", "13.xx.xx.xx"]}}'
kubectl get svc mc-azure-hosted-cp-lb -n kcm-system
# Résultat :
kmc-azure-hosted-cp-lb LoadBalancer 10.104.136.148 10.0.0.4,13.xxx.xx.xx 6443:30661/TCP,8132:30619/TCP 64m
5.2 Méthode alternative
Même comme ca, en forçant l'adresse IP sur l'ip publique de la VM ca ne marche pas.
Je vais donc redéployer kcml sur un cluster d'administration basé sur AKS. de cette manière l'intégration à l'eco-système Azure sera plus simple. Stockage, loadbalancers.
Je vais créer un vnet, subnet, Route table et un nsg
- resourcegroup : 001-kcm-k8s-hosted-cp
- un vnet : 001-kcm-k8s-hosted-cp-vnet
- un subnet : 001-kcm-k8s-hosted-cp-subnet-001
- un nsg : 001-kcm-k8s-hosted-cp-nsg-001
- une route table : 001-kcm-k8s-hosted-cp-rt-001
kubectl apply -f- <<EOF
apiVersion: k0rdent.mirantis.com/v1alpha1
kind: ClusterDeployment
metadata:
name: 001-kcm-k8s-hosted-cp
spec:
template: azure-hosted-cp-0-1-0
credential: azure-cluster-identity-cred
config:
clusterLabels: {}
location: "northeurope"
subscriptionID: "${AZURE_SUBSCRIPTION_ID}"
vmSize: Standard_A4_v2
workersNumber: 2
resourceGroup: 001-kcm-k8s-hosted-cp
network:
vnetName: 001-kcm-k8s-hosted-cp-vnet
nodeSubnetName: 001-kcm-k8s-hosted-cp-subnet-001
routeTableName: 001-kcm-k8s-hosted-cp-rt-001
securityGroupName: 001-kcm-k8s-hosted-cp-nsg-001
EOF
J'ai bien la création d'un loadbalancer pour le control plane géré par k0smotron
kmc-001-kcm-k8s-hosted-cp-lb LoadBalancer 10.0.228.50 135.x.x.9 6443:32191/TCP,8132:30190/TCP
# Test curl
curl -k https://135.x.x.9:6443
# Résultat :
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "Unauthorized",
"reason": "Unauthorized",
"code": 401
}
C'est OK!
5.3 Récupération du kubeconfig
kubectl view-secret 001-kcm-k8s-hosted-cp-kubeconfig -n kcm-system > 001-kcm-k8s-hosted-cp.conf
# Vérifications
KUBECONFIG=001-kcm-k8s-hosted-cp.conf kubectl get nodes
No resources found
KUBECONFIG=001-kcm-k8s-hosted-cp.conf kubectl get po -A
# Résultats
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-6cd7d8cc9f-k8xd7 0/1 Pending 0 48s
kube-system cloud-controller-manager-668b5cf9b6-trzsv 0/1 Pending 0 48s
kube-system coredns-7b7b486b6c-vjh7v 0/1 Pending 0 49s
kube-system metrics-server-78c4ccbc7f-kcmqs 0/1 Pending 0 48s
projectsveltos sveltos-agent-manager-7c967bfdd5-7c4d9 0/1 Pending 0 24s
# Aucun des pods n'est prets !
Quand on regarde la documentation il y a une note qui n'est pas clair, car on ne sait pas quand il faut patcher la resource azurecluster
Référence : https://docs.k0rdent.io/v0.1.0/template-azure/
kubectl get azurecluster
# Résultat :
NAME CLUSTER READY REASON AGE
001-kcm-k8s-hosted-cp 001-kcm-k8s-hosted-cp 3m21s
J'ai donc patché la resource pour voir si ca changeait quelque chose 😀
kubectl patch azurecluster 001-kcm-k8s-hosted-cp --type=merge --subresource status --patch 'status: {ready: true}'
# Résultat :
azurecluster.infrastructure.cluster.x-k8s.io/001-kcm-k8s-hosted-cp patched
Et ... ca fonctionne !!!
J'ai bien 2 vm qui sont provisionnées
Maintenant on a :
KUBECONFIG=001-kcm-k8s-hosted-cp.conf kubectl get po -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-6cd7d8cc9f-pvvwh 1/1 Running 0 86m
kube-system calico-node-2wfrf 1/1 Running 0 4m9s
kube-system calico-node-tw7vs 1/1 Running 0 4m10s
kube-system cloud-controller-manager-668b5cf9b6-k9jx4 0/1 CrashLoopBackOff 3 (41s ago) 6m26s
kube-system cloud-node-manager-nllzg 1/1 Running 0 4m10s
kube-system cloud-node-manager-vl2j8 1/1 Running 0 4m9s
kube-system coredns-645c5d6f5b-2tldj 1/1 Running 0 3m59s
kube-system coredns-645c5d6f5b-cv4nz 1/1 Running 0 3m59s
kube-system csi-azuredisk-controller-54ff6d4cb7-44q7b 4/6 CrashLoopBackOff 12 (23s ago) 2m41s
kube-system csi-azuredisk-controller-54ff6d4cb7-k6zvx 3/6 CrashLoopBackOff 12 (8s ago) 2m41s
kube-system csi-azuredisk-node-4p268 3/3 Running 0 2m41s
kube-system csi-azuredisk-node-qjp8j 3/3 Running 0 2m41s
kube-system konnectivity-agent-j4r4n 1/1 Running 0 4m10s
kube-system konnectivity-agent-j7lng 1/1 Running 0 4m9s
kube-system kube-proxy-nq7z6 1/1 Running 0 4m9s
kube-system kube-proxy-s6m2s 1/1 Running 0 4m10s
kube-system metrics-server-78c4ccbc7f-qdz88 1/1 Running 0 86m
projectsveltos sveltos-agent-manager-665b9479b8-8mmm4 1/1 Running 0 86m
Il va falloir fixer encore le cloud-controller-manager comme à l'étape précédente
export CLUSTER_DEPLOYMENT_NAME="001-kcm-k8s-hosted-cp"
export LOCATION="northeurope"
KUBECONFIG=001-kcm-k8s-hosted-cp.conf kubectl apply -f- <<EOF
apiVersion: v1
kind: Secret
metadata:
name: azure-cloud-provider
namespace: kube-system
type: Opaque
stringData:
cloud-config: |-
{
"cloud": "AzurePublicCloud",
"tenantId": "${AZURE_TENANT_ID}",
"subscriptionId": "${AZURE_SUBSCRIPTION_ID}",
"aadClientId": "${AZURE_CLIENT_ID}",
"aadClientSecret": "${AZURE_CLIENT_SECRET}",
"resourceGroup": "${CLUSTER_DEPLOYMENT_NAME}",
"securityGroupName": "${CLUSTER_DEPLOYMENT_NAME}-nsg-001",
"securityGroupResourceGroup": "${CLUSTER_DEPLOYMENT_NAME}",
"location": "${LOCATION}",
"vmType": "vmss",
"vnetName": "${CLUSTER_DEPLOYMENT_NAME}-vnet",
"vnetResourceGroup": "${CLUSTER_DEPLOYMENT_NAME}",
"subnetName": "${CLUSTER_DEPLOYMENT_NAME}-subnet-001",
"routeTableName": "${CLUSTER_DEPLOYMENT_NAME}-rt-001",
"loadBalancerSku": "Standard",
"loadBalancerName": "",
"maximumLoadBalancerRuleCount": 250,
"useManagedIdentityExtension": false,
"useInstanceMetadata": true
}
EOF
Je provoque un redémarrage des pods du namespace kube-system
KUBECONFIG=001-kcm-k8s-hosted-cp.conf kubectl -n kube-system rollout restart deploy cloud-controller-manager csi-azuredisk-controller calico-kube-controllers metrics-server coredns
deployment.apps/cloud-controller-manager restarted
deployment.apps/csi-azuredisk-controller restarted
deployment.apps/calico-kube-controllers restarted
deployment.apps/metrics-server restarted
deployment.apps/coredns restarted
# Vérifications :
KUBECONFIG=001-kcm-k8s-hosted-cp.conf kubectl get po -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-555f4ffcbc-ks7r5 1/1 Running 0 10s
kube-system calico-node-mvqms 1/1 Running 0 18m
kube-system calico-node-rcztl 1/1 Running 0 19m
kube-system cloud-controller-manager-8d7d987f8-jpx4n 1/1 Running 0 13s
kube-system cloud-node-manager-ltz8t 1/1 Running 0 8m32s
kube-system cloud-node-manager-msnw6 1/1 Running 0 8m32s
kube-system coredns-645c5d6f5b-cfkt2 1/1 Running 0 9m36s
kube-system coredns-6c4b58d497-685fl 0/1 Pending 0 12s
kube-system coredns-6c4b58d497-kw87j 0/1 Running 0 12s
kube-system csi-azuredisk-controller-54ff6d4cb7-rrm4n 6/6 Running 0 8m20s
kube-system csi-azuredisk-controller-54ff6d4cb7-rs7mf 6/6 Running 0 8m20s
kube-system csi-azuredisk-controller-7c45dc7f7f-twc89 0/6 Pending 0 13s
kube-system csi-azuredisk-node-vlc2b 3/3 Running 0 8m20s
kube-system csi-azuredisk-node-zsfdj 3/3 Running 0 8m20s
kube-system konnectivity-agent-pxrv2 1/1 Running 0 9m34s
kube-system konnectivity-agent-x5spn 1/1 Running 0 9m34s
kube-system kube-proxy-59rb9 1/1 Running 0 18m
kube-system kube-proxy-n5wp6 1/1 Running 0 18m
kube-system metrics-server-5b9b76db47-tqk67 0/1 Running 0 12s
kube-system metrics-server-78c4ccbc7f-w8phh 1/1 Running 0 7m11s
projectsveltos sveltos-agent-manager-7c967bfdd5-7c4d9 1/1 Running 0 28m
Maintenant tout est Okubectl !
5.4 Test du cluster créé
KUBECONFIG=001-kcm-k8s-hosted-cp.conf kubectl create deploy web --image nginx -n default
KUBECONFIG=001-kcm-k8s-hosted-cp.conf kubectl expose deploy web --type LoadBalancer -n default --port 80
KUBECONFIG=001-kcm-k8s-hosted-cp.conf kubectl get deploy,svc -n default
# Résultats :
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/web 1/1 1 1 3m22s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 34m
service/web LoadBalancer 10.101.53.225 4.208.216.226 80:32732/TCP 2m14s
Le cloud controller fonctionne bien il a créé un loadbalancer qui pointe sur les vm du cluster kubernetes
5.5 Test de l'accès au service web
curl -s -o /dev/null -I -w "%{http_code}" 4.208.216.226
200%
Le déprovisionnement fonctionne aussi très bien le loadbalancer ainsi que l'adresse ip publique sont bien supprimés
5.6 Cleaning
# Très important !
kubectl patch azurecluster 001-kcm-k8s-hosted-cp --type=merge --patch 'metadata: {finalizers: [manual]}'
kubectl delete clusterdeployment 001-kcm-k8s-hosted-cp
# CA PREND DU TEMPS ! (Nettoyage de toutes les ressources Azure)
# Libérer la resource pour sa suppression
kubectl patch azurecluster 001-kcm-k8s-hosted-cp --type=json -p='[{"op": "remove", "path": "/metadata/finalizers/0"}]'
6. Conclusions
k0rdent (kcm) démontre sa capacité à simplifier considérablement le déploiement et la gestion de clusters Kubernetes sur Azure. Que ce soit pour des clusters AKS entièrement managés, des clusters k0s autonomes, ou des clusters avec un plan de contrôle hébergé, k0rdent offre une abstraction puissante grâce à l'intégration de Cluster API.
L'automatisation fournie par k0rdent réduit la complexité, accélère les déploiements, et permet aux équipes de se concentrer sur leurs applications plutôt que sur l'infrastructure sous-jacente.
L'utilisation de templates préconfigurés et la gestion centralisée des identifiants facilitent grandement l'adoption de Kubernetes sur Azure.
Découvrez les derniers articles d'alter way