Version imprimable multipages. Cliquer ici pour imprimer.
Documentation
- 1: Documentation de Kubernetes
- 2: Installation
- 2.1: Environnement d'apprentissage
- 2.2: Télécharger Kubernetes
- 2.2.1: Construire une release
- 2.3: Environnement de production
- 2.3.1: Installer Kubernetes avec les outils de déploiement
- 2.3.1.1: Déploiement d'un cluster avec kubeadm
- 2.3.1.1.1: Installer kubeadm
- 2.3.1.1.2: Création d'un Cluster a master unique avec kubeadm
- 2.3.1.1.3: Personnalisation de la configuration du control plane avec kubeadm
- 2.3.1.1.4: Options pour la topologie en haute disponibilité
- 2.3.1.1.5: Création de clusters hautement disponibles avec kubeadm
- 2.3.1.1.6: Configurer un cluster etcd en haute disponibilité avec kubeadm
- 2.3.1.1.7: Configuration des kubelet de votre cluster avec kubeadm
- 2.3.1.1.8: Dépanner kubeadm
- 2.3.2: Solutions Cloud clés en main
- 2.3.3: On-Premises VMs
- 2.3.4: Windows dans Kubernetes
- 2.4: Solutions Cloud personnalisées
- 3: Concepts
- 3.1: Vue d'ensemble
- 3.1.1: Qu'est-ce-que Kubernetes ?
- 3.1.2: Composants de Kubernetes
- 3.1.3: Utilisation des objets Kubernetes
- 3.1.3.1: Namespaces
- 3.2: Architecture de Kubernetes
- 3.2.1: Noeuds
- 3.2.2: Communication Master-Node
- 3.2.3: Concepts sous-jacents au Cloud Controller Manager
- 3.3: Les conteneurs
- 3.3.1: Images
- 3.3.2: Classe d'exécution (Runtime Class)
- 3.3.3: L'environnement du conteneur
- 3.3.4: Hooks de cycle de vie de conteneurs
- 3.4: Workloads
- 3.4.1: Pods
- 3.4.1.1: Aperçu du Pod
- 3.4.1.2: Pods
- 3.4.1.3: Cycle de vie d'un Pod
- 3.4.1.4: Contraintes de propagation de topologie pour les Pods
- 3.4.1.5: Init Containers
- 3.4.2: Contrôleurs
- 3.4.2.1: ReplicaSet
- 3.4.2.2: Déploiements
- 3.4.2.3: StatefulSets
- 3.5: Services, Equilibreur de charge, et Réseau
- 3.5.1: EndpointSlices
- 3.5.2: Service
- 3.5.3: DNS pour les services et les pods
- 3.5.4: Ingress
- 3.6: Stockage
- 3.6.1: Volumes
- 3.6.2: Volumes persistants
- 3.7: Configuration
- 3.7.1: Secrets
- 3.8: Sécurité
- 3.9: Politiques
- 3.10: Administration d'un cluster
- 3.10.1: Vue d'ensemble de l'administration d'un cluster
- 3.10.2: Certificats
- 3.10.3: Architecture de Journalisation d'évènements (logging)
- 3.11: Extensions Kubernetes
- 3.11.1: Extensions de l'API Kubernetes
- 3.11.2: Extensions compute, stockage et réseau
- 4: Solutions indépendantes
- 4.1: Serveurs physiques
- 5: Tâches
- 5.1: Outils d'installation
- 5.1.1: Installer et configurer kubectl
- 5.1.2: Installer Minikube
- 5.2: Administration d'un cluster
- 5.2.1: Administration avec kubeadm
- 5.2.2: Gestion de la mémoire du CPU et des ressources d'API
- 5.2.3: Installation d'un fournisseur de politiques de réseau
- 5.2.4: Développer un Cloud Controller Manager
- 5.2.5: Kubernetes cloud-controller-manager
- 5.3: Configuration des Pods et des conteneurs
- 5.3.1: Allouer des ressources mémoire aux conteneurs et aux pods
- 5.3.2: Allouer des ressources CPU aux conteneurs et aux pods
- 5.3.3: Configurer la qualité de service pour les pods
- 5.3.4: Affecter des ressources supplémentaires à un conteneur
- 5.3.5: Configurer un pod en utilisant un volume pour le stockage
- 5.3.6: Configurer les comptes de service pour les pods
- 5.3.7: Récupération d'une image d'un registre privé
- 5.3.8: Configurer les Liveness, Readiness et Startup Probes
- 5.3.9: Assigner des pods aux nœuds
- 5.3.10: Configurer l'initialisation du pod
- 5.3.11: Configurer un pod pour utiliser une ConfigMap
- 5.3.12: Partager l'espace de nommage des processus entre les conteneurs d'un Pod
- 5.3.13: Convertir un fichier Docker Compose en ressources Kubernetes
- 5.4: Gérez vos objets Kubernetes
- 5.5: Injection des données dans les applications
- 5.6: Exécution des applications
- 5.7: Exécution des jobs
- 5.8: Accès aux applications dans un cluster
- 5.8.1: Tableau de bord (Dashboard)
- 5.8.2: Configurer l'accès à plusieurs clusters
- 5.8.3: Lister toutes les images de conteneur exécutées dans un cluster
- 5.9: Monitoring, Logging et Debugging
- 5.10: Extensions de Kubernetes
- 5.11: TLS
- 5.12: Fédération
- 5.13: Gestion des démons du cluster
- 5.14: Installation du catalogue de services
- 6: Tutoriels
- 6.1: Hello Minikube
- 6.2: Apprendre les bases de Kubernetes
- 6.2.1: Créer un cluster
- 6.2.1.1: Utiliser Minikube pour créer un cluster
- 6.2.1.2: Didacticiel interactif - Création d'un cluster
- 6.2.2: Déployer une application
- 6.2.2.1: Utiliser kubectl pour créer un déploiement
- 6.2.2.2: Tutoriel interactif - Déploiement d'une application
- 6.2.3: Explorez vos applications
- 6.2.4: Rendre publique votre application
- 6.2.5: Mise à l'échelle des applications
- 6.2.6: Mise à jour des applications
- 6.3: Formations en ligne
- 6.4: Configuration
- 6.5: Applications sans états
- 6.6: Applications avec états
- 6.7: Clusters
- 6.8: Services
- 7: Documents de Référence
- 7.1: Glosarium
- 7.2: Problèmes et alertes de sécurité de Kubernetes
- 7.3: Utilisation de l'API Kubernetes
- 7.4: Accéder à l'API
- 7.5: Référence de l'API
- 7.6: Référence des outils d'installation
- 7.6.1: Kubeadm
- 7.6.1.1: Aperçu de kubeadm
- 7.6.1.2: Kubeadm généré
- 7.6.1.3: kubeadm init
- 7.6.2: kubefed
- 7.7: CLI kubectl
- 7.7.1: Aperçu de kubectl
- 7.7.2: Support de JSONPath
- 7.7.3: Aide-mémoire kubectl
- 7.7.4: Commandes kubectl
- 7.7.5: Conventions d'utilisation de kubectl
- 7.7.6: kubectl
- 7.8: Référence sur les outils en ligne de commande
- 8: Contribuer à la documentation Kubernetes
- 8.1: Commencez à contribuer
- 8.2: Contributions avancées
- 8.3: Aperçu du style de documentation
- 8.3.1: Documentation Style Guide
- 8.3.2: Rédiger une nouveau sujet
- 8.3.3: Utilisation des modèles de page
- 8.3.4: Organisation du contenu
- 8.3.5: Hugo Shortcodes personnalisés
- 8.4: Vue d'ensemble des documents de référence
- 8.4.1: Génération de documentation de référence pour l'API Kubernetes
- 8.4.2: Génération de la documentation de référence pour l'API de fédération Kubernetes
- 8.4.3: Génération de pages de référence pour les composants et les outils Kubernetes
- 8.5: Participez au SIG Docs
- 8.6: Traduction de la documentation Kubernetes
1 - Documentation de Kubernetes
1.1 - Versions supportées de la documentation Kubernetes
Ce site contient la documentation de la version actuelle de Kubernetes et les quatre versions précédentes de Kubernetes.
Version courante
La version actuelle est v1.23.
Versions précédentes
2 - Installation
Utilisez cette page pour trouver le type de solution qui correspond le mieux à vos besoins.
Le choix de distribution Kubernetes dépend des ressources dont vous disposez et de la flexibilité dont vous avez besoin. Vous pouvez exécuter Kubernetes presque partout, de votre ordinateur portable aux machines virtuelles d'un fournisseur de cloud jusqu'à un rack de serveurs en bare metal. Vous pouvez également mettre en place un cluster entièrement géré en exécutant une seule commande ou bien créer votre propre cluster personnalisé sur vos serveurs bare-metal.
Solutions locales
La solution locale, installée sur votre machine, est un moyen facile de démarrer avec Kubernetes. Vous pouvez créer et tester des clusters Kubernetes sans vous soucier de la consommation des ressources et des quotas d'un cloud.
Vous devriez choisir une solution locale si vous souhaitez :
- Essayer ou commencer à apprendre Kubernetes
- Développer et réaliser des tests sur des clusters locaux
Choisissez une solution locale.
Solutions hébergées
Les solutions hébergées sont un moyen pratique de créer et de maintenir des clusters Kubernetes. Elles permettent de gérer et d'exploiter vos clusters pour que vous n'ayez pas à le faire.
Vous devriez choisir une solution hébergée si vous :
- Voulez une solution entièrement gérée
- Voulez vous concentrer sur le développement de vos applications ou services
- N'avez pas d'équipe de Site Reliability Engineering (SRE) dédiée, mais que vous souhaitez une haute disponibilité.
- Vous n'avez pas les ressources pour héberger et surveiller vos clusters
Choisissez une solution hébergée.
Solutions cloud clés en main
Ces solutions vous permettent de créer des clusters Kubernetes avec seulement quelques commandes et sont activement développées et bénéficient du soutien actif de la communauté. Elles peuvent également être hébergés sur un ensemble de fournisseurs de Cloud de type IaaS, mais elles offrent plus de liberté et de flexibilité en contrepartie d'un effort à fournir plus important.
Vous devriez choisir une solution cloud clés en main si vous :
- Voulez plus de contrôle sur vos clusters que ne le permettent les solutions hébergées
- Voulez réaliser vous même un plus grand nombre d'operations
Choisissez une solution clé en main
Solutions clés en main sur site
Ces solutions vous permettent de créer des clusters Kubernetes sur votre cloud privé, interne et sécurisé, avec seulement quelques commandes.
Vous devriez choisir une solution de cloud clé en main sur site si vous :
- Souhaitez déployer des clusters sur votre cloud privé
- Disposez d'une équipe SRE dédiée
- Avez les ressources pour héberger et surveiller vos clusters
Choisissez une solution clé en main sur site.
Solutions personnalisées
Les solutions personnalisées vous offrent le maximum de liberté sur vos clusters, mais elles nécessitent plus d'expertise. Ces solutions vont du bare-metal aux fournisseurs de cloud sur différents systèmes d'exploitation.
Choisissez une solution personnalisée.
A suivre
Allez à Choisir la bonne solution pour une liste complète de solutions.
2.1 - Environnement d'apprentissage
2.1.1 - Installer Kubernetes avec Minikube
Minikube est un outil facilitant l’exécution locale de Kubernetes. Minikube exécute un cluster Kubernetes à nœud unique dans une machine virtuelle (VM) de votre ordinateur portable pour les utilisateurs qui souhaitent essayer Kubernetes ou le développer au quotidien.
Fonctionnalités de Minikube
Minikube prend en charge les fonctionnalités Kubernetes suivantes:
- DNS
- NodePorts
- ConfigMaps et Secrets
- Dashboards
- Container Runtime: Docker, CRI-O, et containerd
- Activation de la CNI (Container Network Interface)
- Ingress
Installation
Consultez Installation de Minikube.
Démarrage rapide
Cette brève démonstration vous explique comment démarrer, utiliser et supprimer les minikube localement. Suivez les étapes ci-dessous pour commencer et explorer Minikube.
-
Lancez Minikube et créez un cluster:
minikube start
Le résultat est similaire à ceci:
Starting local Kubernetes cluster... Running pre-create checks... Creating machine... Starting local Kubernetes cluster...
Pour plus d'informations sur le démarrage de votre cluster avec une version spécifique de Kubernetes, une machine virtuelle ou un environnement de conteneur, voir Démarrage d'un cluster.
-
Vous pouvez maintenant interagir avec votre cluster à l'aide de kubectl. Pour plus d'informations, voir Interagir avec votre cluster.
Créons un déploiement Kubernetes en utilisant une image existante nommée
echoserver
, qui est un serveur HTTP, et exposez-la sur le port 8080 à l’aide de--port
.kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.10
Le résultat est similaire à ceci:
deployment.apps/hello-minikube created
-
Pour accéder au Deployment
hello-minikube
, exposez-le comme un Service:kubectl expose deployment hello-minikube --type=NodePort --port=8080
L'option
--type=NodePort
spécifie le type du Service.Le résultat est similaire à ceci:
service/hello-minikube exposed
-
Le Pod
hello-minikube
est maintenant lancé, mais vous devez attendre que le Pod soit opérationnel avant d'y accéder via le Service.Vérifiez si le Pod est opérationnel:
kubectl get pod
Si la sortie affiche le
STATUS
commeContainerCreating
, le Pod est toujours en cours de création:NAME READY STATUS RESTARTS AGE hello-minikube-3383150820-vctvh 0/1 ContainerCreating 0 3s
Si la sortie indique le statut
STATUS
commeRunning
, le Pod est maintenant opérationnel:NAME READY STATUS RESTARTS AGE hello-minikube-3383150820-vctvh 1/1 Running 0 13s
-
Obtenez l'URL du Service exposé pour afficher les détails du service:
minikube service hello-minikube --url
-
Pour afficher les détails de votre cluster local, copiez et collez l’URL que vous avez obtenue en tant que sortie dans votre navigateur.
Le résultat est similaire à ceci:
Hostname: hello-minikube-7c77b68cff-8wdzq Pod Information: -no pod information available- Server values: server_version=nginx: 1.13.3 - lua: 10008 Request Information: client_address=172.17.0.1 method=GET real path=/ query= request_version=1.1 request_scheme=http request_uri=http://192.168.99.100:8080/ Request Headers: accept=*/* host=192.168.99.100:30674 user-agent=curl/7.47.0 Request Body: -no body in request-
Si vous ne souhaitez plus que le service et le cluster s'exécutent, vous pouvez les supprimer.
-
Supprimez le Service
hello-minikube
:kubectl delete services hello-minikube
Le résultat est similaire à ceci:
service "hello-minikube" deleted
-
Supprimez le Deployment
hello-minikube
:kubectl delete deployment hello-minikube
Le résultat est similaire à ceci:
deployment.extensions "hello-minikube" deleted
-
Arrêtez le cluster de minikube local:
minikube stop
Le résultat est similaire à ceci:
Stopping "minikube"... "minikube" stopped.
Pour plus d'informations, voir Arrêt d'un cluster.
-
Supprimez le cluster de minikube local:
minikube delete
Le résultat est similaire à ceci:
Deleting "minikube" ... The "minikube" cluster has been deleted.
Pour plus d'informations, voir Suppression d'un cluster.
Gérer votre cluster
Démarrer un cluster
La commande minikube start
peut être utilisée pour démarrer votre cluster.
Cette commande crée et configure une machine virtuelle qui exécute un cluster Kubernetes à un seul nœud.
Cette commande configure également kubectl pour communiquer avec ce cluster.
Si vous êtes derrière un proxy Web, vous devez transmettre ces informations à la commande minikube start
:
https_proxy=<my proxy> minikube start --docker-env http_proxy=<my proxy> --docker-env https_proxy=<my proxy> --docker-env no_proxy=192.168.99.0/24
Malheureusement, définir les seules variables d'environnement ne fonctionne pas.
Minikube crée également un contexte "minikube" et le définit par défaut dans kubectl.
Pour revenir à ce contexte, exécutez la commande suivante: kubectl config use-context minikube
.
Spécifier la version de Kubernetes
Vous pouvez spécifier la version de Kubernetes pour Minikube à utiliser en ajoutant la chaîne --kubernetes-version
à la commande minikube start
.
Par exemple, pour exécuter la version v1.23.0, procédez comme suit:
minikube start --kubernetes-version v1.23.0
Spécification du pilote de machine virtuelle
Vous pouvez changer le pilote de machine virtuelle en ajoutant l'indicateur --vm-driver=<nom_du_pilote>
à minikube start
.
Par exemple, la commande serait:
minikube start --vm-driver=<nom_du_pilote>
Minikube prend en charge les pilotes suivants:
- virtualbox
- vmwarefusion
- kvm2 (installation du pilote)
- hyperkit (installation du pilote)
- hyperv (installation du pilote)
Notez que l'adresse IP ci-dessous est dynamique et peut changer. Il peut être récupéré avec
minikube ip
. - vmware (installation du pilote) (VMware unified driver)
- none (Exécute les composants Kubernetes sur l’hôte et non sur une machine virtuelle. Il n'est pas recommandé d'exécuter le pilote none sur des postes de travail personnels. L'utilisation de ce pilote nécessite Docker (docker installer) et un environnement Linux)
Démarrage d'un cluster sur des exécutions de conteneur alternatives
Vous pouvez démarrer Minikube aux exécutions de conteneurs suivantes.
Pour utiliser containerd en tant que moteur d'exécution du conteneur, exécutez:
minikube start \
--network-plugin=cni \
--enable-default-cni \
--container-runtime=containerd \
--bootstrapper=kubeadm
Ou vous pouvez utiliser la version étendue:
minikube start \
--network-plugin=cni \
--enable-default-cni \
--extra-config=kubelet.container-runtime=remote \
--extra-config=kubelet.container-runtime-endpoint=unix:///run/containerd/containerd.sock \
--extra-config=kubelet.image-service-endpoint=unix:///run/containerd/containerd.sock \
--bootstrapper=kubeadm
Pour utiliser CRI-O comme environnement d'exécution du conteneur, exécutez:
minikube start \
--network-plugin=cni \
--enable-default-cni \
--container-runtime=cri-o \
--bootstrapper=kubeadm
Ou vous pouvez utiliser la version étendue:
minikube start \
--network-plugin=cni \
--enable-default-cni \
--extra-config=kubelet.container-runtime=remote \
--extra-config=kubelet.container-runtime-endpoint=/var/run/crio.sock \
--extra-config=kubelet.image-service-endpoint=/var/run/crio.sock \
--bootstrapper=kubeadm
Utiliser des images locales en réutilisant le démon Docker
Lorsque vous utilisez une seule machine virtuelle pour Kubernetes, il est utile de réutiliser le démon Docker intégré de Minikube. La réutilisation du démon intégré signifie que vous n’avez pas besoin de créer un registre Docker sur votre ordinateur hôte et d’y insérer l’image. Au lieu de cela, vous pouvez créer le même démon Docker que Minikube, ce qui accélère les expériences locales.
:latest
est la valeur par défaut, avec une stratégie d'extraction d'image par défaut correspondante de Always
, une erreur d'extraction d'image (ErrImagePull
) est éventuellement générée si vous n'avez pas l'image Docker dans le registre par défaut de Docker (généralement DockerHub). .
Pour travailler avec le démon Docker sur votre hôte Mac/Linux, utilisez la commande docker-env
dans votre shell:
eval $(minikube docker-env)
Vous pouvez maintenant utiliser Docker sur la ligne de commande de votre ordinateur hôte Mac/Linux pour communiquer avec le démon Docker dans la VM Minikube:
docker ps
Sur Centos 7, Docker peut signaler l’erreur suivante:
Could not read CA certificate "/etc/docker/ca.pem": open /etc/docker/ca.pem: no such file or directory
Vous pouvez résoudre ce problème en mettant à jour /etc/sysconfig/docker
pour vous assurer que les modifications de l'environnement de Minikube sont respectées:
< DOCKER_CERT_PATH=/etc/docker
---
> if [ -z "${DOCKER_CERT_PATH}" ]; then
> DOCKER_CERT_PATH=/etc/docker
> fi
Configuration de Kubernetes
Minikube a une fonction de "configurateur" qui permet aux utilisateurs de configurer les composants Kubernetes avec des valeurs arbitraires.
Pour utiliser cette fonctionnalité, vous pouvez utiliser l'indicateur --extra-config
de la commande minikube start
.
Cet indicateur est répété, vous pouvez donc le transmettre plusieurs fois avec plusieurs valeurs différentes pour définir plusieurs options.
Cet indicateur prend une chaîne de la forme composant.key=valeur
, où composant
est l'une des chaînes de la liste ci-dessous, key
est une valeur de la structure de configuration et valeur
est la valeur à définir.
Des clés valides peuvent être trouvées en examinant la documentation de Kubernetes composantconfigs
pour chaque composant.
Voici la documentation pour chaque configuration prise en charge:
Exemples
Pour changer le paramètre MaxPods
en 5 sur le Kubelet, passez cet indicateur: --extra-config=kubelet.MaxPods=5
.
Cette fonctionnalité prend également en charge les structures imbriquées.
Pour modifier le paramètre LeaderElection.LeaderElect
sur true
sur le planificateur, transmettez cet indicateur: --extra-config=scheduler.LeaderElection.LeaderElect=true
.
Pour définir le AuthorizationMode
du apiserver
sur RBAC
, vous pouvez utiliser: --extra-config=apiserver.authorization-mode=RBAC
.
Arrêter un cluster
La commande minikube stop
peut être utilisée pour arrêter votre cluster.
Cette commande arrête la machine virtuelle Minikube, mais conserve tout l'état et les données du cluster.
Le redémarrage du cluster le restaurera à son état précédent.
Suppression d'un cluster
La commande minikube delete
peut être utilisée pour supprimer votre cluster.
Cette commande ferme et supprime la machine virtuelle Minikube.
Aucune donnée ou état n'est conservé.
Mise à niveau de minikube
Voir upgrade minikube
Interagir avec votre cluster
Kubectl
La commande minikube start
crée un contexte kubectl appelé "minikube".
Ce contexte contient la configuration pour communiquer avec votre cluster Minikube.
Minikube définit automatiquement ce contexte par défaut, mais si vous devez y revenir ultérieurement, exécutez:
kubectl config use-context minikube
,
Ou passez le contexte sur chaque commande comme ceci: kubectl get pods --context=minikube
.
Dashboard
Pour accéder au Kubernetes Dashboard, lancez cette commande dans un shell après avoir lancé Minikube pour obtenir l'adresse:
minikube dashboard
Services
Pour accéder à un service exposé via un port de nœud, exécutez cette commande dans un shell après le démarrage de Minikube pour obtenir l'adresse:
minikube service [-n NAMESPACE] [--url] NAME
La mise en réseau
La machine virtuelle Minikube est exposée au système hôte via une adresse IP routable uniquement depuis le hôte, qui peut être obtenue à l'aide de la commande minikube ip
.
Tous les services de type NodePort
sont accessibles via cette adresse IP, sur le NodePort.
Pour déterminer le NodePort pour votre service, vous pouvez utiliser une commande kubectl
comme celle-ci:
kubectl get service $SERVICE --output='jsonpath="{.spec.ports[0].nodePort}"'
Volumes persistants
Minikube supporte les PersistentVolumes de type hostPath
.
Ces volumes persistants sont mappés vers un répertoire à l'intérieur de la VM Minikube.
La machine virtuelle Minikube démarre dans un fichier tmpfs, de sorte que la plupart des répertoires ne seront pas conservés lors des redémarrages avec (minikube stop
).
Toutefois, Minikube est configuré pour conserver les fichiers stockés dans les répertoires d’hôte suivants:
/data
/var/lib/minikube
/var/lib/docker
Voici un exemple de configuration PersistentVolume permettant de conserver des données dans le répertoire /data
:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0001
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 5Gi
hostPath:
path: /data/pv0001/
Dossiers hôtes montés
Certains pilotes vont monter un dossier hôte dans la VM afin de pouvoir facilement partager des fichiers entre la VM et l'hôte. Celles-ci ne sont pas configurables pour le moment et diffèrent selon le pilote et le système d'exploitation que vous utilisez.
Pilote | OS | HostFolder | VM |
---|---|---|---|
VirtualBox | Linux | /home |
/hosthome |
VirtualBox | macOS | /Users |
/Users |
VirtualBox | Windows | C:/Users |
/c/Users |
VMware Fusion | macOS | /Users |
/Users |
Xhyve | macOS | /Users |
/Users |
Registres de conteneurs privés
Pour accéder à un registre de conteneurs privé, suivez les étapes de cette page.
Nous vous recommandons d'utiliser ImagePullSecrets
, mais si vous souhaitez configurer l'accès sur la VM Minikube, vous pouvez placer le .dockercfg
dans le repertoire /home/docker
ou le config.json
dans le repertoire /home/docker/.docker
.
Add-ons
Pour que Minikube puisse démarrer ou redémarrer correctement des addons personnalisés, placez les addons que vous souhaitez lancer avec Minikube dans le répertoire ~/.minikube/addons
.
Les extensions de ce dossier seront déplacées vers la VM Minikube et lancées à chaque démarrage ou redémarrage de Minikube.
Utilisation de Minikube avec un proxy HTTP
Minikube crée une machine virtuelle qui inclut Kubernetes et un démon Docker. Lorsque Kubernetes tente de planifier des conteneurs à l'aide de Docker, le démon Docker peut nécessiter un accès réseau externe pour extraire les conteneurs.
Si vous êtes derrière un proxy HTTP, vous devrez peut-être fournir à Docker les paramètres de proxy.
Pour ce faire, transmettez les variables d’environnement requises en tant qu’indicateurs lors de la création de minikube start
.
Par exemple:
minikube start --docker-env http_proxy=http://$YOURPROXY:PORT \
--docker-env https_proxy=https://$YOURPROXY:PORT
Si l'adresse de votre machine virtuelle est 192.168.99.100, il est probable que vos paramètres de proxy empêcheront kubectl
de l'atteindre directement.
Pour contourner la configuration du proxy pour cette adresse IP, vous devez modifier vos paramètres no_proxy.
Vous pouvez le faire avec:
export no_proxy=$no_proxy,$(minikube ip)
Problèmes connus
Les fonctionnalités nécessitant plusieurs nœuds ne fonctionneront pas dans Minikube.
Conception
Minikube utilise libmachine pour le provisionnement de machines virtuelles, et kubeadm mettre en service un cluster Kubernetes.
Pour plus d'informations sur Minikube, voir la proposition.
Liens supplémentaires
- Objectifs et non-objectifs: Pour les objectifs et non-objectifs du projet Minikube, veuillez consulter notre roadmap.
- Guide de développement: Voir CONTRIBUTING.md pour avoir un aperçu de comment envoyer des pull requests.
- Construire Minikube: Pour obtenir des instructions sur la création / test de Minikube à partir des sources, voir le guide de build.
- Ajout d'une nouvelle dépendance: Pour savoir comment ajouter une nouvelle dépendance à Minikube, voir la section guide d'ajout de dépendances.
- Ajout d'un nouvel addon: Pour savoir comment ajouter un nouvel addon pour Minikube, reportez-vous au Ajout d’un addon.
- MicroK8s: Les utilisateurs de Linux qui souhaitent éviter d’exécuter une machine virtuelle peuvent envisager MicroK8s.
Communauté
Les contributions, questions et commentaires sont les bienvenus et sont encouragés ! Les développeurs de minikube sont dans le canal #minikube du Slack de Kubernetes (recevoir une invitation ici). Nous avons également la liste de diffusion kubernetes-dev Google Groupes. Si vous publiez sur la liste, veuillez préfixer votre sujet avec "minikube:".
2.2 - Télécharger Kubernetes
2.2.1 - Construire une release
Vous pouvez soit compiler une version à partir des sources, soit télécharger une version pré-compilée. Si vous ne prévoyez pas de développer Kubernetes nous vous suggérons d'utiliser une version pré-compilée de la version actuelle, que l'on peut trouver dans le répertoire Release Notes.
Le code source de Kubernetes peut être téléchargé sur le repo kubernetes/kubernetes.
Installer à partir des sources
Si vous installez simplement une version à partir des sources, il n'est pas nécessaire de mettre en place un environnement golang complet car tous les builds se font dans un conteneur Docker.
Construire une release est simple.
git clone https://github.com/kubernetes/kubernetes.git
cd kubernetes
make release
Pour plus de détails sur le processus de release, voir le repertoire build
dans kubernetes/kubernetes.
2.3 - Environnement de production
2.3.1 - Installer Kubernetes avec les outils de déploiement
2.3.1.1 - Déploiement d'un cluster avec kubeadm
2.3.1.1.1 - Installer kubeadm
Cette page vous apprend comment installer la boîte à outils kubeadm
.
Pour plus d'informations sur la création d'un cluster avec kubeadm, une fois que vous avez effectué ce processus d'installation, voir la page: Utiliser kubeadm pour créer un cluster.
Pré-requis
- Une ou plusieurs machines exécutant:
- Ubuntu 16.04+
- Debian 9+
- CentOS 7
- Red Hat Enterprise Linux (RHEL) 7
- Fedora 25+
- HypriotOS v1.0.1+
- Flatcar Container Linux (testé avec 2512.3.0)
- 2 Go ou plus de RAM par machine (toute quantité inférieure laissera peu de place à vos applications)
- 2 processeurs ou plus
- Connectivité réseau complète entre toutes les machines du cluster (réseau public ou privé)
- Nom d'hôte, adresse MAC et product_uuid uniques pour chaque nœud. Voir ici pour plus de détails.
- Certains ports doivent êtres ouverts sur vos machines. Voir ici pour plus de détails.
- Swap désactivé. Vous devez impérativement désactiver le swap pour que la kubelet fonctionne correctement.
Vérifiez que les adresses MAC et product_uuid sont uniques pour chaque nœud
- Vous pouvez obtenir l'adresse MAC des interfaces réseau en utilisant la commande
ip link
ouifconfig -a
- Le product_uuid peut être vérifié en utilisant la commande
sudo cat /sys/class/dmi/id/product_uuid
Il est très probable que les périphériques matériels aient des adresses uniques, bien que certaines machines virtuelles puissent avoir des valeurs identiques. Kubernetes utilise ces valeurs pour identifier de manière unique les nœuds du cluster. Si ces valeurs ne sont pas uniques à chaque nœud, le processus d'installation peut échouer.
Vérifiez les cartes réseaux
Si vous avez plusieurs cartes réseaux et que vos composants Kubernetes ne sont pas accessibles par la route par défaut, nous vous recommandons d’ajouter une ou plusieurs routes IP afin que les adresses de cluster Kubernetes soient acheminées via la carte approprié.
Permettre à iptables de voir le trafic ponté
Assurez-vous que le module br_netfilter
est chargé. Cela peut être fait en exécutant lsmod | grep br_netfilter
. Pour le charger explicitement, appelez sudo modprobe br_netfilter
.
Pour que les iptables de votre nœud Linux voient correctement le trafic ponté, vous devez vous assurer que net.bridge.bridge-nf-call-iptables
est défini sur 1 dans votre configuration sysctl
, par ex.
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system
Pour plus de détails, veuillez consulter la page Configuration requise pour le plug-in réseau.
Vérifiez les ports requis
nœuds maîtres (masters)
Protocole | Direction | Plage de Port | Utilisé pour | Utilisé par |
---|---|---|---|---|
TCP | Entrant | 6443* | Kubernetes API server | Tous |
TCP | Entrant | 2379-2380 | Etcd server client API | kube-apiserver, etcd |
TCP | Entrant | 10250 | Kubelet API | Lui-même, Control plane |
TCP | Entrant | 10251 | kube-scheduler | Lui-même |
TCP | Entrant | 10252 | kube-controller-manager | Lui-même |
nœuds workers
Protocole | Direction | Plage de Port | Utilisé pour | Utilisé par |
---|---|---|---|---|
TCP | Entrant | 10250 | Kubelet API | Lui-même, Control plane |
TCP | Entrant | 30000-32767 | NodePort Services** | Eux-mêmes |
** Plage de ports par défaut pour les Services NodePort.
Tous les numéros de port marqués d'un * sont écrasables. Vous devrez donc vous assurer que les ports personnalisés que vous utilisez sont également ouverts.
Bien que les ports etcd soient inclus dans les nœuds masters, vous pouvez également héberger votre propre cluster etcd en externe ou sur des ports personnalisés.
Le plug-in de réseau de pod que vous utilisez (voir ci-dessous) peut également nécessiter certains ports à ouvrir. Étant donné que cela diffère d’un plugin à l’autre, veuillez vous reporter à la documentation des plugins sur le(s) port(s) requis(s).
Installation du runtime
Pour exécuter des conteneurs dans des pods, Kubernetes utilise un container runtime.
Par défaut, Kubernetes utilise le Container Runtime Interface (CRI) pour s'interfacer avec votre environnement d'exécution de conteneur choisi.
Si vous ne spécifiez pas de runtime, kubeadm essaie automatiquement de détecter un Runtime de conteneur en parcourant une liste de sockets de domaine Unix bien connus. Le tableau suivant répertorie les environnements d'exécution des conteneurs et leurs chemins de socket associés:
Runtime | Chemin vers le socket de domaine Unix |
---|---|
Docker | /var/run/docker.sock |
containerd | /run/containerd/containerd.sock |
CRI-O | /var/run/crio/crio.sock |
Si Docker et containerd sont détectés, Docker est prioritaire. C'est nécessaire car Docker 18.09 est livré avec containerd et les deux sont détectables même si vous installez Docker. Si deux autres environnements d'exécution ou plus sont détectés, kubeadm se ferme avec une erreur.
Le kubelet s'intègre à Docker via l'implémentation CRI intégrée de dockershim
.
Voir runtimes de conteneur pour plus d'informations.
Par défaut, kubeadm utilise Docker comme environnement d'exécution du conteneur.
Le kubelet s'intègre à Docker via l'implémentation CRI intégrée de dockershim
.
Voir runtimes de conteneur pour plus d'informations.
Installation de kubeadm, des kubelets et de kubectl
Vous installerez ces paquets sur toutes vos machines:
-
kubeadm
: la commande pour initialiser le cluster. -
la
kubelet
: le composant qui s'exécute sur toutes les machines de votre cluster et fait des actions comme le démarrage des pods et des conteneurs. -
kubectl
: la ligne de commande utilisée pour parler à votre cluster.
kubeadm n'installera pas ni ne gèrera les kubelet
ou kubectl
pour vous.
Vous devez vous assurer qu'ils correspondent à la version du control plane de Kubernetes que vous souhaitez que kubeadm installe pour vous. Si vous ne le faites pas, vous risquez qu'une
erreur de version se produise, qui pourrait conduire à un comportement inattendu.
Cependant, une version mineure entre les kubelets et le control plane est pris en charge,
mais la version de la kubelet ne doit jamais dépasser la version de l'API server.
Par exemple, les kubelets exécutant la version 1.7.0 devraient être entièrement compatibles avec un API server en 1.8.0,
mais pas l'inverse.
For information about installing kubectl
, see Installation et configuration kubectl.
Pour plus d'informations sur les compatibilités de version, voir:
- Kubernetes version et politique de compatibilité de version
- Kubeadm-specific politique de compatibilité de version
sudo apt-get update && sudo apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF
# Mettre SELinux en mode permissif (le désactiver efficacement)
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
sudo systemctl enable --now kubelet
Note:
-
Mettre SELinux en mode permissif en lançant
setenforce 0
etsed ...
le désactive efficacement. C'est nécessaire pour permettre aux conteneurs d'accéder au système de fichiers hôte, qui est nécessaire par exemple pour les réseaux de pod. Vous devez le faire jusqu'à ce que le support de SELinux soit amélioré dans Kubelet. -
Vous pouvez laisser SELinux activé si vous savez comment le configurer, mais il peut nécessiter des paramètres qui ne sont pas pris en charge par kubeadm.
Installez les plugins CNI (requis pour la plupart des réseaux de pods) :
CNI_VERSION="v0.8.2"
ARCH="amd64"
sudo mkdir -p /opt/cni/bin
curl -L "https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-${ARCH}-${CNI_VERSION}.tgz" | sudo tar -C /opt/cni/bin -xz
Définissez le répertoire pour télécharger les fichiers de commande
DOWNLOAD_DIR=/usr/local/bin
sudo mkdir -p $DOWNLOAD_DIR
Installez crictl (requis pour Kubeadm / Kubelet Container Runtime Interface (CRI))
CRICTL_VERSION="v1.22.0"
ARCH="amd64"
curl -L "https://github.com/kubernetes-sigs/cri-tools/releases/download/${CRICTL_VERSION}/crictl-${CRICTL_VERSION}-linux-${ARCH}.tar.gz" | sudo tar -C $DOWNLOAD_DIR -xz
Installez kubeadm
, kubelet
, kubectl
et ajoutez un service systemd kubelet
:
RELEASE_VERSION="v0.6.0"
RELEASE="$(curl -sSL https://dl.k8s.io/release/stable.txt)"
ARCH="amd64"
cd $DOWNLOAD_DIR
sudo curl -L --remote-name-all https://storage.googleapis.com/kubernetes-release/release/${RELEASE}/bin/linux/${ARCH}/{kubeadm,kubelet,kubectl}
sudo chmod +x {kubeadm,kubelet,kubectl}
curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubelet/lib/systemd/system/kubelet.service" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /etc/systemd/system/kubelet.service
sudo mkdir -p /etc/systemd/system/kubelet.service.d
curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubeadm/10-kubeadm.conf" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
Activez et démarrez kubelet
:
sudo systemctl enable --now kubelet
/usr
comme un système de fichiers en lecture seule.
Avant de démarrer votre cluster, vous devez effectuer des étapes supplémentaires pour configurer un répertoire accessible en écriture.
Consultez le Guide de dépannage de Kubeadm pour savoir comment configurer un répertoire accessible en écriture.
Kubelet redémarre maintenant toutes les quelques secondes, car il attend les instructions de kubeadm dans une boucle de crash.
Configurer le driver de cgroup utilisé par la kubelet sur un nœud master
Lorsque vous utilisez Docker, kubeadm détecte automatiquement le pilote ( driver ) de cgroup pour kubelet
et le configure dans le fichier /var/lib/kubelet/config.yaml
lors de son éxecution.
Si vous utilisez un autre CRI, vous devez passer votre valeur cgroupDriver
avec kubeadm init
, comme ceci :
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: <value>
Pour plus de détails, veuillez lire Utilisation de kubeadm init avec un fichier de configuration.
Veuillez noter que vous devez seulement le faire si le driver de cgroupe de votre CRI
n'est pas cgroupfs
, car c'est déjà la valeur par défaut dans la kubelet.
--cgroup-driver
est obsolète par kubelet, si vous l'avez dans/var/lib/kubelet/kubeadm-flags.env
ou /etc/default/kubelet
(/etc/sysconfig/kubelet
pour les RPM), veuillez le supprimer et utiliser à la place KubeletConfiguration
(stocké dans/var/lib/kubelet/config.yaml
par défaut).
Il est nécessaire de redémarrer la kubelet:
sudo systemctl daemon-reload
sudo systemctl restart kubelet
La détection automatique du pilote cgroup pour d'autres runtimes de conteneur comme CRI-O et containerd est un travail en cours.
Dépannage
Si vous rencontrez des difficultés avec kubeadm, veuillez consulter notre documentation de dépannage.
A suivre
2.3.1.1.2 - Création d'un Cluster a master unique avec kubeadm
kubeadm vous aide à démarrer un cluster Kubernetes minimum, viable et conforme aux meilleures pratiques. Avec kubeadm, votre cluster doit passer les tests de Conformance Kubernetes. Kubeadm prend également en charge d'autres fonctions du cycle de vie, telles que les mises à niveau, la rétrogradation et la gestion des bootstrap tokens.
Comme vous pouvez installer kubeadm sur différents types de machines (par exemple, un ordinateur portable, un serveur, Raspberry Pi, etc.), il est parfaitement adapté à l'intégration avec des systèmes d'approvisionnement comme Terraform ou Ansible.
La simplicité de kubeadm lui permet d'être utilisé dans une large gamme de cas d'utilisation:
- Les nouveaux utilisateurs peuvent commencer par kubeadm pour essayer Kubernetes pour la première fois.
- Les utilisateurs familiarisés avec Kubernetes peuvent créer des clusters avec kubeadm et tester leurs applications.
- Les projets plus importants peuvent inclure kubeadm en tant que brique de base dans un système plus complexe pouvant également inclure d'autres outils d'installation.
Kubeadm est conçu pour être un moyen simple pour les nouveaux utilisateurs de commencer à essayer Kubernetes, pour la première fois éventuellement. C'est un moyen pour les utilisateurs avancés de tester leur application en même temps qu'un cluster facilement, et aussi être une brique de base dans un autre écosystème et/ou un outil d’installation avec une plus grand portée.
Vous pouvez installer très facilement kubeadm sur des systèmes d'exploitation prenant en charge l'installation des paquets deb ou rpm. Le SIG responsable de kubeadm, SIG Cluster Lifecycle, fournit ces paquets pré-construits pour vous, mais vous pouvez également les construire à partir des sources pour d'autres systèmes d'exploitation.
Maturité de kubeadm
Elément | Niveau de maturité |
---|---|
Command line UX | GA |
Implementation | GA |
Config file API | beta |
CoreDNS | GA |
kubeadm alpha subcommands | alpha |
High availability | alpha |
DynamicKubeletConfig | alpha |
Self-hosting | alpha |
Les fonctionnalités globales de kubeadm sont GA. Quelques sous-fonctionnalités, comme
la configuration, les API de fichiers sont toujours en cours de développement. L'implémentation de la création du cluster
peut changer légèrement au fur et à mesure que l'outil évolue, mais la mise en œuvre globale devrait être assez stable.
Toutes les commandes sous kubeadm alpha
sont par définition prises en charge au niveau alpha.
Calendrier de support
Les versions de Kubernetes sont généralement prises en charge pendant neuf mois et pendant cette
période, une version de correctif peut être publiée à partir de la branche de publication si un bug grave ou un
problème de sécurité est trouvé. Voici les dernières versions de Kubernetes et le calendrier de support
qui s'applique également à kubeadm
.
Version de Kubernetes | Date de sortie de la version | Fin de vie |
---|---|---|
v1.6.x | Mars 2017 | Décembre 2017 |
v1.7.x | Juin 2017 | Mars 2018 |
v1.8.x | Septembre 2017 | Juin 2018 |
v1.9.x | Décembre 2017 | Septembre 2018 |
v1.10.x | Mars 2018 | Décembre 2018 |
v1.11.x | Juin 2018 | Mars 2019 |
v1.12.x | Septembre 2018 | Juin 2019 |
v1.13.x | Décembre 2018 | Septembre 2019 |
Pré-requis
- Une ou plusieurs machines exécutant un système d'exploitation compatible deb/rpm, par exemple Ubuntu ou CentOS
- 2 Go ou plus de RAM par machine. Si vous essayez moins cela laissera trop peu de place pour vos applications.
- 2 processeurs ou plus sur le master
- Connectivité réseau entre toutes les machines du cluster, qu'il soit public ou privé.
Objectifs
- Installer un cluster Kubernetes à master unique ou un cluster à haute disponibilité
- Installez un réseau de pods sur le cluster afin que vos pods puissent se parler
Instructions
Installer kubeadm sur vos hôtes
Voir "Installation de kubeadm".
Si vous avez déjà installé kubeadm, lancez apt-get update && apt-get upgrade
ou yum update
pour obtenir la dernière version de kubeadm.
Lorsque vous effectuez une mise à niveau, la kubelet redémarre plusieurs fois au bout de quelques secondes car elle attend dans une boucle de blocage kubeadm pour lui dire quoi faire. Ce fonctionnement est normal. Une fois que vous avez initialisé votre master, la kubelet s'exécute normalement.
Initialiser votre master
Le master est la machine sur laquelle s'exécutent les composants du control plane, y compris etcd (la base de données du cluster) et l'API serveur (avec lequel la CLI kubectl communique).
- Choisissez un add-on réseau pour les pods et vérifiez s’il nécessite des arguments à
passer à l'initialisation de kubeadm. Selon le
fournisseur tiers que vous choisissez, vous devrez peut-être définir le
--pod-network-cidr
sur une valeur spécifique au fournisseur. Voir Installation d'un add-on réseau de pod. - (Facultatif) Sauf indication contraire, kubeadm utilise l'interface réseau associée
avec la passerelle par défaut pour annoncer l’IP du master. Pour utiliser une autre
interface réseau, spécifiez l'option
--apiserver-advertise-address=<ip-address>
àkubeadm init
. Pour déployer un cluster Kubernetes en utilisant l’adressage IPv6, vous devez spécifier une adresse IPv6, par exemple--apiserver-advertise-address=fd00::101
- (Optional) Lancez
kubeadm config images pull
avant de fairekubeadm init
pour vérifier la connectivité aux registres gcr.io.
Maintenant, lancez:
kubeadm init <args>
Plus d'information
Pour plus d'informations sur les arguments de kubeadm init
, voir le
guide de référence kubeadm.
Pour une liste complète des options de configuration, voir la documentation du fichier de configuration.
Pour personnaliser les composants du control plane, y compris l'affectation facultative d'IPv6 à la sonde liveness, pour les composants du control plane et du serveur etcd, fournissez des arguments supplémentaires à chaque composant, comme indiqué dans les arguments personnalisés.
Pour lancer encore une fois kubeadm init
, vous devez d'abord détruire le cluster.
Si vous joignez un nœud avec une architecture différente par rapport à votre cluster, créez un
Déploiement ou DaemonSet pour kube-proxy
et kube-dns
sur le nœud. C’est nécéssaire car les images Docker pour ces
composants ne prennent actuellement pas en charge la multi-architecture.
kubeadm init
exécute d’abord une série de vérifications préalables pour s’assurer que la machine
est prête à exécuter Kubernetes. Ces vérifications préalables exposent des avertissements et se terminent
en cas d'erreur. Ensuite kubeadm init
télécharge et installe les composants du control plane du cluster.
Cela peut prendre plusieurs minutes. l'output devrait ressembler à:
[init] Using Kubernetes version: vX.Y.Z
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Activating the kubelet service
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [kubeadm-master localhost] and IPs [10.138.0.4 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [kubeadm-master localhost] and IPs [10.138.0.4 127.0.0.1 ::1]
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [kubeadm-master kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 10.138.0.4]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[apiclient] All control plane components are healthy after 31.501735 seconds
[uploadconfig] storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-X.Y" in namespace kube-system with the configuration for the kubelets in the cluster
[patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "kubeadm-master" as an annotation
[mark-control-plane] Marking the node kubeadm-master as control-plane by adding the label "node-role.kubernetes.io/master=''"
[mark-control-plane] Marking the node kubeadm-master as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[bootstrap-token] Using token: <token>
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstraptoken] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstraptoken] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstraptoken] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstraptoken] creating the "cluster-info" ConfigMap in the "kube-public" namespace
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
Your Kubernetes master has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/fr/docs/concepts/cluster-administration/addons/
You can now join any number of machines by running the following on each node
as root:
kubeadm join <master-ip>:<master-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>
Pour que kubectl fonctionne pour votre utilisateur non root, exécutez ces commandes, qui font
également partie du resultat de la commande kubeadm init
:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternativement, si vous êtes root
, vous pouvez exécuter:
export KUBECONFIG=/etc/kubernetes/admin.conf
Faites un enregistrement du retour de la commande kubeadm join
que kubeadm init
génère. Vous avez
besoin de cette commande pour joindre des noeuds à votre cluster.
Le jeton est utilisé pour l'authentification mutuelle entre le master et les nœuds qui veulent le rejoindre.
Le jeton est secret. Gardez-le en sécurité, parce que n'importe qui avec ce
jeton peut ajouter des nœuds authentifiés à votre cluster. Ces jetons peuvent être listés,
créés et supprimés avec la commande kubeadm token
. Voir le
Guide de référence kubeadm.
Installation d'un add-on réseau
Vous devez installer un add-on réseau pour pod afin que vos pods puissent communiquer les uns avec les autres.
Le réseau doit être déployé avant toute application. De plus, CoreDNS ne démarrera pas avant l’installation d’un réseau. kubeadm ne prend en charge que les réseaux basés sur un CNI (et ne prend pas en charge kubenet).
Plusieurs projets fournissent des réseaux de pod Kubernetes utilisant CNI, dont certains supportent les network policies. Allez voir la page des add-ons pour une liste complète des add-ons réseau disponibles.
- Le support IPv6 a été ajouté dans CNI v0.6.0.
- CNI bridge et local-ipam sont les seuls plug-ins de réseau IPv6 pris en charge dans Kubernetes version 1.9.
Notez que kubeadm configure un cluster sécurisé par défaut et impose l’utilisation de RBAC. Assurez-vous que votre manifeste de réseau prend en charge RBAC.
Veuillez également à ce que votre réseau Pod ne se superpose à aucun des réseaux hôtes,
car cela pourrait entraîner des problèmes.
Si vous constatez une collision entre le réseau de pod de votre plug-in de réseau et certains
de vos réseaux hôtes,
vous devriez penser à un remplacement de CIDR approprié et l'utiliser lors de kubeadm init
avec
--pod-network-cidr
et en remplacement du YAML de votre plugin réseau.
Vous pouvez installer un add-on réseau de pod avec la commande suivante:
kubectl apply -f <add-on.yaml>
Vous ne pouvez installer qu'un seul réseau de pod par cluster.
Sélectionnez l'un des onglets pour consulter les instructions d'installation du fournisseur de réseau de pods.
Pour plus d'informations sur l'utilisation de Calico, voir Guide de démarrage rapide de Calico sur Kubernetes, Installation de Calico pour les netpols ( network policies ) et le réseau, ainsi que d'autres resources liées à ce sujet.
Pour que Calico fonctionne correctement, vous devez passer --pod-network-cidr = 192.168.0.0 / 16
à kubeadm init
ou mettre à jour le fichier calico.yml
pour qu'il corresponde à votre réseau de Pod.
Notez que Calico fonctionne uniquement sur amd64
, arm64
, ppc64le
et s390x
.
kubectl apply -f https://docs.projectcalico.org/v3.8/manifests/calico.yaml
Canal utilise Calico pour les netpols et Flannel pour la mise en réseau. Reportez-vous à la documentation Calico pour obtenir le guide de démarrage officiel.
Pour que Canal fonctionne correctement, --pod-network-cidr = 10.244.0.0 / 16
doit être passé à
kubeadm init
. Notez que Canal ne fonctionne que sur amd64
.
kubectl apply -f https://docs.projectcalico.org/v3.8/manifests/canal.yaml
Pour plus d'informations sur l'utilisation de Cilium avec Kubernetes, voir Guide d'installation de Kubernetes pour Cilium.
Ces commandes déploieront Cilium avec son propre etcd géré par l'opérateur etcd.
Note: Si vous utilisez kubeadm dans un seul noeud, veuillez enlever sa marque (taint) pour que les pods etcd-operator puissent être déployés dans le nœud du control plane.
kubectl taint nodes <node-name> node-role.kubernetes.io/master:NoSchedule-
Pour déployer Cilium, il vous suffit de lancer:
kubectl create -f https://raw.githubusercontent.com/cilium/cilium/v1.4/examples/kubernetes/1.13/cilium.yaml
Une fois que tous les pods Cilium sont marqués «READY», vous commencez à utiliser votre cluster.
$ kubectl get pods -n kube-system --selector=k8s-app=cilium
NAME READY STATUS RESTARTS AGE
cilium-drxkl 1/1 Running 0 18m
Pour que flannel
fonctionne correctement, vous devez passer --pod-network-cidr = 10.244.0.0 / 16
à kubeadm init
.
Paramétrez /proc/sys/net/bridge/bridge-nf-call-iptables
à «1» en exécutant
sysctl net.bridge.bridge-nf-call-iptables = 1
passez le trafic IPv4 bridged à iptables. Ceci est nécessaire pour que certains plugins CNI
fonctionnent, pour plus d'informations
allez voir ici.
Notez que flannel
fonctionne sur amd64
, arm
, arm64
, ppc64le
et s390x
sous Linux.
Windows (amd64
) est annoncé comme supporté dans la v0.11.0 mais son utilisation n’est pas
documentée.
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml
Pour plus d’informations sur flannel
, voir le dépôt CoreOS sur GitHub.
Paramétrez /proc/sys/net/bridge/bridge-nf-call-iptables
à «1» en exécutant
sysctl net.bridge.bridge-nf-call-iptables = 1
Cette commande indiquera de passer le trafic IPv4 bridgé à iptables.
Ceci est nécessaire pour que certains plugins CNI fonctionnent, pour plus d'informations
s'il vous plaît allez voir ici.
Kube-router s'appuie sur kube-controller-manager pour allouer le pod CIDR aux nœuds. Par conséquent,
utilisez kubeadm init
avec l'option --pod-network-cidr
.
Kube-router fournit un réseau de pod, une stratégie réseau et un proxy de service basé sur un IP Virtual Server (IPVS) / Linux Virtual Server (LVS) hautement performant.
Pour plus d'informations sur la configuration du cluster Kubernetes avec Kube-router à l'aide de kubeadm, veuillez consulter le guide d'installation.
Paramétrez /proc/sys/net/bridge/bridge-nf-call-iptables
à 1
en exécutant
sysctl net.bridge.bridge-nf-call-iptables = 1
Cette commande indiquera de passer le trafic IPv4 bridged à iptables. Ceci est nécessaire pour que certains plugins CNI fonctionnent,
pour plus d'informations
veuillez consulter la documentation ici.
Le guide d'installation officiel de Romana est ici.
Romana ne fonctionne que sur amd64
.
kubectl apply -f https://raw.githubusercontent.com/romana/romana/master/containerize/specs/romana-kubeadm.yml
Paramétrez /proc/sys/net/bridge/bridge-nf-call-iptables
à «1» en exécutant sysctl net.bridge.bridge-nf-call-iptables = 1
Cette commande indiquera de passer le trafic IPv4 bridged à iptables. Ceci est nécessaire pour que certains plugins CNI fonctionnent, pour plus d'informations
s'il vous plaît allez voir ici.
Le guide de configuration officiel de Weave Net est ici.
Weave Net fonctionne sur amd64
, arm
, arm64
et ppc64le
sans aucune action supplémentaire requise.
Weave Net paramètre le mode hairpin par défaut. Cela permet aux pods de se connecter via leur adresse IP de service
s'ils ne connaissent pas leur Pod IP.
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
Fournit une solution SDN superposée, offrant un réseau multicouches, un réseau de cloud hybride, prise en charge simultanée des couches superposées, application de la stratégie réseau, isolation du réseau, chaînage de service et équilibrage de charge flexible.
Il existe de nombreuses manières flexibles d’installer JuniperContrail / TungstenFabric CNI.
Veuillez vous référer à ce guide de démarrage rapide: TungstenFabric
Une fois qu'un réseau de pod a été installé, vous pouvez vérifier qu'il fonctionne en
vérifiant que le pod CoreDNS est en cours d’exécution dans l'output de kubectl get pods --all-namespaces
.
Et une fois que le pod CoreDNS est opérationnel, vous pouvez continuer en joignant vos nœuds.
Si votre réseau ne fonctionne pas ou si CoreDNS n'est pas en cours d'exécution, vérifiez notre documentation de dépannage.
Isolation des nœuds du control plane
Par défaut, votre cluster ne déploie pas de pods sur le master pour des raisons de sécurité. Si vous souhaitez pouvoir déployer des pods sur le master, par exemple, pour un cluster Kubernetes mono-machine pour le développement, exécutez:
kubectl taint nodes --all node-role.kubernetes.io/master-
Avec un resultat ressemblant à quelque chose comme:
node "test-01" untainted
taint "node-role.kubernetes.io/master:" not found
taint "node-role.kubernetes.io/master:" not found
Cela supprimera la marque node-role.kubernetes.io/master
de tous les nœuds qui
l'ont, y compris du nœud master, ce qui signifie que le scheduler sera alors capable
de déployer des pods partout.
Faire rejoindre vos nœuds
Les nœuds sont ceux sur lesquels vos workloads (conteneurs, pods, etc.) sont exécutées. Pour ajouter de nouveaux nœuds à votre cluster, procédez comme suit pour chaque machine:
- SSH vers la machine
- Devenir root (par exemple,
sudo su-
) - Exécutez la commande qui a été récupérée sur l'output de
kubeadm init
. Par exemple:
kubeadm join --token <token> <master-ip>:<master-port> --discovery-token-ca-cert-hash sha256:<hash>
Si vous n'avez pas le jeton, vous pouvez l'obtenir en exécutant la commande suivante sur le nœud master:
kubeadm token list
L'output est similaire à ceci:
TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS
8ewj1p.9r9hcjoqgajrj4gi 23h 2018-06-12T02:51:28Z authentication, The default bootstrap system:
signing token generated by bootstrappers:
'kubeadm init'. kubeadm:
default-node-token
Par défaut, les jetons expirent après 24 heures. Si vous joignez un nœud au cluster après l’expiration du jeton actuel, vous pouvez créer un nouveau jeton en exécutant la commande suivante sur le nœud maître:
kubeadm token create
L'output est similaire à ceci:
5didvk.d09sbcov8ph2amjw
Si vous n'avez pas la valeur --discovery-token-ca-cert-hash
, vous pouvez l'obtenir en
exécutant la suite de commande suivante sur le nœud master:
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^.* //'
L'output est similaire à ceci:
8cb2de97839780a412b93877f8507ad6c94f73add17d5d7058e91741c9d5ec78
<maître-ip>: <maître-port>
, l'adresse IPv6 doit être placée
entre crochets, par exemple: [fd00 :: 101]: 2073
.
Le resultat devrait ressembler à quelque chose comme:
[preflight] Running pre-flight checks
... (log output of join workflow) ...
Node join complete:
* Certificate signing request sent to master and response
received.
* Kubelet informed of new secure connection details.
Run 'kubectl get nodes' on the master to see this machine join.
Quelques secondes plus tard, vous remarquerez ce nœud dans l'output de kubectl get node
.
(Optionnel) Contrôler votre cluster à partir de machines autres que le master
Afin d'utiliser kubectl sur une autre machine (par exemple, un ordinateur portable) pour communiquer avec votre cluster, vous devez copier le fichier administrateur kubeconfig de votre master sur votre poste de travail comme ceci:
scp root@<master ip>:/etc/kubernetes/admin.conf .
kubectl --kubeconfig ./admin.conf get nodes
L'exemple ci-dessus suppose que l'accès SSH est activé pour root. Si ce n'est pas le cas,
vous pouvez copier le fichier admin.conf
pour qu'il soit accessible à un autre utilisateur.
et scp
en utilisant cet autre utilisateur à la place.
Le fichier admin.conf
donne à l'utilisateur superuser des privilèges sur le cluster.
Ce fichier doit être utilisé avec parcimonie. Pour les utilisateurs normaux, il est recommandé de
générer une information d'identification unique pour laquelle vous ajoutez des privilèges à la liste blanche
(whitelist).
Vous pouvez faire ceci avec kubeadm alpha kubeconfig utilisateur --nom-client <CN>
.
Le resultat de cette commande génèrera un fichier KubeConfig qui sera envoyé sur STDOUT, que vous
devrez enregistrer dans un fichier et donner à votre utilisateur. Après cela, créez la whitelist des
privilèges en utilisant kubectl create (cluster) rolebinding.
(Facultatif) Proxifier l'API Server vers localhost
Si vous souhaitez vous connecter à l'API server à partir de l'éxterieur du cluster, vous pouvez utiliser
kubectl proxy
:
scp root@<master ip>:/etc/kubernetes/admin.conf .
kubectl --kubeconfig ./admin.conf proxy
Vous pouvez maintenant accéder à l'API server localement à http://localhost:8001/api/v1
Destruction
Pour annuler ce que kubeadm a fait, vous devez d’abord drainer le nœud et assurez-vous que le nœud est vide avant de l'arrêter. En communiquant avec le master en utilisant les informations d'identification appropriées, exécutez:
kubectl drain <node name> --delete-local-data --force --ignore-daemonsets
kubectl delete node <node name>
Ensuite, sur le nœud en cours de suppression, réinitialisez l'état de tout ce qui concerne kubeadm:
kubeadm reset
Le processus de réinitialisation ne réinitialise pas et ne nettoie pas les règles iptables ni les tables IPVS. Si vous souhaitez réinitialiser iptables, vous devez le faire manuellement:
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
Si vous souhaitez réinitialiser les tables IPVS, vous devez exécuter la commande suivante:
ipvsadm -C
Si vous souhaitez recommencer Il suffit de lancer kubeadm init
ou kubeadm join
avec les
arguments appropriés.
Plus d'options et d'informations sur la
commande de réinitialisation de kubeadm
.
Maintenir un cluster
Vous trouverez des instructions pour la maintenance des clusters kubeadm (mises à niveau, rétrogradation, etc.) ici
Explorer les autres add-ons
Parcourez la liste des add-ons, y compris des outils pour la journalisation, la surveillance, la stratégie réseau, la visualisation et le contrôle de votre cluster Kubernetes.
Et après ?
- Vérifiez que votre cluster fonctionne correctement avec Sonobuoy
- En savoir plus sur l'utilisation avancée de kubeadm dans la documentation de référence de kubeadm
- En savoir plus sur Kubernetes concepts et
kubectl
. - Configurez la rotation des logs. Vous pouvez utiliser logrotate pour cela. Lorsque vous utilisez Docker,
vous pouvez spécifier des options de rotation des logs pour le démon Docker, par exemple
--log-driver = fichier_json --log-opt = taille_max = 10m --log-opt = fichier_max = 5
. Consultez Configurer et dépanner le démon Docker pour plus de détails.
Feedback
- Pour les bugs, visitez kubeadm GitHub issue tracker
- Pour le support, rendez vous sur le Channel Slack kubeadm: #kubeadm
- Le Channel Slack: General SIG Cluster Lifecycle Development: #sig-cluster-lifecycle
- SIG Cluster Lifecycle SIG information
- SIG Cluster Lifecycle Mailing List: kubernetes-sig-cluster-lifecycle
Politique de compatibilité de versions
L'outil CLI kubeadm de la version vX.Y peut déployer des clusters avec un control plane de la version vX.Y ou vX. (Y-1). kubeadm CLI vX.Y peut également mettre à niveau un cluster existant créé par kubeadm de la version vX. (Y-1).
Pour cette raison, nous ne pouvons pas voir plus loin, kubeadm CLI vX.Y peut ou pas être en mesure de déployer des clusters vX. (Y + 1).
Exemple: kubeadm v1.8 peut déployer des clusters v1.7 et v1.8 et mettre à niveau des clusters v1.7 créés par kubeadm vers v1.8.
Ces ressources fournissent plus d'informations sur le saut de version pris en charge entre les kubelets et le control plane, ainsi que sur d'autres composants Kubernetes:
- politique de compatibilité de versions de Kubernetes
- Guide d'installation spécifique à Kubeadm
kubeadm fonctionne sur plusieurs plates-formes
Les packages et fichiers binaires de kubeadm deb/rpm sont conçus pour amd64, arm (32 bits), arm64, ppc64le et s390x suite à la multiplateforme proposal.
Les images de conteneur multiplatform pour le control plane et les addons sont également pris en charge depuis la v1.12.
Seuls certains fournisseurs de réseau proposent des solutions pour toutes les plateformes. Veuillez consulter la liste des fournisseurs de réseau ci-dessus ou la documentation de chaque fournisseur pour déterminer si le fournisseur prend en charge votre plate-forme.
Limitations
Remarque: kubeadm évolue continuellement et ces limitations seront résolues en temps voulu.
- Le cluster créé ici a un seul master, avec une seule base de données etcd. Cela signifie que si le master est irrécupérable, votre cluster peut perdre ses données et peut avoir besoin d'être recréé à partir de zéro. L'ajout du support HA (plusieurs serveurs etcd, plusieurs API servers, etc.) à kubeadm est encore en cours de developpement.
Contournement: régulièrement sauvegarder etcd.
le répertoire des données etcd configuré par kubeadm se trouve dans /var/lib/etcd
sur le master.
Diagnostic
Si vous rencontrez des difficultés avec kubeadm, veuillez consulter nos troubleshooting docs.
2.3.1.1.3 - Personnalisation de la configuration du control plane avec kubeadm
Kubernetes 1.12 [stable]
L'objet ClusterConfiguration
de kubeadm expose le champ extraArgs
qui peut
remplacer les indicateurs par défaut transmis au control plane à des composants
tels que l'APIServer, le ControllerManager et le Scheduler. Les composants sont
définis à l'aide des champs suivants:
apiServer
controllerManager
scheduler
Le champ extraArgs
se compose de paires clé: valeur
. Pour remplacer un indicateur
pour un composant du control plane:
- Ajoutez les champs appropriés à votre configuration.
- Ajoutez les indicateurs à remplacer dans le champ.
Pour plus de détails sur chaque champ de la configuration, vous pouvez accéder aux pages de référence de l'API.
Paramètres pour l'API Server
Pour plus de détails, voir la documentation de référence pour kube-apiserver.
Exemple d'utilisation:
apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterConfiguration
kubernetesVersion: v1.13.0
metadata:
name: 1.13-sample
apiServer:
extraArgs:
advertise-address: 192.168.0.103
anonymous-auth: false
enable-admission-plugins: AlwaysPullImages,DefaultStorageClass
audit-log-path: /home/johndoe/audit.log
Paramètres pour le ControllerManager
Pour plus de détails, voir la documentation de référence pour kube-controller-manager.
Exemple d'utilisation:
apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterConfiguration
kubernetesVersion: v1.13.0
metadata:
name: 1.13-sample
controllerManager:
extraArgs:
cluster-signing-key-file: /home/johndoe/keys/ca.key
bind-address: 0.0.0.0
deployment-controller-sync-period: 50
Paramètres pour le Scheduler
Pour plus de détails, voir la documentation de référence pour kube-scheduler.
Example usage:
apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterConfiguration
kubernetesVersion: v1.13.0
metadata:
name: 1.13-sample
scheduler:
extraArgs:
bind-address: 0.0.0.0
config: /home/johndoe/schedconfig.yaml
kubeconfig: /home/johndoe/kubeconfig.yaml
2.3.1.1.4 - Options pour la topologie en haute disponibilité
Cette page explique les deux options de configuration de topologie de vos clusters Kubernetes pour la haute disponibilité.
Vous pouvez configurer un cluster en haute disponibilité:
- Avec des nœuds du control plane empilés, les nœuds etcd étant co-localisés avec des nœuds du control plane
- Avec des nœuds etcd externes, où etcd s'exécute sur des nœuds distincts du control plane
Vous devez examiner attentivement les avantages et les inconvénients de chaque topologie avant de configurer un cluster en haute disponibilité.
Topologie etcd empilée
Un cluster HA empilé est une topologie réseau où le cluster de stockage de données distribuées est fourni par etcd et est superposé au cluster formé par les noeuds gérés par kubeadm qui exécute les composants du control plane.
Chaque nœud du control plane exécute une instance de kube-apiserver
, kube-scheduler
et
kube-controller-manager
.
Le kube-apiserver
est exposé aux nœuds à l'aide d'un loadbalancer.
Chaque nœud du control plane crée un membre etcd local et ce membre etcd communique uniquement avec
le kube-apiserver
de ce noeud. Il en va de même pour le kube-controller-manager
local
et les instances de kube-scheduler
.
Cette topologie couple les control planes et les membres etcd sur les mêmes nœuds. C'est plus simple à mettre en place qu'un cluster avec des nœuds etcd externes et plus simple à gérer pour la réplication.
Cependant, un cluster empilé présente un risque d'échec du couplage. Si un noeud tombe en panne, un membre etcd et une instance du control plane sont perdus et la redondance est compromise. Vous pouvez atténuer ce risque en ajoutant plus de nœuds au control plane.
Par conséquent, vous devez exécuter au moins trois nœuds de control plane empilés pour un cluster en haute disponibilité.
C'est la topologie par défaut dans kubeadm. Un membre etcd local est créé automatiquement
sur les noeuds du control plane en utilisant kubeadm init
et kubeadm join --experimental-control-plane
.
Schéma de la Topologie etcd empilée
Topologie etcd externe
Un cluster haute disponibilité avec un etcd externe est une topologie réseau où le cluster de stockage de données distribuées fourni par etcd est externe au cluster formé par les nœuds qui exécutent les composants du control plane.
Comme la topologie etcd empilée, chaque nœud du control plane d'une topologie etcd externe exécute
une instance de kube-apiserver
, kube-scheduler
et kube-controller-manager
. Et le kube-apiserver
est exposé aux nœuds workers à l’aide d’un load-balancer. Cependant, les membres etcd s'exécutent sur
des hôtes distincts et chaque hôte etcd communique avec le kube-apiserver
de chaque nœud du control plane.
Cette topologie dissocie le control plane et le membre etcd. Elle fournit donc une configuration HA où perdre une instance de control plane ou un membre etcd a moins d'impact et n'affecte pas la redondance du cluster autant que la topologie HA empilée.
Cependant, cette topologie requiert le double du nombre d'hôtes de la topologie HA integrée. Un minimum de trois machines pour les nœuds du control plane et de trois machines pour les nœuds etcd est requis pour un cluster HA avec cette topologie.
Schéma de la Topologie externe etcd
A suivre
2.3.1.1.5 - Création de clusters hautement disponibles avec kubeadm
Cette page explique deux approches différentes pour configurer un Kubernetes à haute disponibilité. cluster utilisant kubeadm:
- Avec des nœuds de control plane empilés. Cette approche nécessite moins d'infrastructure. Les membres etcd et les nœuds du control plane sont co-localisés.
- Avec un cluster etcd externe cette approche nécessite plus d'infrastructure. Les nœuds du control plane et les membres etcd sont séparés.
Avant de poursuivre, vous devez déterminer avec soin quelle approche répond le mieux aux besoins de vos applications et de l'environnement. Cette comparaison décrit les avantages et les inconvénients de chacune.
Vos clusters doivent exécuter Kubernetes version 1.12 ou ultérieure. Vous devriez aussi savoir que la mise en place de clusters HA avec kubeadm est toujours expérimentale et sera simplifiée davantage dans les futures versions. Vous pouvez par exemple rencontrer des problèmes lors de la mise à niveau de vos clusters. Nous vous encourageons à essayer l’une ou l’autre approche et à nous faire part de vos commentaires dans Suivi des problèmes Kubeadm.
Notez que la fonctionnalité alpha HighAvailability
est obsolète dans la version 1.12 et supprimée dans la version 1.13
Voir aussi La documentation de mise à niveau HA.
Pré-requis
Pour les deux méthodes, vous avez besoin de cette infrastructure:
- Trois machines qui répondent aux pré-requis des exigences de kubeadm pour les maîtres (masters)
- Trois machines qui répondent aux pré-requis des exigences de kubeadm pour les workers
- Connectivité réseau complète entre toutes les machines du cluster (public ou réseau privé)
- Privilèges sudo sur toutes les machines
- Accès SSH d'une machine à tous les nœuds du cluster
kubeadm
et unekubelet
installés sur toutes les machines.kubectl
est optionnel.
Pour le cluster etcd externe uniquement, vous avez besoin également de:
- Trois machines supplémentaires pour les membres etcd
Premières étapes pour les deux méthodes
- Certains plugins réseau CNI tels que Calico nécessitent un CIDR tel que
192.168.0.0 / 16
et certains comme Weave n'en ont pas besoin. Voir la Documentation du CNI réseau. Pour ajouter un CIDR de pod, définissez le champpodSubnet: 192.168.0.0 / 16
sous l'objetnetworking
deClusterConfiguration
.
Créez un load balancer pour kube-apiserver
-
Créez un load balancer kube-apiserver avec un nom résolu en DNS.
-
Dans un environnement cloud, placez vos nœuds du control plane derrière un load balancer TCP. Ce load balancer distribue le trafic à tous les nœuds du control plane sains dans sa liste. La vérification de la bonne santé d'un apiserver est une vérification TCP sur le port que kube-apiserver écoute (valeur par défaut:
6443
). -
Il n'est pas recommandé d'utiliser une adresse IP directement dans un environnement cloud.
-
Le load balancer doit pouvoir communiquer avec tous les nœuds du control plane sur le port apiserver. Il doit également autoriser le trafic entrant sur son réseau de port d'écoute.
-
HAProxy peut être utilisé comme load balancer.
-
Assurez-vous que l'adresse du load balancer correspond toujours à l'adresse de
ControlPlaneEndpoint
de kubeadm.
-
-
Ajoutez les premiers nœuds du control plane au load balancer et testez la connexion:
nc -v LOAD_BALANCER_IP PORT
- Une erreur
connection refused
est attendue car l'apiserver n'est pas encore en fonctionnement. Cependant, un timeout signifie que le load balancer ne peut pas communiquer avec le nœud du control plane. Si un timeout survient, reconfigurez le load balancer pour communiquer avec le nœud du control plane.
- Une erreur
-
Ajouter les nœuds du control plane restants au groupe cible du load balancer.
Configurer SSH
SSH est requis si vous souhaitez contrôler tous les nœuds à partir d'une seule machine.
-
Activer ssh-agent sur votre machine ayant accès à tous les autres nœuds du cluster:
eval $(ssh-agent)
-
Ajoutez votre clé SSH à la session:
ssh-add ~/.ssh/path_to_private_key
-
SSH entre les nœuds pour vérifier que la connexion fonctionne correctement.
-
Lorsque vous faites un SSH sur un noeud, assurez-vous d’ajouter l’option
-A
:ssh -A 10.0.0.7
-
Lorsque vous utilisez sudo sur n’importe quel nœud, veillez à préserver l’environnement afin que le SSH forwarding fonctionne:
sudo -E -s
-
Control plane empilé et nœuds etcd
Étapes pour le premier nœud du control plane
-
Sur le premier nœud du control plane, créez un fichier de configuration appelé
kubeadm-config.yaml
:apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration kubernetesVersion: stable apiServer: certSANs: - "LOAD_BALANCER_DNS" controlPlaneEndpoint: "LOAD_BALANCER_DNS:LOAD_BALANCER_PORT"
kubernetesVersion
doit représenter la version de Kubernetes à utiliser. Cet exemple utilisestable
.controlPlaneEndpoint
doit correspondre à l'adresse ou au DNS et au port du load balancer.- Il est recommandé que les versions de kubeadm, kubelet, kubectl et kubernetes correspondent.
-
Assurez-vous que le nœud est dans un état sain:
sudo kubeadm init --config=kubeadm-config.yaml
Vous devriez voir quelque chose comme:
...
Vous pouvez à présent joindre n'importe quelle machine au cluster en lancant la commande suivante sur chaque nœeud en tant que root:
kubeadm join 192.168.0.200:6443 --token j04n3m.octy8zely83cy2ts --discovery-token-ca-cert-hash sha256:84938d2a22203a8e56a787ec0c6ddad7bc7dbd52ebabc62fd5f4dbea72b14d1f
```
-
Copiez ce jeton dans un fichier texte. Vous en aurez besoin plus tard pour joindre d’autres nœuds du control plane au cluster.
-
Activez l'extension CNI Weave:
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
-
Tapez ce qui suit et observez les pods des composants démarrer:
kubectl get pod -n kube-system -w
- Il est recommandé de ne joindre les nouveaux nœuds du control plane qu'après l'initialisation du premier nœud.
-
Copiez les fichiers de certificat du premier nœud du control plane dans les autres:
Dans l'exemple suivant, remplacez
CONTROL_PLANE_IPS
par les adresses IP des autres nœuds du control plane.USER=ubuntu # customizable CONTROL_PLANE_IPS="10.0.0.7 10.0.0.8" for host in ${CONTROL_PLANE_IPS}; do scp /etc/kubernetes/pki/ca.crt "${USER}"@$host: scp /etc/kubernetes/pki/ca.key "${USER}"@$host: scp /etc/kubernetes/pki/sa.key "${USER}"@$host: scp /etc/kubernetes/pki/sa.pub "${USER}"@$host: scp /etc/kubernetes/pki/front-proxy-ca.crt "${USER}"@$host: scp /etc/kubernetes/pki/front-proxy-ca.key "${USER}"@$host: scp /etc/kubernetes/pki/etcd/ca.crt "${USER}"@$host:etcd-ca.crt scp /etc/kubernetes/pki/etcd/ca.key "${USER}"@$host:etcd-ca.key scp /etc/kubernetes/admin.conf "${USER}"@$host: done
Étapes pour le reste des nœuds du control plane
-
Déplacer les fichiers créés à l'étape précédente où
scp
était utilisé:USER=ubuntu # customizable mkdir -p /etc/kubernetes/pki/etcd mv /home/${USER}/ca.crt /etc/kubernetes/pki/ mv /home/${USER}/ca.key /etc/kubernetes/pki/ mv /home/${USER}/sa.pub /etc/kubernetes/pki/ mv /home/${USER}/sa.key /etc/kubernetes/pki/ mv /home/${USER}/front-proxy-ca.crt /etc/kubernetes/pki/ mv /home/${USER}/front-proxy-ca.key /etc/kubernetes/pki/ mv /home/${USER}/etcd-ca.crt /etc/kubernetes/pki/etcd/ca.crt mv /home/${USER}/etcd-ca.key /etc/kubernetes/pki/etcd/ca.key mv /home/${USER}/admin.conf /etc/kubernetes/admin.conf
Ce processus écrit tous les fichiers demandés dans le dossier
/etc/kubernetes
. -
Lancez
kubeadm join
sur ce nœud en utilisant la commande de join qui vous avait été précédemment donnée parkubeadm init
sur le premier noeud. Ça devrait ressembler a quelque chose comme ça:sudo kubeadm join 192.168.0.200:6443 --token j04n3m.octy8zely83cy2ts --discovery-token-ca-cert-hash sha256:84938d2a22203a8e56a787ec0c6ddad7bc7dbd52ebabc62fd5f4dbea72b14d1f --experimental-control-plane
- Remarquez l'ajout de l'option
--experimental-control-plane
. Ce paramètre automatise l'adhésion au control plane du cluster.
- Remarquez l'ajout de l'option
-
Tapez ce qui suit et observez les pods des composants démarrer:
kubectl get pod -n kube-system -w
-
Répétez ces étapes pour le reste des nœuds du control plane.
Noeuds etcd externes
Configurer le cluster etcd
- Suivez ces instructions pour configurer le cluster etcd.
Configurer le premier nœud du control plane
-
Copiez les fichiers suivants de n’importe quel nœud du cluster etcd vers ce nœud.:
export CONTROL_PLANE="[email protected]" +scp /etc/kubernetes/pki/etcd/ca.crt "${CONTROL_PLANE}": +scp /etc/kubernetes/pki/apiserver-etcd-client.crt "${CONTROL_PLANE}": +scp /etc/kubernetes/pki/apiserver-etcd-client.key "${CONTROL_PLANE}":
- Remplacez la valeur de
CONTROL_PLANE
par l'utilisateur@hostname
de cette machine.
- Remplacez la valeur de
-
Créez un fichier YAML appelé
kubeadm-config.yaml
avec le contenu suivant:apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration kubernetesVersion: stable apiServer: certSANs: - "LOAD_BALANCER_DNS" controlPlaneEndpoint: "LOAD_BALANCER_DNS:LOAD_BALANCER_PORT" etcd: external: endpoints: - https://ETCD_0_IP:2379 - https://ETCD_1_IP:2379 - https://ETCD_2_IP:2379 caFile: /etc/kubernetes/pki/etcd/ca.crt certFile: /etc/kubernetes/pki/apiserver-etcd-client.crt keyFile: /etc/kubernetes/pki/apiserver-etcd-client.key
-
La différence entre etcd empilé et externe, c’est que nous utilisons le champ
external
pouretcd
dans la configuration de kubeadm. Dans le cas de la topologie etcd empilée, c'est géré automatiquement. -
Remplacez les variables suivantes dans le modèle (template) par les valeurs appropriées pour votre cluster:
LOAD_BALANCER_DNS
LOAD_BALANCER_PORT
ETCD_0_IP
ETCD_1_IP
ETCD_2_IP
-
-
Lancez
kubeadm init --config kubeadm-config.yaml
sur ce nœud. -
Ecrivez le résultat de la commande de join dans un fichier texte pour une utilisation ultérieure.
-
Appliquer le plugin CNI Weave:
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
Étapes pour le reste des nœuds du control plane
Pour ajouter le reste des nœuds du control plane, suivez ces instructions. Les étapes sont les mêmes que pour la configuration etcd empilée, à l’exception du fait qu'un membre etcd local n'est pas créé.
Pour résumer:
- Assurez-vous que le premier nœud du control plane soit complètement initialisé.
- Copier les certificats entre le premier nœud du control plane et les autres nœuds du control plane.
- Joignez chaque nœud du control plane à l'aide de la commande de join que vous avez enregistrée dans
un fichier texte, puis ajoutez l'option
--experimental-control-plane
.
Tâches courantes après l'amorçage du control plane
Installer un réseau de pod
Suivez ces instructions afin d'installer le réseau de pod. Assurez-vous que cela correspond au pod CIDR que vous avez fourni dans le fichier de configuration principal.
Installer les workers
Chaque nœud worker peut maintenant être joint au cluster avec la commande renvoyée à partir du resultat
de n’importe quelle commande kubeadm init
. L'option --experimental-control-plane
ne doit pas
être ajouté aux nœuds workers.
2.3.1.1.6 - Configurer un cluster etcd en haute disponibilité avec kubeadm
Par défaut, Kubeadm exécute un cluster etcd mono nœud dans un pod statique géré par la kubelet sur le nœud du plan de contrôle (control plane). Ce n'est pas une configuration haute disponibilité puisque le cluster etcd ne contient qu'un seul membre et ne peut donc supporter qu'aucun membre ne devienne indisponible. Cette page vous accompagne dans le processus de création d'un cluster etcd à trois membres en haute disponibilité, pouvant être utilisé en tant que cluster externe lors de l’utilisation de kubeadm pour configurer un cluster kubernetes.
Pré-requis
- Trois machines pouvant communiquer entre elles via les ports 2379 et 2380. Cette methode utilise ces ports par défaut. Cependant, ils sont configurables via le fichier de configuration kubeadm.
- Chaque hôte doit avoir docker, kubelet et kubeadm installés.
- Certains paquets pour copier des fichiers entre les hôtes. Par exemple,
ssh
etscp
.
Mise en place du cluster
L’approche générale consiste à générer tous les certificats sur un nœud et à ne distribuer que les fichiers nécessaires aux autres nœuds.
-
Configurez la kubelet pour qu'elle soit un gestionnaire de service pour etcd.
Etant donné qu'etcd a été créé en premier, vous devez remplacer la priorité de service en créant un nouveau fichier unit qui a une priorité plus élevée que le fichier unit de la kubelet fourni par kubeadm.
cat << EOF > /etc/systemd/system/kubelet.service.d/20-etcd-service-manager.conf [Service] ExecStart= ExecStart=/usr/bin/kubelet --address=127.0.0.1 --pod-manifest-path=/etc/kubernetes/manifests Restart=always EOF systemctl daemon-reload systemctl restart kubelet
-
Créez des fichiers de configuration pour kubeadm.
Générez un fichier de configuration kubeadm pour chaque machine qui éxécutera un membre etcd en utilisant le script suivant.
# Update HOST0, HOST1, and HOST2 with the IPs or resolvable names of your hosts export HOST0=10.0.0.6 export HOST1=10.0.0.7 export HOST2=10.0.0.8 # Create temp directories to store files that will end up on other hosts. mkdir -p /tmp/${HOST0}/ /tmp/${HOST1}/ /tmp/${HOST2}/ ETCDHOSTS=(${HOST0} ${HOST1} ${HOST2}) NAMES=("infra0" "infra1" "infra2") for i in "${!ETCDHOSTS[@]}"; do HOST=${ETCDHOSTS[$i]} NAME=${NAMES[$i]} cat << EOF > /tmp/${HOST}/kubeadmcfg.yaml apiVersion: "kubeadm.k8s.io/v1beta1" kind: ClusterConfiguration etcd: local: serverCertSANs: - "${HOST}" peerCertSANs: - "${HOST}" extraArgs: initial-cluster: ${NAMES[0]}=https://${ETCDHOSTS[0]}:2380,${NAMES[1]}=https://${ETCDHOSTS[1]}:2380,${NAMES[2]}=https://${ETCDHOSTS[2]}:2380 initial-cluster-state: new name: ${NAME} listen-peer-urls: https://${HOST}:2380 listen-client-urls: https://${HOST}:2379 advertise-client-urls: https://${HOST}:2379 initial-advertise-peer-urls: https://${HOST}:2380 EOF done
-
Générer l'autorité de certification
Si vous avez déjà une autorité de certification, alors la seule action qui est faite copie les fichiers
crt
etkey
de la CA dans/etc/kubernetes/pki/etcd/ca.crt
et/etc/kubernetes/pki/etcd/ca.key
. Une fois ces fichiers copiés, passez à l'étape suivante, "Créer des certificats pour chaque membre".Si vous ne possédez pas déjà de CA, exécutez cette commande sur
$HOST0
(où vous avez généré les fichiers de configuration pour kubeadm).kubeadm init phase certs etcd-ca
Cela crée deux fichiers
/etc/kubernetes/pki/etcd/ca.crt
/etc/kubernetes/pki/etcd/ca.key
-
Créer des certificats pour chaque membre
kubeadm init phase certs etcd-server --config=/tmp/${HOST2}/kubeadmcfg.yaml kubeadm init phase certs etcd-peer --config=/tmp/${HOST2}/kubeadmcfg.yaml kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST2}/kubeadmcfg.yaml kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST2}/kubeadmcfg.yaml cp -R /etc/kubernetes/pki /tmp/${HOST2}/ # cleanup non-reusable certificates find /etc/kubernetes/pki -not -name ca.crt -not -name ca.key -type f -delete kubeadm init phase certs etcd-server --config=/tmp/${HOST1}/kubeadmcfg.yaml kubeadm init phase certs etcd-peer --config=/tmp/${HOST1}/kubeadmcfg.yaml kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST1}/kubeadmcfg.yaml kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST1}/kubeadmcfg.yaml cp -R /etc/kubernetes/pki /tmp/${HOST1}/ find /etc/kubernetes/pki -not -name ca.crt -not -name ca.key -type f -delete kubeadm init phase certs etcd-server --config=/tmp/${HOST0}/kubeadmcfg.yaml kubeadm init phase certs etcd-peer --config=/tmp/${HOST0}/kubeadmcfg.yaml kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST0}/kubeadmcfg.yaml kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST0}/kubeadmcfg.yaml # No need to move the certs because they are for HOST0 # clean up certs that should not be copied off this host find /tmp/${HOST2} -name ca.key -type f -delete find /tmp/${HOST1} -name ca.key -type f -delete
-
Copier les certificats et les configurations kubeadm
Les certificats ont été générés et doivent maintenant être déplacés vers leur hôtes respectifs.
USER=ubuntu HOST=${HOST1} scp -r /tmp/${HOST}/* ${USER}@${HOST}: ssh ${USER}@${HOST} USER@HOST $ sudo -Es root@HOST $ chown -R root:root pki root@HOST $ mv pki /etc/kubernetes/
-
S'assurer que tous les fichiers attendus existent
La liste complète des fichiers requis sur
$HOST0
est la suivante:/tmp/${HOST0} └── kubeadmcfg.yaml --- /etc/kubernetes/pki ├── apiserver-etcd-client.crt ├── apiserver-etcd-client.key └── etcd ├── ca.crt ├── ca.key ├── healthcheck-client.crt ├── healthcheck-client.key ├── peer.crt ├── peer.key ├── server.crt └── server.key
Sur
$HOST1
:$HOME └── kubeadmcfg.yaml --- /etc/kubernetes/pki ├── apiserver-etcd-client.crt ├── apiserver-etcd-client.key └── etcd ├── ca.crt ├── healthcheck-client.crt ├── healthcheck-client.key ├── peer.crt ├── peer.key ├── server.crt └── server.key
Sur
$HOST2
:$HOME └── kubeadmcfg.yaml --- /etc/kubernetes/pki ├── apiserver-etcd-client.crt ├── apiserver-etcd-client.key └── etcd ├── ca.crt ├── healthcheck-client.crt ├── healthcheck-client.key ├── peer.crt ├── peer.key ├── server.crt └── server.key
-
Créer les manifestes de pod statiques
Maintenant que les certificats et les configurations sont en place, il est temps de créer les manifestes. Sur chaque hôte, exécutez la commande
kubeadm
pour générer un manifeste statique pour etcd.root@HOST0 $ kubeadm init phase etcd local --config=/tmp/${HOST0}/kubeadmcfg.yaml root@HOST1 $ kubeadm init phase etcd local --config=/tmp/${HOST1}/kubeadmcfg.yaml root@HOST2 $ kubeadm init phase etcd local --config=/tmp/${HOST2}/kubeadmcfg.yaml
-
Facultatif: Vérifiez la santé du cluster
docker run --rm -it \ --net host \ -v /etc/kubernetes:/etc/kubernetes quay.io/coreos/etcd:${ETCD_TAG} etcdctl \ --cert-file /etc/kubernetes/pki/etcd/peer.crt \ --key-file /etc/kubernetes/pki/etcd/peer.key \ --ca-file /etc/kubernetes/pki/etcd/ca.crt \ --endpoints https://${HOST0}:2379 cluster-health ... cluster is healthy
- Configurez
${ETCD_TAG}
avec la version de votre image etcd. Par exemplev3.2.24
. - Configurez
${HOST0}
avec l'adresse IP de l'hôte que vous testez.
- Configurez
A suivre
Une fois que vous avez un cluster de 3 membres etcd qui fonctionne, vous pouvez continuer à configurer un control plane hautement disponible utilisant la méthode etcd externe avec kubeadm.
2.3.1.1.7 - Configuration des kubelet de votre cluster avec kubeadm
Kubernetes 1.11 [stable]
Le cycle de vie de l’outil CLI kubeadm est découplé de celui de la kubelet, qui est un démon qui s'éxécute sur chaque noeud du cluster Kubernetes. L'outil CLI de kubeadm est exécuté par l'utilisateur lorsque Kubernetes est initialisé ou mis à niveau, alors que la kubelet est toujours exécutée en arrière-plan.
Comme la kubelet est un démon, elle doit être maintenue par une sorte d'init système ou un gestionnaire de service. Lorsque la kubelet est installée à l'aide de DEB ou de RPM, systemd est configuré pour gérer la kubelet. Vous pouvez utiliser un gestionnaire différent à la place, mais vous devez le configurer manuellement.
Certains détails de configuration de la kubelet doivent être identiques pour
toutes les kubelets du cluster, tandis que d’autres aspects de la configuration
doivent être définis par nœud, pour tenir compte des différentes caractéristiques
d’une machine donnée, telles que le système d’exploitation, le stockage et la
mise en réseau. Vous pouvez gérer la configuration manuellement de vos kubelets,
mais kubeadm fournit maintenant un type d’API KubeletConfiguration
pour la gestion centralisée de vos configurations de kubelets.
Patterns de configuration des Kubelets
Les sections suivantes décrivent les modèles de configuration de kubelet simplifiés en utilisant kubeadm, plutôt que de gérer manuellement la configuration des kubelets pour chaque nœud.
Propagation de la configuration niveau cluster à chaque kubelet
Vous pouvez fournir à la kubelet les valeurs par défaut à utiliser par les commandes kubeadm init
et
kubeadm join
. Des exemples intéressants incluent l’utilisation d’un runtime CRI différent ou la
définition du sous-réseau par défaut utilisé par les services.
Si vous souhaitez que vos services utilisent le sous-réseau 10.96.0.0 / 12
par défaut pour les
services, vous pouvez passer le paramètre --service-cidr
à kubeadm:
kubeadm init --service-cidr 10.96.0.0/12
Les adresses IP virtuelles pour les services sont maintenant attribuées à partir de ce sous-réseau.
Vous devez également définir l'adresse DNS utilisée par la kubelet, en utilisant l'option
--cluster-dns
. Ce paramètre doit être le même pour chaque kubelet sur chaque master et worker
du cluster. La kubelet fournit un objet API structuré versionné qui peut configurer la plupart des
paramètres dans la kubelet et pousser cette configuration à chaque exécution de la kubelet dans
le cluster. Cet objet s'appelle la ComponentConfig de la kubelet.
La ComponentConfig permet à l’utilisateur de spécifier des options tels que les adresses IP DNS du
cluster exprimées en une liste de valeurs pour une clé formatée en CamelCased, illustrée par l'exemple suivant:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
clusterDNS:
- 10.96.0.10
Pour plus de détails sur ComponentConfig, jetez un œil à cette section.
Fournir des détails de configuration spécifiques à l'instance
Certaines machines nécessitent des configurations de kubelet spécifiques, en raison de la différences de matériel, de système d’exploitation, réseau ou d’autres paramètres spécifiques à l’hôte. La liste suivante fournit quelques exemples.
-
Le chemin d'accès au fichier de résolution DNS, tel que spécifié par l'option de configuration de la kubelet
--resolv-conf
, peut différer selon les systèmes d'exploitation ou selon que vous utilisez ou nonsystemd-resolved
. Si ce chemin est incorrect, la résolution DNS échouera sur le nœud dont la kubelet est configuré de manière incorrecte. -
L'objet API de nœud
.metadata.name
est défini par défaut sur le hostname de la machine, sauf si vous utilisez un fournisseur de cloud. Vous pouvez utiliser l’indicateur--hostname-override
pour remplacer le comportement par défaut si vous devez spécifier un nom de nœud différent du hostname de la machine. -
Actuellement, la kubelet ne peut pas détecter automatiquement le driver cgroup utilisé par le runtime CRI, mais la valeur de
--cgroup-driver
doit correspondre au driver cgroup utilisé par le runtime CRI pour garantir la santé de la kubelet. -
En fonction du runtime du CRI utilisé par votre cluster, vous devrez peut-être spécifier des options différentes pour la kubelet. Par exemple, lorsque vous utilisez Docker, vous devez spécifier des options telles que
--network-plugin = cni
, mais si vous utilisez un environnement d’exécution externe, vous devez spécifier--container-runtime = remote
et spécifier le CRI endpoint en utilisant l'option--container-runtime-path-endpoint = <chemin>
.
Vous pouvez spécifier ces options en modifiant la configuration d’une kubelet individuelle dans votre gestionnaire de service, tel que systemd.
Configurer les kubelets en utilisant kubeadm
Il est possible de configurer la kubelet que kubeadm va démarrer si un objet API personnalisé
KubeletConfiguration
est passé en paramètre via un fichier de configuration comme
kubeadm ... --config some-config-file.yaml
.
En appelant kubeadm config print-default --api-objects KubeletConfiguration
vous
pouvez voir toutes les valeurs par défaut pour cette structure.
Regardez aussi la référence API pour le composant ComponentConfig des kubelets pour plus d'informations sur les champs individuels.
Workflow lors de l'utilisation de kubeadm init
Lorsque vous appelez kubeadm init
, la configuration de la kubelet est organisée sur le disque
sur /var/lib/kubelet/config.yaml
, et également chargé sur une ConfigMap du cluster. La ConfigMap
est nommé kubelet-config-1.X
, où .X
est la version mineure de la version de Kubernetes
que vous êtes en train d'initialiser. Un fichier de configuration de kubelet est également écrit dans
/etc/kubernetes/kubelet.conf
avec la configuration de base à l'échelle du cluster pour tous les
kubelets du cluster. Ce fichier de configuration pointe vers les certificats clients permettant aux
kubelets de communiquer avec l'API server. Ceci répond au besoin de
propager la configuration niveau cluster à chaque kubelet.
Pour répondre au besoin de
fournir des détails de configuration spécifiques à l'instance de kubelet,
kubeadm écrit un fichier d'environnement dans /var/lib/kubelet/kubeadm-flags.env
, qui contient une liste
d'options à passer à la kubelet quand elle démarre. Les options sont représentées dans le fichier comme ceci:
KUBELET_KUBEADM_ARGS="--flag1=value1 --flag2=value2 ..."
Outre les indicateurs utilisés lors du démarrage de la kubelet, le fichier contient également des
informations dynamiques comme des paramètres tels que le driver cgroup et s'il faut utiliser un autre
socket de runtime CRI (--cri-socket
).
Après avoir rassemblé ces deux fichiers sur le disque, kubeadm tente d’exécuter ces deux commandes, si vous utilisez systemd:
systemctl daemon-reload && systemctl restart kubelet
Si le rechargement et le redémarrage réussissent, le workflow normal de kubeadm init
continue.
Workflow en utilisant kubeadm join
Lorsque vous exécutez kubeadm join
, kubeadm utilise les informations d'identification du bootstrap
token pour faire un bootstrap TLS, qui récupère les informations d’identité nécessaires pour télécharger le
kubelet-config-1.X
ConfigMap puis l'écrit dans /var/lib/kubelet/config.yaml
. Le fichier d’environnement
dynamique est généré exactement de la même manière que kubeadm init
.
Ensuite, kubeadm
exécute les deux commandes suivantes pour charger la nouvelle configuration dans la kubelet:
systemctl daemon-reload && systemctl restart kubelet
Après le chargement de la nouvelle configuration par la kubelet, kubeadm écrit le fichier KubeConfig
/etc/kubernetes/bootstrap-kubelet.conf
, qui contient un certificat de CA et un jeton Bootstrap.
Ceux-ci sont utilisés par la kubelet pour effectuer le TLS Bootstrap et obtenir une information
d'identification unique, qui est stocké dans /etc/kubernetes/kubelet.conf
. Quand ce fichier est
écrit, la kubelet a terminé l'exécution du bootstrap TLS.
Le fichier kubelet généré pour systemd
Le fichier de configuration installé par le package DEB ou RPM de kubeadm est écrit dans
/etc/systemd/system/kubelet.service.d/10-kubeadm.conf
et est utilisé par systemd.
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf
--kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating
the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably,
# the user should use the .NodeRegistration.KubeletExtraArgs object in the configuration files instead.
# KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/default/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS
Ce fichier spécifie les emplacements par défaut pour tous les fichiers gérés par kubeadm pour la kubelet.
- Le fichier KubeConfig à utiliser pour le TLS Bootstrap est
/etc/kubernetes/bootstrap-kubelet.conf
, mais il n'est utilisé que si/etc/kubernetes/kubelet.conf
n'existe pas. - Le fichier KubeConfig avec l’identité unique de la kubelet est
/etc/kubernetes/kubelet.conf
. - Le fichier contenant le ComponentConfig de la kubelet est
/var/lib/kubelet/config.yaml
. - Le fichier d'environnement dynamique qui contient
KUBELET_KUBEADM_ARGS
est sourcé à partir de/var/lib/kubelet/kubeadm-flags.env
. - Le fichier qui peut contenir les paramètres surchargés par l'utilisateur avec
KUBELET_EXTRA_ARGS
provient de/etc/default/kubelet
(pour les DEBs), ou/etc/sysconfig/kubelet
(pour les RPMs)KUBELET_EXTRA_ARGS
est le dernier de la chaîne d'options et a la priorité la plus élevée en cas de conflit de paramètres.
Fichiers binaires de Kubernetes et contenu du package
Les packages DEB et RPM fournis avec les versions de Kubernetes sont les suivants:
Nom du paquet | Description |
---|---|
kubeadm |
Installe l'outil CLI /usr/bin/kubeadm et le fichier instantané de kubelet pour la kubelet. |
kubelet |
Installe /usr/bin/kubelet . |
kubectl |
Installe /usr/bin/kubectl . |
kubernetes-cni |
Installe les binaires officiels du CNI dans le repertoire /opt/cni/bin . |
cri-tools |
Installe /usr/bin/crictl à partir de https://github.com/kubernetes-incubator/cri-tools. |
2.3.1.1.8 - Dépanner kubeadm
Comme avec n'importe quel programme, vous pourriez rencontrer une erreur lors de l'installation ou de l'exécution de kubeadm. Cette page répertorie certains scénarios d’échec courants et propose des étapes pouvant vous aider à comprendre et résoudre le problème.
Si votre problème ne figure pas dans la liste ci-dessous, procédez comme suit:
-
Si vous pensez que votre problème est un bug avec kubeadm:
- Aller à github.com/kubernetes/kubeadm et rechercher les problèmes existants.
- Si aucune issue n'existe, veuillez en ouvrir une et suivez le modèle ( template ) d'issue
-
Si vous ne savez pas comment fonctionne kubeadm, vous pouvez demander sur Slack dans le canal #kubeadm, ou posez une questions sur StackOverflow. Merci d'ajouter les tags pertinents comme
#kubernetes
et#kubeadm
, ainsi on pourra vous aider.
ebtables
ou un exécutable similaire introuvable lors de l'installation
Si vous voyez les warnings suivants lors de l'exécution kubeadm init
[preflight] WARNING: ebtables not found in system path
[preflight] WARNING: ethtool not found in system path
Ensuite, il peut vous manquer ebtables
, ethtool
ou un exécutable similaire sur votre nœud. Vous
pouvez l'installer avec les commandes suivantes:
- For Ubuntu/Debian users, run
apt install ebtables ethtool
. - For CentOS/Fedora users, run
yum install ebtables ethtool
.
kubeadm reste bloqué en attente du control plane pendant l'installation
Si vous remarquez que kubeadm init
se bloque après la ligne suivante:
[apiclient] Created API client, waiting for the control plane to become ready
Cela peut être causé par un certain nombre de problèmes. Les plus communs sont:
-
problèmes de connexion réseau. Vérifiez que votre machine dispose d'une connectivité réseau complète avant de continuer.
-
la configuration du driver cgroup par défaut pour la kubelet diffère de celle utilisée par Docker. Vérifiez le fichier journal du système (par exemple,
/var/log/message
) ou examinez le résultat dejournalctl -u kubelet
. Si vous voyez quelque chose comme ce qui suit:error: failed to run Kubelet: failed to create kubelet: misconfiguration: kubelet cgroup driver: "systemd" is different from docker cgroup driver: "cgroupfs"
Il existe deux méthodes courantes pour résoudre le problème du driver cgroup:
- Installez à nouveau Docker en suivant les instructions ici.
- Changez manuellement la configuration de la kubelet pour correspondre au driver Docker cgroup, vous pouvez vous référer à Configurez le driver de cgroupe utilisé par la kubelet sur le Nœud Master pour des instruction détaillées.
- Les conteneurs Docker du control plane sont en crashloop ou suspendus. Vous pouvez le vérifier en lançant
docker ps
et étudier chaque conteneur en exécutantdocker logs
.
kubeadm bloque lors de la suppression de conteneurs gérés
Les événements suivants peuvent se produire si Docker s'arrête et ne supprime pas les conteneurs gérés par Kubernetes:
sudo kubeadm reset
[preflight] Running pre-flight checks
[reset] Stopping the kubelet service
[reset] Unmounting mounted directories in "/var/lib/kubelet"
[reset] Removing kubernetes-managed containers
(block)
Une solution possible consiste à redémarrer le service Docker, puis à réexécuter kubeadm reset
:
sudo systemctl restart docker.service
sudo kubeadm reset
L'inspection des journaux de Docker peut également être utile:
journalctl -ul docker
Pods dans l'état RunContainerError
, CrashLoopBackOff
ou Error
Juste après kubeadm init
, il ne devrait pas y avoir de pods dans ces états.
- S'il existe des pods dans l'un de ces états juste après
kubeadm init
, veuillez ouvrir un issue dans le dépôt de Kubeadm.coredns
(oukube-dns
) devrait être dans l'étatPending
jusqu'à ce que vous ayez déployé la solution réseau. - Si vous voyez des pods dans les états
RunContainerError
,CrashLoopBackOff
ouError
après le déploiement de la solution réseau et que rien ne se passe pourcoredns
(oukube-dns
), il est très probable que la solution Pod Network que vous avez installée est en quelque sorte endommagée. Vous devrez peut-être lui accorder plus de privilèges RBAC ou utiliser une version plus récente. S'il vous plaît créez une issue dans le dépôt du fournisseur de réseau de Pod. - Si vous installez une version de Docker antérieure à 1.12.1, supprimez l'option
MountFlags = slave
lors du démarrage dedockerd
avecsystemd
et redémarrezdocker
. Vous pouvez voir les options de montage dans/usr/lib/systemd/system/docker.service
. Les options de montage peuvent interférer avec les volumes montés par Kubernetes et mettre les pods dans l'étatCrashLoopBackOff
. L'erreur se produit lorsque Kubernetes ne trouve pas les fichiersvar/run/secrets/kubernetes.io/serviceaccount
.
coredns
(ou kube-dns
) est bloqué dans l'état Pending
Ceci est prévu et fait partie du design. kubeadm est agnostique vis-à-vis du fournisseur
de réseau, ainsi l'administrateur devrait installer la solution réseau pod
de choix. Vous devez installer un réseau de pods avant que CoreDNS ne soit complètement déployé.
D'où l' état Pending
avant la mise en place du réseau.
Les services HostPort
ne fonctionnent pas
Les fonctionnalités HostPort
et HostIP
sont disponibles en fonction de votre fournisseur
de réseau de pod. Veuillez contacter l’auteur de la solution de réseau de Pod pour savoir si
Les fonctionnalités HostPort
et HostIP
sont disponibles.
Les fournisseurs de CNI Calico, Canal, et Flannel supportent HostPort.
Pour plus d'informations, voir la CNI portmap documentation.
Si votre fournisseur de réseau ne prend pas en charge le plug-in portmap CNI, vous devrez peut-être utiliser le
NodePort feature of services ou utiliser HostNetwork=true
.
Les pods ne sont pas accessibles via leur IP de service
-
De nombreux add-ons réseau ne permettent pas encore hairpin mode qui permet aux pods d’accéder à eux-mêmes via leur IP de service. Ceci est un problème lié au CNI. S'il vous plaît contacter le fournisseur d'add-on réseau afin d'obtenir des informations en matière de prise en charge du mode hairpin.
-
Si vous utilisez VirtualBox (directement ou via Vagrant), vous devrez vous assurez que
hostname -i
renvoie une adresse IP routable. Par défaut la première interface est connectée à un réseau d’hôte uniquement
non routable. En contournement vous pouvez modifier/etc/hosts
, jetez un œil à ce Vagrantfile par exemple.
Erreurs de certificats TLS
L'erreur suivante indique une possible incompatibilité de certificat.
# kubectl get pods
Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of
"crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")
-
Vérifiez que le fichier
$HOME/.kube/config
contient un certificat valide, et re-générer un certificat si nécessaire. Les certificats dans un fichier kubeconfig sont encodés en base64. La commandebase64 -d
peut être utilisée pour décoder le certificat etopenssl x509 -text -noout
peut être utilisé pour afficher les informations du certificat. -
Une autre solution consiste à écraser le
kubeconfig
existant pour l'utilisateur" admin ":mv $HOME/.kube $HOME/.kube.bak sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
Carte réseau par défaut lors de l'utilisation de flannel comme réseau de pod dans Vagrant
L'erreur suivante peut indiquer que quelque chose n'allait pas dans le réseau de pod:
Error from server (NotFound): the server could not find the requested resource
- Si vous utilisez flannel comme réseau de pod dans Vagrant, vous devrez spécifier le nom d'interface par défaut pour flannel.
Vagrant attribue généralement deux interfaces à tous les ordinateurs virtuels. La
première, pour laquel tous les hôtes se voient attribuer l’adresse IP 10.0.2.15
,
est pour le trafic externe qui est NATé.
Cela peut entraîner des problèmes avec Flannel, qui utilise par défaut la première
interface sur un hôte. Ceci conduit au fait que tous les hôtes pensent qu'ils ont la
même adresse IP publique. Pour éviter cela, passez l'option --iface eth1
sur Flannel
pour que la deuxième interface soit choisie.
IP non publique utilisée pour les conteneurs
Dans certaines situations, les commandes kubectl logs
et kubectl run
peuvent
renvoyer les erreurs suivantes dans un cluster par ailleurs fonctionnel:
Error from server: Get https://10.19.0.41:10250/containerLogs/default/mysql-ddc65b868-glc5m/mysql:
dial tcp 10.19.0.41:10250: getsockopt: no route to host
-
Cela peut être dû au fait que Kubernetes utilise une adresse IP qui ne peut pas communiquer avec d’autres adresses IP même sous-réseau, éventuellement à cause d'une politique mise en place par le fournisseur de la machine.
-
Digital Ocean attribue une adresse IP publique à
eth0
ainsi qu’une adresse privée à utiliser en interne comme IP d'ancrage pour leur fonction IP flottante, maiskubelet
choisira cette dernière commeInternalIP
du noeud au lieu du public.Utilisez
ip addr show
pour verifier ce scénario au lieu deifconfig
carifconfig
n'affichera pas l'alias de l'adresse IP incriminée. Sinon, une API spécifique à Digital Ocean permet de rechercher l'adresse IP d'ancrage à partir du droplet:curl http://169.254.169.254/metadata/v1/interfaces/public/0/anchor_ipv4/address
La solution consiste à indiquer à la
kubelet
l'adresse IP à utiliser avec--node-ip
. Lors de l'utilisation de Digital Ocean, il peut être public (assigné àeth0
) ou privé (assigné àeth1
) si vous voulez utiliser le réseau privé optionnel. la la sectionKubeletExtraArgs
de kubeadmNodeRegistrationOptions
structure peut être utilisé pour cela.Puis redémarrer la
kubelet
:systemctl daemon-reload systemctl restart kubelet
Les pods coredns
sont en état CrashLoopBackOff
ou Error
Si vous avez des nœuds qui exécutent SELinux avec une version plus ancienne de Docker, vous risquez
de rencontrer un problème ou les pods de coredns
ne démarrent pas. Pour résoudre ce problème, vous pouvez essayer l'une des options suivantes:
- Mise à niveau vers une nouvelle version de Docker.
- Désactiver SELinux.
- Modifiez le déploiement de
coredns
pour définirallowPrivilegeEscalation
àtrue
:
kubectl -n kube-system get deployment coredns -o yaml | \
sed 's/allowPrivilegeEscalation: false/allowPrivilegeEscalation: true/g' | \
kubectl apply -f -
une autre raison pour laquelle CoreDNS peut se retrouver dans l'état CrashLoopBackOff
est lorsqu'un
Pod de CoreDNS déployé dans Kubernetes détecte une boucle. Un certain nombre de solutions de contournement
sont disponibles pour éviter que Kubernetes ne tente de redémarrer le pod CoreDNS chaque fois que CoreDNS détecte une boucle et s'arrête.
allowPrivilegeEscalation
sur true
peut compromettre
la sécurité de votre cluster.
Les pods etcd redémarrent continuellement
Si vous rencontrez l'erreur suivante:
rpc error: code = 2 desc = oci runtime error: exec failed: container_linux.go:247: starting container
process caused "process_linux.go:110: decoding init error from pipe caused \"read parent: connection
reset by peer\""
ce problème apparaît si vous exécutez CentOS 7 avec Docker 1.13.1.84. Cette version de Docker peut empêcher la kubelet de s'exécuter dans le conteneur etcd.
Pour contourner le problème, choisissez l'une de ces options.:
- Revenir à une version antérieure de Docker, telle que la 1.13.1-75:
yum downgrade docker-1.13.1-75.git8633870.el7.centos.x86_64 docker-client-1.13.1-75.git8633870.el7.centos.x86_64 docker-common-1.13.1-75.git8633870.el7.centos.x86_64
- Installez l'une des versions les plus récentes recommandées, telles que la 18.06:
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce-18.06.1.ce-3.el7.x86_64
2.3.2 - Solutions Cloud clés en main
2.3.3 - On-Premises VMs
2.3.4 - Windows dans Kubernetes
2.4 - Solutions Cloud personnalisées
2.4.1 - CoreOS sur AWS ou GCE
Il existe plusieurs guides permettant d'utiliser Kubernetes avec CoreOS.
Guides officiels CoreOS
Ces guides sont maintenus par CoreOS et déploient Kubernetes à la "façon CoreOS" avec du TLS, le composant complémentaire pour le DNS interne, etc. Ces guides passent les tests de conformité Kubernetes et nous vous recommendons de [les tester vous-même] (https://coreos.com/kubernetes/docs/latest/conformance-tests.html).
-
Guide et outil en ligne de commande pour créer un cluster multi-noeuds sur AWS. CloudFormation est utilisé pour créer un noeud maitre ("master") et plusieurs noeuds de type "worker".
-
Multi-noeuds sur serveurs physiques (Bare Metal)
Guide et service HTTP / API pour l'initialisation et l'installation d’un cluster à plusieurs nœuds bare metal à partir d'un PXE. Ignition est utilisé pour provisionner un cluster composé d'un master et de plusieurs workers lors du démarrage initial des serveurs.
-
Guide pour l'installation d'un cluster multi-noeuds sur Vagrant. L'outil de déploiement permet de configurer indépendemment le nombre de noeuds etcd, masters et workers afin d'obtenir un control plane en haute disponibilité.
-
C'est la façon la plus rapide d'installer un environnement de développement local Kubernetes. Il suffit simplement de
git clone
,vagrant up
puis configurerkubectl
. -
Un guide générique qui permet de déployer un cluster en haute disponibilité (avec du TLS) sur n'importe cloud ou sur du bare metal. Répéter les étapes pour obtenir plus de noeuds master ou worker
Guide de la communauté
Ces guides sont maintenus par des membres de la communauté et couvrent des besoins et cas d'usages spécifiques. Ils proposent différentes manières de configurer Kubernetes sur CoreOS.
-
Cluster multi-noeuds facile sur Google Compute Engine
Installation scriptée d'un master unique et de plusieurs workers sur GCE. Les composants Kubernetes sont gérés par fleet
-
Cluster multi-noeuds en utilisant cloud-config et Weave sur Vagrant
Configure un cluster de 3 machines sur Vagrant, le réseau du cluster étant fourni par Weave.
-
Cluster multi-noeuds en utilisant cloud-config et Vagrant
Configure un cluster local composé d'un master et de plusieurs workers sur l'hyperviseur de votre choix: VirtualBox, Parallels, ou VMware
-
Cluster d'un seul noeud en utilisant une application macOS
Guide permettant d'obtenir un cluster d'un seul noeud faisant office de master et worker et contrôlé par une application macOS menubar. (basé sur xhyve et CoreOS)
-
Cluster multi-noeuds avec Vagrant et fleet en utilisant une petite application macOS
Guide permettant d'obtenir un cluster composé d'un master, de plusieurs workers contrôlés par une application macOS menubar.
-
Multi-node cluster using cloud-config, CoreOS and VMware ESXi
Configure un cluster composé d'un master et de plusieurs workers sur VMWare ESXi
-
Cluster Unique/Multi noeuds en utilisant cloud-config, CoreOS et Foreman
Configure un cluster composé d'un ou de plusieurs noeuds avec Foreman.
Niveau de support
IaaS Provider | Config. Mgmt | OS | Networking | Docs | Conforms | Support Level |
---|---|---|---|---|---|---|
GCE | CoreOS | CoreOS | flannel | docs | Community (@pires) | |
Vagrant | CoreOS | CoreOS | flannel | docs | Community (@pires, @AntonioMeireles) |
Pour le niveau de support de toutes les solutions se référer au Tableau des solutions.
2.4.2 - Installer Kubernetes avec Kubespray (on-premises et fournisseurs de cloud)
Cette documentation permet d'installer rapidement un cluster Kubernetes hébergé sur GCE, Azure, Openstack, AWS, vSphere, Oracle Cloud Infrastructure (expérimental) ou sur des serveurs physiques (bare metal) grâce à Kubespray.
Kubespray se base sur des outils de provisioning, des paramètres et playbooks Ansible ainsi que sur des connaissances spécifiques à Kubernetes et l'installation de systèmes d'exploitation afin de fournir:
- Un cluster en haute disponibilité
- des composants modulables
- Le support des principales distributions Linux:
- Container Linux de CoreOS
- Debian Jessie, Stretch, Wheezy
- Ubuntu 16.04, 18.04
- CentOS/RHEL 7
- Fedora/CentOS Atomic
- openSUSE Leap 42.3/Tumbleweed
- des tests d'intégration continue
Afin de choisir l'outil le mieux adapté à votre besoin, veuillez lire cette comparaison avec kubeadm et kops.
Créer un cluster
(1/5) Prérequis
Les serveurs doivent être installés en s'assurant des éléments suivants:
- Ansible v2.6 (ou version plus récente) et python-netaddr installés sur la machine qui exécutera les commandes Ansible
- Jinja 2.9 (ou version plus récente) est nécessaire pour exécuter les playbooks Ansible
- Les serveurs cibles doivent avoir accès à Internet afin de télécharger les images Docker. Autrement, une configuration supplémentaire est nécessaire, (se référer à Offline Environment)
- Les serveurs cibles doivent être configurés afin d'autoriser le transfert IPv4 (IPv4 forwarding)
- Votre clé ssh doit être copiée sur tous les serveurs faisant partie de votre inventaire Ansible.
- La configuration du pare-feu n'est pas gérée. Vous devrez vous en charger en utilisant votre méthode habituelle. Afin d'éviter tout problème pendant l'installation nous vous conseillons de le désacttiver.
- Si Kubespray est exécuté avec un utilisateur autre que "root", une méthode d'autorisation appropriée devra être configurée sur les serveurs cibles (exemple: sudo). Il faudra aussi utiliser le paramètre
ansible_become
ou ajouter--become
oub
à la ligne de commande.
Afin de vous aider à préparer votre de votre environnement, Kubespray fournit les outils suivants:
(2/5) Construire un fichier d'inventaire Ansible
Lorsque vos serveurs sont disponibles, créez un fichier d'inventaire Ansible (inventory). Vous pouvez le créer manuellement ou en utilisant un script d'inventaire dynamique. Pour plus d'informations se référer à Building your own inventory.
(3/5) Préparation au déploiement de votre cluster
Kubespray permet de personnaliser de nombreux éléments:
- Choix du mode: kubeadm ou non-kubeadm
- Plugins CNI (réseau)
- Configuration du DNS
- Choix du control plane: natif/binaire ou dans un conteneur docker/rkt
- Version de chaque composant
- "route reflectors" Calico
- Moteur de conteneur
- docker
- rkt
- cri-o
- Méthode de génération des certificats (Vault n'étant plus maintenu)
Ces paramètres Kubespray peuvent être définis dans un fichier de variables. Si vous venez juste de commencer à utiliser Kubespray nous vous recommandons d'utiliser les paramètres par défaut pour déployer votre cluster et découvrir Kubernetes
(4/5) Déployer un Cluster
Vous pouvez ensuite lancer le déploiement de votre cluster:
Déploiement du cluster en utilisant l'outil en ligne de commande ansible-playbook.
ansible-playbook -i your/inventory/hosts.ini cluster.yml -b -v \
--private-key=~/.ssh/private_key
Pour des déploiements plus importants (>100 noeuds) quelques ajustements peuvent être nécessaires afin d'obtenir de meilleurs résultats.
(5/5) Vérifier le déploiement
Kubespray fournit le moyen de vérifier la connectivité inter-pods ainsi que la résolution DNS grâce à Netchecker. Les pods netchecker-agents s'assurent que la résolution DNS (services Kubernetes) ainsi que le ping entre les pods fonctionnent correctement. Ces pods reproduisent un comportement similaire à celui des autres applications et offrent un indicateur de santé du cluster.
Opérations sur le cluster
Kubespray fournit des playbooks supplémentaires qui permettent de gérer votre cluster: scale et upgrade.
Mise à l'échelle du cluster
Vous pouvez ajouter des noeuds à votre cluster en exécutant le playbook scale
. Pour plus d'informations se référer à Adding nodes.
vous pouvez retirer des noeuds de votre cluster en exécutant le playbook remove-node
. Se référer à Remove nodes.
Mise à jour du cluster
Vous pouvez mettre à jour votre cluster en exécutant le playbook upgrade-cluster
. Pour plus d'informations se référer à Upgrades.
Nettoyage
Vous pouvez réinitialiser vos noeuds et supprimer tous les composants installés par Kubespray en utilisant le playbook reset.
reset
, assurez-vous de ne pas cibler accidentellement un cluster de production !
Retours
- Channel Slack: #kubespray
- Issues GitHub
A suivre
Jetez un oeil aux travaux prévus sur Kubespray: roadmap.
2.4.3 - Installer Kubernetes sur AWS avec kops
Cette documentation pour un démarrage rapide montre comment facilement installer un cluster Kubernetes sur AWS.
L'outil utilisé est kops
.
kops est un système de provisionnement dont les principes sont:
- Une installation totalement automatisée
- Utilisation du DNS pour identifier les clusters
- Auto-guérison: tous les composants tournent dans des groupe de mise à l'échelle automatique (auto-scaling)
- Support de plusieurs systèmes d'exploitation (Debian, Ubuntu 16.04 supportés, Centos & RHEL, Amazon Linux et CoreOS) - se référer à images.md
- Haute disponibilité - se référer à high_availability.md
- Peut provisionner directement, ou générer des manifests terraform - se référer à terraform.md
Si ces principes ne vous conviennent pas, vous préférerez probablement construire votre propre cluster selon votre convenance grâce à kubeadm.
Créer un cluster
(1/5) Installer kops
Pré-requis
Il est nécessaire d'avoir kubectl d'installé pour que kops puisse fonctionner.
Installation
Télécharger kops à partir de la page de releases (Il est aussi facile à construire à partir des sources):
Sur macOS:
Téléchargez la dernière version avec la commande:
curl -LO https://github.com/kubernetes/kops/releases/download/$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)/kops-darwin-amd64
Pour télécharger une version spécifique, remplacez le
$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)
partie de la commande avec la version spécifique.
Par exemple, pour télécharger la version 1.15.0 de kops, tapez:
curl -LO https://github.com/kubernetes/kops/releases/download/1.15.0/kops-darwin-amd64
Rendre le binaire exécutable kops.
chmod +x kops-darwin-amd64
Déplacez le fichier binaire kops dans votre chemin.
sudo mv kops-darwin-amd64 /usr/local/bin/kops
Vous pouvez également installer kops en utilisant [Homebrew] (https://brew.sh/).
brew update && brew install kops
Sur Linux:
Téléchargez la dernière version avec la commande:
curl -LO https://github.com/kubernetes/kops/releases/download/$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)/kops-linux-amd64
Pour télécharger une version spécifique, remplacez le
$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)
partie de la commande avec la version spécifique.
Par exemple, pour télécharger la version 1.15.0 de kops, tapez:
curl -LO https://github.com/kubernetes/kops/releases/download/1.15.0/kops-linux-amd64
Rendre le binaire exécutable kops
chmod +x kops-linux-amd64
Déplacez le fichier binaire kops dans votre chemin.
sudo mv kops-linux-amd64 /usr/local/bin/kops
Vous pouvez également installer kops en utilisant [Homebrew] (https://docs.brew.sh/Homebrew-on-Linux).
brew update && brew install kops
(2/5) Créer un domaine route53 pour votre cluster
kops utilise le DNS pour la découverte, que ce soit à l'intérieur du cluster ou pour pouvoir communiquer avec l'API de kubernetes à partir des clients.
Pour kops le nom du cluster doit impérativement être un nom de domaine valide. De cette façon vous ne confondrez pas vos cluster et vous pourrez les partager avec vos collègues sans ambiguïté. Par ailleurs vous pourrez vous y connecter sans avoir à vous rappeler une adresse IP.
Vous pouvez, et vous devriez certainement, utiliser des sous-domaines afin de séparer vos clusters.
Dans notre exemple nous utiliserons useast1.dev.example.com
. Le point d'accès au serveur API sera donc api.useast1.dev.example.com
.
Une zone hébergée Route53 peut servir les sous-domaines. Votre zone hébergée pourrait être useast1.dev.example.com
,
mais aussi dev.example.com
ou même example.com
. kops fonctionne avec n'importe lequel d'entre eux, le choix dépend de vos contraintes d'organisation (ex: Vous êtes autorisés à créer des enregistrements dns dans dev.example.com
mais pas dans example.com
)
Supposons que vous utilisiez dev.example.com
comme zone hébergée. Vous créeriez cette zone hébergée en utilisant la méthode normal, ou avec une ligne de commande telle que aws route53 create-hosted-zone --name dev.example.com --caller-reference 1
.
Vous devrez ensuite configurer vos enregistrements NS dans le domaine parent afin que vous puissiez résoudre dans ce domaine.
Vous créeriez donc des enregistrements NS dans le domaine example.com
pour dev
.
S'il s'agit d'un nom de domaine racine, vous devrez configurer les enregistrements NS chez votre hébergeur de nom de domaine (là où vous avez acheté votre nom de domaine example.com
).
Cette étape est délicate, soyez vigilants (c’est la première cause de problèmes !). Vous pouvez vérifier que votre cluster est configuré correctement avec l'outil dig, en exécutant:
dig NS dev.example.com
Vous devriez voir les 4 enregistrements NS attribués à votre zone hébergée sur Route53.
(3/5) Créez un conteneur (bucket) S3 pour stocker l'état de vos clusters.
kops vous permet de gérer vos clusters même lorsque ceux-ci sont déjà installés. Pour ce faire, il est nécessaire de conserver une trace des clusters que vous avez créé, avec leur configuration, les clés qu’ils utilisent, etc. Ces informations sont stockées dans un bucket S3. Les autorisations S3 sont utilisées pour contrôler l'accès au bucket.
Plusieurs clusters peuvent utiliser le même bucket S3 et vous pouvez aussi le partager avec vos collègues qui administrer les mêmes clusters - c'est beaucoup plus facile que de faire circuler des fichiers kubecfg. Cependant quiconque ayant accès au bucket S3 aura un accès complet (permissions élevées) à tous vos clusters. Vous souhaiterez donc limiter l'accès à l'équipe opérationnelle.
Plus généralement, vous auriez un bucket S3 pour chaque équipe ops (et le nom correspondrait souvent au nom de la zone hébergée ci-dessus!)
Dans notre exemple, nous avons choisi dev.example.com
comme zone hébergée. Nous allons donc choisir clusters.dev.example.com
comm le nom du bucket S3.
-
Exportez
AWS_PROFILE
(si vous devez sélectionner un profil pour que l'outil en ligne de commande d'AWS fonctionne). -
Créez le compartiment S3 en utilisant
aws s3 mb s3://clusters.dev.example.com
-
Vous pouvez
export KOPS_STATE_STORE=s3://clusters.dev.example.com
afin que kops utilise cet emplacement par défaut. Nous vous suggérons de le mettre dans votre profil bash ou similaire.
(4/5) Construisez votre configuration de cluster
Exécutez "kops create cluster" pour créer votre configuration de cluster:
kops create cluster --zones=us-east-1c useast1.dev.example.com
kops créera la configuration pour votre cluster. Notez que cela génère uniquement la configuration, la création des ressources cloud se fait à l'étape suivante avec kops update cluster
. Cela vous permettra d'analyser la configuration ou de la modifier avant de l'appliquer.
Voici quelques commandes qui vous permettent de visualiser ou éditer:
- Listez vos clusters avec:
kops get cluster
- Éditez ce cluster avec:
kops edit cluster useast1.dev.example.com
- Modifiez votre groupe d'instances de nœuds:
kops edit ig --name=useast1.dev.example.com nodes
- Éditez votre groupe d'instances maître (master):
kops edit ig --name=useast1.dev.example.com master-us-east-1c
Si vous utilisez kops pour la première fois, prenez quelques minutes pour les essayer! Un groupe d'instances est un ensemble d'instances, qui seront enregistrées en tant que noeuds kubernetes. Sur AWS, cela est implémenté via des groupes de mise à l'échelle automatique (auto-scaling). Vous pouvez avoir plusieurs groupes d'instances, par exemple si vous voulez des nœuds combinant des instances ponctuelles (spot instances) et à la demande, ou éventuellement des instances GPU et non-GPU.
(5/5) Créer le cluster dans AWS
Exécutez "kops update cluster" pour créer votre cluster dans AWS :
kops update cluster useast1.dev.example.com --yes
Cela prend quelques secondes à s'exécuter, et ensuite votre cluster prendra probablement quelques minutes pour être réellement opérationnel.
kops update cluster
sera l'outil que vous utiliserez à chaque fois que vous modifierez la configuration de votre cluster.
Il applique les modifications que vous avez apportées à la configuration sur votre cluster (reconfiguration d'AWS ou de kubernetes au besoin).
Par exemple, après un kops edit ig nodes
, puis un kops update cluster --yes
pour appliquer votre configuration, parfois, vous devrez également exécuter un kops rolling-update cluster
pour déployer la configuration immédiatement.
Sans l'argument --yes
, kops update cluster
vous montrera un aperçu de ce qu’il va faire. C'est pratique
pour les clusters de production !
Explorer d'autres composants additionnels (add-ons)
Reportez-vous à la [liste des add-ons] (/docs/concepts/cluster-administration/addons/) pour explorer d'autres add-ons, y compris des outils de journalisation, de surveillance, de stratégie réseau, de visualisation ou de contrôle de votre cluster Kubernetes.
Nettoyer
- Pour supprimer votre cluster:
kops delete cluster useast1.dev.example.com --yes
Retour d'information
- Channel Slack: [#kops-users] (https://kubernetes.slack.com/messages/kops-users/)
- [Problèmes GitHub] (https://github.com/kubernetes/kops/issues)
A suivre
- En apprendre davantages sur les concepts Kubernetes et
kubectl
. - En savoir plus sur les utilisations avancées de
kops
. - Pour les bonnes pratiques et les options de configuration avancées de
kops
se référer à la documentation
3 - Concepts
La section Concepts vous aide à mieux comprendre les composants du système Kubernetes et les abstractions que Kubernetes utilise pour représenter votre cluster. Elle vous aide également à mieux comprendre le fonctionnement de Kubernetes en général.
Vue d'ensemble
Pour utiliser Kubernetes, vous utilisez les objets de l'API Kubernetes pour décrire l'état souhaité de votre cluster: quelles applications ou autres processus que vous souhaitez exécuter, quelles images de conteneur elles utilisent, le nombre de réplicas, les ressources réseau et disque que vous mettez à disposition, et plus encore.
Vous définissez l'état souhaité en créant des objets à l'aide de l'API Kubernetes, généralement via l'interface en ligne de commande, kubectl
.
Vous pouvez également utiliser l'API Kubernetes directement pour interagir avec le cluster et définir ou modifier l'état souhaité.
Une fois que vous avez défini l'état souhaité, le plan de contrôle Kubernetes (control plane en anglais) permet de faire en sorte que l'état actuel du cluster corresponde à l'état souhaité. Pour ce faire, Kubernetes effectue automatiquement diverses tâches, telles que le démarrage ou le redémarrage de conteneurs, la mise à jour du nombre de réplicas d'une application donnée, etc. Le control plane Kubernetes comprend un ensemble de processus en cours d'exécution sur votre cluster:
- Le maître Kubernetes (Kubernetes master en anglais) qui est un ensemble de trois processus qui s'exécutent sur un seul nœud de votre cluster, désigné comme nœud maître (master node en anglais). Ces processus sont: kube-apiserver, kube-controller-manager et kube-scheduler.
- Chaque nœud non maître de votre cluster exécute deux processus:
- kubelet, qui communique avec le Kubernetes master.
- kube-proxy, un proxy réseau reflétant les services réseau Kubernetes sur chaque nœud.
Objets Kubernetes
Kubernetes contient un certain nombre d'abstractions représentant l'état de votre système: applications et processus conteneurisés déployés, leurs ressources réseau et disque associées, ainsi que d'autres informations sur les activités de votre cluster. Ces abstractions sont représentées par des objets de l'API Kubernetes; consultez Vue d'ensemble des objets Kubernetes pour plus d'informations.
Les objets de base de Kubernetes incluent:
En outre, Kubernetes contient un certain nombre d'abstractions de niveau supérieur appelées Contrôleurs. Les contrôleurs s'appuient sur les objets de base et fournissent des fonctionnalités supplémentaires.
Voici quelques exemples:
Kubernetes control plane
Les différentes parties du control plane Kubernetes, telles que les processus Kubernetes master et kubelet, déterminent la manière dont Kubernetes communique avec votre cluster. Le control plane conserve un enregistrement de tous les objets Kubernetes du système et exécute des boucles de contrôle continues pour gérer l'état de ces objets. À tout moment, les boucles de contrôle du control plane répondent aux modifications du cluster et permettent de faire en sorte que l'état réel de tous les objets du système corresponde à l'état souhaité que vous avez fourni.
Par exemple, lorsque vous utilisez l'API Kubernetes pour créer un objet Deployment, vous fournissez un nouvel état souhaité pour le système. Le control plane Kubernetes enregistre la création de cet objet et exécute vos instructions en lançant les applications requises et en les planifiant vers des nœuds de cluster, afin que l'état actuel du cluster corresponde à l'état souhaité.
Kubernetes master
Le Kubernetes master est responsable du maintien de l'état souhaité pour votre cluster.
Lorsque vous interagissez avec Kubernetes, par exemple en utilisant l'interface en ligne de commande kubectl
, vous communiquez avec le master Kubernetes de votre cluster.
Le "master" fait référence à un ensemble de processus gérant l'état du cluster. En règle générale, tous les processus sont exécutés sur un seul nœud du cluster. Ce nœud est également appelé master. Le master peut également être répliqué pour la disponibilité et la redondance.
Noeuds Kubernetes
Les nœuds d’un cluster sont les machines (serveurs physiques, machines virtuelles, etc.) qui exécutent vos applications et vos workflows. Le master node Kubernetes contrôle chaque noeud; vous interagirez rarement directement avec les nœuds.
Metadonnées des objets Kubernetes
A suivre
Si vous souhaitez écrire une page de concept, consultez Utilisation de modèles de page pour plus d'informations sur le type de page pour la documentation d'un concept.
3.1 - Vue d'ensemble
3.1.1 - Qu'est-ce-que Kubernetes ?
Cette page est une vue d'ensemble de Kubernetes.
Kubernetes est une plate-forme open-source extensible et portable pour la gestion de charges de travail (workloads) et de services conteneurisés. Elle favorise à la fois l'écriture de configuration déclarative (declarative configuration) et l'automatisation. C'est un large écosystème en rapide expansion. Les services, le support et les outils Kubernetes sont largement disponibles.
Google a rendu open-source le projet Kubernetes en 2014. Le développement de Kubernetes est basé sur une décennie et demie d’expérience de Google avec la gestion de la charge et de la mise à l'échelle (scale) en production, associée aux meilleures idées et pratiques de la communauté.
Pourquoi ai-je besoin de Kubernetes et que peut-il faire ?
Kubernetes a un certain nombre de fonctionnalités. Il peut être considéré comme:
- une plate-forme de conteneurs
- une plate-forme de microservices
- une plate-forme cloud portable et beaucoup plus.
Kubernetes fournit un environnement de gestion focalisé sur le conteneur (container-centric). Il orchestre les ressources machines (computing), la mise en réseau et l’infrastructure de stockage sur les workloads des utilisateurs. Cela permet de se rapprocher de la simplicité des Platform as a Service (PaaS) avec la flexibilité des solutions d'Infrastructure as a Service (IaaS), tout en gardant de la portabilité entre les différents fournisseurs d'infrastructures (providers).
Comment Kubernetes est-il une plate-forme ?
Même si Kubernetes fournit de nombreuses fonctionnalités, il existe toujours de nouveaux scénarios qui bénéficieraient de fonctionnalités complémentaires. Ces workflows spécifiques à une application permettent d'accélérer la vitesse de développement. Si l'orchestration fournie de base est acceptable pour commencer, il est souvent nécessaire d'avoir une automatisation robuste lorsque l'on doit la faire évoluer. C'est pourquoi Kubernetes a également été conçu pour servir de plate-forme et favoriser la construction d’un écosystème de composants et d’outils facilitant le déploiement, la mise à l’échelle et la gestion des applications.
Les Labels permettent aux utilisateurs d'organiser leurs ressources comme ils/elles le souhaitent. Les Annotations autorisent les utilisateurs à définir des informations personnalisées sur les ressources pour faciliter leurs workflows et fournissent un moyen simple aux outils de gérer la vérification d'un état (checkpoint state).
De plus, le plan de contrôle Kubernetes (control plane) est construit sur les mêmes APIs que celles accessibles aux développeurs et utilisateurs. Les utilisateurs peuvent écrire leurs propres contrôleurs (controllers), tels que les ordonnanceurs (schedulers), avec leurs propres APIs qui peuvent être utilisés par un outil en ligne de commande.
Ce choix de conception a permis de construire un ensemble d'autres systèmes par dessus Kubernetes.
Ce que Kubernetes n'est pas
Kubernetes n’est pas une solution PaaS (Platform as a Service). Kubernetes opérant au niveau des conteneurs plutôt qu'au niveau du matériel, il fournit une partie des fonctionnalités des offres PaaS, telles que le déploiement, la mise à l'échelle, l'équilibrage de charge (load balancing), la journalisation (logging) et la surveillance (monitoring). Cependant, Kubernetes n'est pas monolithique. Ces implémentations par défaut sont optionnelles et interchangeables. Kubernetes fournit les bases permettant de construire des plates-formes orientées développeurs, en laissant la possibilité à l'utilisateur de faire ses propres choix.
Kubernetes:
- Ne limite pas les types d'applications supportées. Kubernetes prend en charge des workloads extrêmement diverses, dont des applications stateless, stateful ou orientées traitement de données (data-processing). Si l'application peut fonctionner dans un conteneur, elle devrait fonctionner correctement sur Kubernetes.
- Ne déploie pas de code source et ne build pas d'application non plus. Les workflows d'Intégration Continue, de Livraison Continue et de Déploiement Continu (CI/CD) sont réalisés en fonction de la culture d'entreprise, des préférences ou des pré-requis techniques.
- Ne fournit pas nativement de services au niveau applicatif tels que des middlewares (e.g., message buses), des frameworks de traitement de données (par exemple, Spark), des bases de données (e.g., mysql), caches, ou systèmes de stockage clusterisés (e.g., Ceph). Ces composants peuvent être lancés dans Kubernetes et/ou être accessibles à des applications tournant dans Kubernetes via des mécaniques d'intermédiation tel que Open Service Broker.
- N'impose pas de solutions de logging, monitoring, ou alerting. Kubernetes fournit quelques intégrations primaires et des mécanismes de collecte et export de métriques.
- Ne fournit ou n'impose un langague/système de configuration (e.g., jsonnet). Il fournit une API déclarative qui peut être ciblée par n'importe quelle forme de spécifications déclaratives.
- Ne fournit ou n'adopte aucune mécanique de configuration des machines, de maintenance, de gestion ou de contrôle de la santé des systèmes.
De plus, Kubernetes n'est pas vraiment un système d'orchestration. En réalité, il élimine le besoin d'orchestration. Techniquement, l'orchestration se définit par l'exécution d'un workflow spécifié : premièrement faire A, puis B, puis C. Kubernetes quant à lui est composé d'un ensemble de processus de contrôle qui pilotent l'état courant vers l'état désiré. Peu importe comment on arrive du point A au point C. Un contrôle centralisé n'est pas non plus requis. Cela aboutit à un système plus simple à utiliser et plus puissant, robuste, résiliant et extensible.
Pourquoi les conteneurs ?
Vous cherchez des raisons d'utiliser des conteneurs ?
L'ancienne façon (old way) de déployer des applications consistait à installer les applications sur un hôte en utilisant les systèmes de gestions de paquets natifs. Cela avait pour principale inconvénient de lier fortement les exécutables, la configuration, les librairies et le cycle de vie de chacun avec l'OS. Il est bien entendu possible de construire une image de machine virtuelle (VM) immuable pour arriver à produire des publications (rollouts) ou retours arrières (rollbacks), mais les VMs sont lourdes et non-portables.
La nouvelle façon (new way) consiste à déployer des conteneurs basés sur une virtualisation au niveau du système d'opération (operation-system-level) plutôt que de la virtualisation hardware. Ces conteneurs sont isolés les uns des autres et de l'hôte : ils ont leurs propres systèmes de fichiers, ne peuvent voir que leurs propres processus et leur usage des ressources peut être contraint. Ils sont aussi plus faciles à construire que des VMs, et vu qu'ils sont décorrélés de l'infrastructure sous-jacente et du système de fichiers de l'hôte, ils sont aussi portables entre les différents fournisseurs de Cloud et les OS.
Étant donné que les conteneurs sont petits et rapides, une application peut être packagée dans chaque image de conteneurs. Cette relation application-image tout-en-un permet de bénéficier de tous les bénéfices des conteneurs. Avec les conteneurs, des images immuables de conteneurs peuvent être créées au moment du build/release plutôt qu'au déploiement, vu que chaque application ne dépend pas du reste de la stack applicative et n'est pas liée à l'environnement de production. La génération d'images de conteneurs au moment du build permet d'obtenir un environnement constant qui peut être déployé tant en développement qu'en production. De la même manière, les conteneurs sont bien plus transparents que les VMs, ce qui facilite le monitoring et le management. Cela est particulièrement vrai lorsque le cycle de vie des conteneurs est géré par l'infrastructure plutôt que caché par un gestionnaire de processus à l'intérieur du conteneur. Avec une application par conteneur, gérer ces conteneurs équivaut à gérer le déploiement de son application.
Résumé des bénéfices des conteneurs :
- Création et déploiement agile d'applications : Augmente la simplicité et l'efficacité de la création d'images par rapport à l'utilisation d'images de VM.
- Développement, intégration et déploiement Continus: Fournit un processus pour constuire et déployer fréquemment et de façon fiable avec la capacité de faire des rollbacks rapides et simples (grâce à l'immuabilité de l'image).
- Séparation des besoins entre Dev et Ops: Création d'images applicatives au moment du build plutôt qu'au déploiement, tout en séparant l'application de l'infrastructure.
- Observabilité Informations venant non seulement du système d'exploitation sous-jacent mais aussi des signaux propres de l'application.
- Consistance entre les environnements de développement, tests et production: Fonctionne de la même manière que ce soit sur un poste local que chez un fournisseur d'hébergement / dans le Cloud.
- Portabilité entre Cloud et distribution système: Fonctionne sur Ubuntu, RHEL, CoreOS, on-prem, Google Kubernetes Engine, et n'importe où.
- Gestion centrée Application: Bascule le niveau d'abstraction d'une virtualisation hardware liée à l'OS à une logique de ressources orientée application.
- Micro-services faiblement couplés, distribués, élastiques: Les applications sont séparées en petits morceaux indépendants et peuvent être déployées et gérées dynamiquement -- pas une stack monolithique dans une seule machine à tout faire.
- Isolation des ressources: Performances de l'application prédictibles.
- Utilisation des ressources: Haute efficacité et densité.
Qu'est-ce-que Kubernetes signifie ? K8s ?
Le nom Kubernetes tire son origine du grec ancien, signifiant capitaine ou pilote et est la racine de gouverneur et cybernetic. K8s est l'abbréviation dérivée par le remplacement des 8 lettres "ubernete" par "8".
A suivre
- Prêt à commencer ?
- Pour plus de détails, voir la documentation Kubernetes.
3.1.2 - Composants de Kubernetes
Ce document résume les divers composants binaires requis pour livrer un cluster Kubernetes fonctionnel.
Composants Master
Les composants Master fournissent le plan de contrôle (control plane) du cluster.
Les composants Master prennent des décisions globales à propos du cluster (par exemple, la planification (scheduling)).
Ils détectent et répondent aux événements du cluster (par exemple, démarrer un nouveau Pod lorsque le champ replicas
d'un déploiement n'est pas satisfait).
Les composants Master peuvent être exécutés sur n'importe quelle machine du cluster. Toutefois, par soucis de simplicité, les scripts de mise en route démarrent typiquement tous les composants master sur la même machine et n'exécutent pas de conteneurs utilisateur sur cette machine. Voir Construire des Clusters en Haute Disponibilité pour une configuration d'exemple en multi-master-VM.
kube-apiserver
Composant sur le master qui expose l'API Kubernetes. Il s'agit du front-end pour le plan de contrôle Kubernetes.
Il est conçu pour une mise à l'échelle horizontale, ce qui veut dire qu'il met à l'échelle en déployant des instances supplémentaires. Voir Construire des Clusters en Haute Disponibilité.
etcd
Base de données clé-valeur consistante et hautement disponible utilisée comme mémoire de sauvegarde pour toutes les données du cluster.
Si votre cluster Kubernetes utilise etcd comme mémoire de sauvegarde, assurez-vous d'avoir un plan de back up pour ces données.
Vous pouvez trouver plus d'informations à propos d'etcd dans la documentation officielle.
kube-scheduler
Composant sur le master qui surveille les pods nouvellement créés qui ne sont pas assignés à un nœud et sélectionne un nœud sur lequel ils vont s'exécuter.
Les facteurs pris en compte pour les décisions de planification (scheduling) comprennent les exigences individuelles et collectives en ressources, les contraintes matérielles/logicielles/politiques, les spécifications d'affinité et d'anti-affinité, la localité des données, les interférences entre charges de travail et les dates limites.
kube-controller-manager
Composant du master qui exécute les contrôleurs.
Logiquement, chaque contrôleur est un processus à part mais, pour réduire la complexité, les contrôleurs sont tous compilés dans un seul binaire et s'exécutent dans un seul processus.
Ces contrôleurs incluent :
- Node Controller : Responsable de détecter et apporter une réponse lorsqu'un nœud tombe en panne.
- Replication Controller : Responsable de maintenir le bon nombre de pods pour chaque objet ReplicationController dans le système.
- Endpoints Controller : Remplit les objets Endpoints (c'est-à-dire joint les Services et Pods).
- Service Account & Token Controllers : Créent des comptes par défaut et des jetons d'accès à l'API pour les nouveaux namespaces.
cloud-controller-manager
Le cloud-controller-manager exécute les contrôleurs qui interagissent avec les fournisseurs cloud sous-jacents. Le binaire du cloud-controller-manager est une fonctionnalité alpha introduite dans la version 1.6 de Kubernetes.
Le cloud-controller-manager exécute seulement les boucles spécifiques des fournisseurs cloud.
Vous devez désactiver ces boucles de contrôleurs dans le kube-controller-manager.
Vous pouvez désactiver les boucles de contrôleurs en définissant la valeur du flag --cloud-provider
à external
lors du démarrage du kube-controller-manager.
Le cloud-controller-manager permet au code du fournisseur cloud et au code de Kubernetes d'évoluer indépendamment l'un de l'autre. Dans des versions antérieures, le code de base de Kubernetes dépendait du code spécifique du fournisseur cloud pour la fonctionnalité. Dans des versions ultérieures, le code spécifique des fournisseurs cloud devrait être maintenu par les fournisseurs cloud eux-mêmes et lié au cloud-controller-manager lors de l'exécution de Kubernetes.
Les contrôleurs suivants ont des dépendances vers des fournisseurs cloud :
- Node Controller : Pour vérifier le fournisseur de cloud afin de déterminer si un nœud a été supprimé dans le cloud après avoir cessé de répondre
- Route Controller : Pour mettre en place des routes dans l'infrastructure cloud sous-jacente
- Service Controller : Pour créer, mettre à jour et supprimer les load balancers des fournisseurs cloud
- Volume Controller : Pour créer, attacher et monter des Volumes, et interagir avec le fournisseur cloud pour orchestrer les volumes.
Composants de nœud
Les composants de nœud (Node components) s'exécutent sur chaque nœud, en maintenant les pods en exécution et en fournissant l'environnement d'exécution Kubernetes.
kubelet
Un agent qui s'exécute sur chaque nœud du cluster. Il s'assure que les conteneurs fonctionnent dans un pod.
Le kubelet prend un ensemble de PodSpecs fournis par divers mécanismes et s'assure du fonctionnement et de la santé des conteneurs décrits dans ces PodSpecs. Le kubelet ne gère que les conteneurs créés par Kubernetes.
kube-proxy
kube-proxy est un proxy réseau qui s'exécute sur chaque nœud du cluster et implémente une partie du concept Kubernetes de Service.
kube-proxy maintient les règles réseau sur les nœuds. Ces règles réseau permettent une communication réseau vers les Pods depuis des sessions réseau à l'intérieur ou à l'extérieur du cluster.
kube-proxy utilise la couche de filtrage de paquets du système d'exploitation s'il y en a une et qu'elle est disponible. Sinon, kube-proxy transmet le trafic lui-même.
Container Runtime
L'environnement d'exécution de conteneurs est le logiciel responsable de l'exécution des conteneurs.
Kubernetes est compatible avec plusieurs environnements d'exécution de conteneur: Docker, containerd, cri-o, rktlet ainsi que toute implémentation de Kubernetes CRI (Container Runtime Interface).
Addons
Les addons utilisent les ressources Kubernetes (DaemonSet, Déploiement, etc)
pour implémenter des fonctionnalités cluster. Comme ces derniers fournissent des fonctionnalités au niveau
du cluster, les ressources dans des namespaces pour les addons appartiennent au namespace kube-system
.
Les addons sélectionnés sont décrits ci-dessous. Pour une liste étendue des addons disponibles, voir la page Addons.
DNS
Tandis que les autres addons ne sont pas strictement requis, tous les clusters Kubernetes devraient avoir un DNS cluster car de nombreux exemples en dépendent.
Le DNS Cluster est un serveur DNS, en plus des autres serveurs DNS dans votre environnement, qui sert les enregistrements DNS pour les services Kubernetes.
Les conteneurs démarrés par Kubernetes incluent automatiquement ce serveur DNS dans leurs recherches DNS.
Interface utilisateur Web (Dashboard)
Le Dashboard est une interface utilisateur web à but général pour les clusters Kubernetes. Il permet aux utilisateurs de gérer et de dépanner aussi bien des applications s'exécutant dans le cluster que le cluster lui-même.
La surveillance des ressources de conteneur
La surveillance des ressources de conteneur enregistre des métriques chronologiques génériques à propos des conteneurs dans une base de données centrale et fournit une interface utilisateur pour parcourir ces données.
Le logging au niveau cluster
Un mécanisme de logging au niveau cluster est chargé de sauvegarder les logs des conteneurs dans un magasin de logs central avec une interface de recherche/navigation.
A suivre
- En savoir plus sur les Nœuds
- En savoir plus sur kube-scheduler
- Lire la documentation officielle d'etcd
3.1.3 - Utilisation des objets Kubernetes
3.1.3.1 - Namespaces
Kubernetes prend en charge plusieurs clusters virtuels présents sur le même cluster physique. Ces clusters virtuels sont appelés namespaces (espaces de nommage en français).
Quand utiliser plusieurs namespaces
Les namespaces sont destinés à être utilisés dans les environnements ayant de nombreux utilisateurs répartis en plusieurs équipes ou projets. Pour les clusters de quelques dizaines d'utilisateurs, vous n'avez pas besoin d'utiliser de namespaces. Commencez à utiliser des namespaces lorsque vous avez besoin des fonctionnalités qu'ils fournissent.
Les namespaces sont des groupes de noms. Ils fournissent un modèle d'isolation de nommage des ressources. Les noms des ressources doivent être uniques dans un namespace, mais pas dans l'ensemble des namespaces. Les namespaces ne peuvent pas être imbriqués les uns dans les autres et chaque ressource Kubernetes ne peut se trouver que dans un seul namespace.
Les namespaces sont un moyen de répartir les ressources d'un cluster entre plusieurs utilisateurs (via quota de ressources).
Dans les futures versions de Kubernetes, les objets du même namespace auront les mêmes stratégies de contrôle d'accès par défaut.
Il n'est pas nécessaire d'utiliser plusieurs namespaces juste pour séparer des ressources légèrement différentes, telles que les versions du même logiciel: utiliser les labels pour distinguer les ressources dans le même namespace.
Utilisation des namespaces
La création et la suppression des namespaces sont décrites dans la Documentation du guide d'administration pour les namespaces.
kube-
, car il est réservé aux namespaces système de Kubernetes.
Affichage des namespaces
Dans un cluster vous pouvez lister les namespaces actuels à l'aide de :
kubectl get namespace
NAME STATUS AGE
default Active 1d
kube-node-lease Active 1d
kube-public Active 1d
kube-system Active 1d
Kubernetes démarre avec quatre namespaces initiaux:
default
Le namespace par défaut pour les objets sans mention d'autre namespacekube-system
Le namespace pour les objets créés par Kubernetes lui-mêmekube-public
Ce namespace est créé automatiquement et est visible par tous les utilisateurs (y compris ceux qui ne sont pas authentifiés). Ce namespace est principalement réservé à l'utilisation du cluster, au cas où certaines ressources devraient être disponibles publiquement dans l'ensemble du cluster. L'aspect public de ce namespace n'est qu'une convention, pas une exigence.kube-node-lease
Ce namespace contient les objets de bail associés à chaque nœud, ce qui améliore les performances des pulsations du nœud à mesure que le cluster évolue.
Définition du namespaces pour une requête
Pour définir le namespace pour une requête en cours, utilisez l'indicateur --namespace
.
Par exemple:
kubectl run nginx --image=nginx --namespace=<insert-namespace-name-here>
kubectl get pods --namespace=<insert-namespace-name-here>
Spécifier un namespace
Vous pouvez enregistrer de manière permanente le namespace à utiliser pour toutes les commandes kubectl à suivre.
kubectl config set-context --current --namespace=<insert-namespace-name-here>
# Validez-le
kubectl config view --minify | grep namespace:
Namespaces et DNS
Lorsque vous créez un Service, il crée une entrée DNS correspondante.
Cette entrée est de la forme <nom-service>.<nom-namespace>.svc.cluster.local
, ce qui signifie
que si un conteneur utilise simplement <nom-service>
, il résoudra le service qui
est local à son namespace. Ceci est utile pour utiliser la même configuration pour
plusieurs namespaces tels que le Développement, la Qualification et la Production. Si vous voulez naviguer
entre plusieurs namespaces, vous devez utiliser le nom de domaine complet (FQDN ou nom de domaine complètement qualifié en français).
Tous les objets ne se trouvent pas dans un namespace
La plupart des ressources Kubernetes (par exemple, pods, services, contrôleurs de réplication et autres) sont dans des namespaces. Cependant, les ressources de type namespace ne sont pas elles-mêmes dans un namespace. Et les ressources de bas niveau, telles que les nœuds et les volumes persistants, ne se trouvent dans aucun namespace.
Pour voir quelles ressources Kubernetes sont et ne sont pas dans un namespace:
# Dans un namespace
kubectl api-resources --namespaced=true
# Pas dans un namespace
kubectl api-resources --namespaced=false
A suivre
- En savoir plus sur créer un nouveau namespace.
- En savoir plus sur suppression d'un namespace.
3.2 - Architecture de Kubernetes
3.2.1 - Noeuds
Un nœud est une machine de travail dans Kubernetes, connue auparavant sous le nom de minion
.
Un nœud peut être une machine virtuelle ou une machine physique, selon le cluster.
Chaque nœud contient les services nécessaires à l'exécution de pods et est géré par les composants du master.
Les services sur un nœud incluent le container runtime, kubelet et kube-proxy.
Consultez la section Le Nœud Kubernetes dans le document de conception de l'architecture pour plus de détails.
Statut du nœud
Le statut d'un nœud contient les informations suivantes:
Chaque section est décrite en détail ci-dessous.
Adresses
L'utilisation de ces champs varie en fonction de votre fournisseur de cloud ou de votre configuration physique.
- HostName: Le nom d'hôte tel que rapporté par le noyau du nœud. Peut être remplacé via le paramètre kubelet
--hostname-override
. - ExternalIP: En règle générale, l'adresse IP du nœud pouvant être routé en externe (disponible de l'extérieur du cluster).
- InternalIP: En règle générale, l'adresse IP du nœud pouvant être routé uniquement dans le cluster.
Condition
Le champ conditions
décrit le statut de tous les nœuds Running
.
Node Condition | Description |
---|---|
OutOfDisk |
True si l'espace disponible sur le nœud est insuffisant pour l'ajout de nouveaux pods, sinon False |
Ready |
True si le noeud est sain et prêt à accepter des pods, False si le noeud n'est pas sain et n'accepte pas de pods, et Unknown si le contrôleur de noeud n'a pas reçu d'information du noeud depuis node-monitor-grace-period (la valeur par défaut est de 40 secondes) |
MemoryPressure |
True s'il existe une pression sur la mémoire du noeud, c'est-à-dire si la mémoire du noeud est faible; autrement False |
PIDPressure |
True s'il existe une pression sur le nombre de processus, c'est-à-dire s'il y a trop de processus sur le nœud; autrement False |
DiskPressure |
True s'il existe une pression sur la taille du disque, c'est-à-dire si la capacité du disque est faible; autrement False |
NetworkUnavailable |
True si le réseau pour le noeud n'est pas correctement configuré, sinon False |
La condition de noeud est représentée sous la forme d'un objet JSON. Par exemple, la réponse suivante décrit un nœud sain.
"conditions": [
{
"type": "Ready",
"status": "True"
}
]
Si le statut de l'état Ready reste Unknown
ou False
plus longtemps que pod-eviction-timeout
, un argument est passé au kube-controller-manager et les pods sur le nœud sont programmés pour être supprimés par le contrôleur du nœud.
Le délai d’expulsion par défaut est de cinq minutes..
Dans certains cas, lorsque le nœud est inaccessible, l'apiserver est incapable de communiquer avec le kubelet sur le nœud.
La décision de supprimer les pods ne peut pas être communiquée au kublet tant que la communication avec l'apiserver n'est pas rétablie.
Entre-temps, les pods dont la suppression est planifiée peuvent continuer à s'exécuter sur le nœud inaccessible.
Dans les versions de Kubernetes antérieures à 1.5, le contrôleur de noeud forcait la suppression de ces pods inaccessibles de l'apiserver.
Toutefois, dans la version 1.5 et ultérieure, le contrôleur de noeud ne force pas la suppression des pods tant qu'il n'est pas confirmé qu'ils ont cessé de fonctionner dans le cluster.
Vous pouvez voir que les pods en cours d'exécution sur un nœud inaccessible sont dans l'état Terminating
ou Unknown
.
Dans les cas où Kubernetes ne peut pas déduire de l'infrastructure sous-jacente si un nœud a définitivement quitté un cluster, l'administrateur du cluster peut avoir besoin de supprimer l'objet nœud à la main.
La suppression de l'objet nœud de Kubernetes entraîne la suppression de tous les objets Pod exécutés sur le nœud de l'apiserver et libère leurs noms.
Dans la version 1.12, la fonctionnalité TaintNodesByCondition
est promue en version bêta, ce qui permet au contrôleur de cycle de vie du nœud de créer automatiquement des marquages (taints en anglais) qui représentent des conditions.
De même, l'ordonnanceur ignore les conditions lors de la prise en compte d'un nœud; au lieu de cela, il regarde les taints du nœud et les tolérances d'un pod.
Les utilisateurs peuvent désormais choisir entre l'ancien modèle de planification et un nouveau modèle de planification plus flexible. Un pod qui n’a aucune tolérance est programmé selon l’ancien modèle. Mais un pod qui tolère les taints d'un nœud particulier peut être programmé sur ce nœud.
Capacité
Décrit les ressources disponibles sur le nœud: CPU, mémoire et nombre maximal de pods pouvant être planifiés sur le nœud.
Info
Informations générales sur le noeud, telles que la version du noyau, la version de Kubernetes (versions de kubelet et kube-proxy), la version de Docker (si utilisée), le nom du système d'exploitation. Les informations sont collectées par Kubelet à partir du noeud.
Gestion
Contrairement aux pods et aux [services] (/docs/concepts/services-networking/service/), un nœud n'est pas créé de manière inhérente par Kubernetes: il est créé de manière externe par un cloud tel que Google Compute Engine, ou bien il existe dans votre pool de machines physiques ou virtuelles. Ainsi, lorsque Kubernetes crée un nœud, il crée un objet qui représente le nœud. Après la création, Kubernetes vérifie si le nœud est valide ou non. Par exemple, si vous essayez de créer un nœud à partir du contenu suivant:
{
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "10.240.79.157",
"labels": {
"name": "my-first-k8s-node"
}
}
}
Kubernetes crée un objet noeud en interne (la représentation) et valide le noeud en vérifiant son intégrité en fonction du champ metadata.name
.
Si le nœud est valide, c'est-à-dire si tous les services nécessaires sont en cours d'exécution, il est éligible pour exécuter un pod.
Sinon, il est ignoré pour toute activité de cluster jusqu'à ce qu'il devienne valide.
Actuellement, trois composants interagissent avec l'interface de noeud Kubernetes: le contrôleur de noeud, kubelet et kubectl.
Contrôleur de nœud
Le contrôleur de noeud (node controller en anglais) est un composant du master Kubernetes qui gère divers aspects des noeuds.
Le contrôleur de nœud a plusieurs rôles dans la vie d'un nœud. La première consiste à affecter un bloc CIDR au nœud lorsqu’il est enregistré (si l’affectation CIDR est activée).
La seconde consiste à tenir à jour la liste interne des nœuds du contrôleur de nœud avec la liste des machines disponibles du fournisseur de cloud. Lorsqu'il s'exécute dans un environnement de cloud, chaque fois qu'un nœud est en mauvaise santé, le contrôleur de nœud demande au fournisseur de cloud si la machine virtuelle de ce nœud est toujours disponible. Sinon, le contrôleur de nœud supprime le nœud de sa liste de nœuds.
La troisième est la surveillance de la santé des nœuds. Le contrôleur de noeud est responsable de la mise à jour de la condition NodeReady de NodeStatus vers ConditionUnknown lorsqu'un noeud devient inaccessible (le contrôleur de noeud cesse de recevoir des heartbeats pour une raison quelconque, par exemple en raison d'une panne du noeud), puis de l'éviction ultérieure de tous les pods du noeud. (en utilisant une terminaison propre) si le nœud continue d’être inaccessible. (Les délais d'attente par défaut sont de 40 secondes pour commencer à signaler ConditionUnknown et de 5 minutes après cela pour commencer à expulser les pods.)
Le contrôleur de nœud vérifie l'état de chaque nœud toutes les --node-monitor-period
secondes.
Dans les versions de Kubernetes antérieures à 1.13, NodeStatus correspond au heartbeat du nœud.
À partir de Kubernetes 1.13, la fonctionnalité de bail de nœud (node lease en anglais) est introduite en tant que fonctionnalité alpha (feature gate NodeLease
, KEP-0009).
Lorsque la fonction de node lease est activée, chaque noeud a un objet Lease
associé dans le namespace kube-node-lease
qui est renouvelé périodiquement par le noeud, et NodeStatus et le node lease sont traités comme des heartbeat du noeud.
Les node leases sont renouvelés fréquemment lorsque NodeStatus est signalé de nœud à master uniquement lorsque des modifications ont été apportées ou que suffisamment de temps s'est écoulé (la valeur par défaut est 1 minute, ce qui est plus long que le délai par défaut de 40 secondes pour les nœuds inaccessibles).
Étant donné qu'un node lease est beaucoup plus léger qu'un NodeStatus, cette fonctionnalité rends le heartbeat d'un nœud nettement moins coûteux, tant du point de vue de l'évolutivité que des performances.
Dans Kubernetes 1.4, nous avons mis à jour la logique du contrôleur de noeud afin de mieux gérer les cas où un grand nombre de noeuds rencontrent des difficultés pour atteindre le master (par exemple parce que le master a un problème de réseau). À partir de la version 1.4, le contrôleur de noeud examine l’état de tous les noeuds du cluster lorsqu’il prend une décision concernant l’éviction des pods.
Dans la plupart des cas, le contrôleur de noeud limite le taux d’expulsion à --node-eviction-rate
(0,1 par défaut) par seconde, ce qui signifie qu’il n’expulsera pas les pods de plus d’un nœud toutes les 10 secondes.
Le comportement d'éviction de noeud change lorsqu'un noeud d'une zone de disponibilité donnée devient défaillant.
Le contrôleur de nœud vérifie quel pourcentage de nœuds de la zone est défaillant (la condition NodeReady est ConditionUnknown ou ConditionFalse) en même temps.
Si la fraction de nœuds défaillant est au moins --unhealthy-zone-threshold
(valeur par défaut de 0,55), le taux d'expulsion est réduit: si le cluster est petit (c'est-à-dire inférieur ou égal à --large-cluster-size-threshold
noeuds - valeur par défaut 50) puis les expulsions sont arrêtées, sinon le taux d'expulsion est réduit à --secondary-node-eviction-rate
(valeur par défaut de 0,01) par seconde.
Ces stratégies sont implémentées par zone de disponibilité car une zone de disponibilité peut être partitionnée à partir du master, tandis que les autres restent connectées. Si votre cluster ne s'étend pas sur plusieurs zones de disponibilité de fournisseur de cloud, il n'existe qu'une seule zone de disponibilité (la totalité du cluster).
L'une des principales raisons de la répartition de vos nœuds entre les zones de disponibilité est de pouvoir déplacer la charge de travail vers des zones saines lorsqu'une zone entière tombe en panne.
Par conséquent, si tous les nœuds d’une zone sont défaillants, le contrôleur de nœud expulse à la vitesse normale --node-eviction-rate
.
Le cas pathologique se produit lorsque toutes les zones sont complètement défaillantes (c'est-à-dire qu'il n'y a pas de nœuds sains dans le cluster).
Dans ce cas, le contrôleur de noeud suppose qu'il existe un problème de connectivité au master et arrête toutes les expulsions jusqu'à ce que la connectivité soit restaurée.
À partir de Kubernetes 1.6, NodeController est également responsable de l'expulsion des pods s'exécutant sur des noeuds avec des marques NoExecute
, lorsque les pods ne tolèrent pas ces marques.
De plus, en tant que fonctionnalité alpha désactivée par défaut, NodeController est responsable de l'ajout de marques correspondant aux problèmes de noeud tels que les noeuds inaccessibles ou non prêts.
Voir cette documentation pour plus de détails sur les marques NoExecute
et cette fonctionnalité alpha.
À partir de la version 1.8, le contrôleur de noeud peut être chargé de créer des tâches représentant les conditions de noeud. Ceci est une fonctionnalité alpha de la version 1.8.
Auto-enregistrement des nœuds
Lorsque l'indicateur de kubelet --register-node
est à true (valeur par défaut), le kubelet tente de s'enregistrer auprès du serveur d'API.
C'est le modèle préféré, utilisé par la plupart des distributions Linux.
Pour l'auto-enregistrement (self-registration en anglais), le kubelet est lancé avec les options suivantes:
--kubeconfig
- Chemin d'accès aux informations d'identification pour s'authentifier auprès de l'apiserver.--cloud-provider
- Comment lire les métadonnées d'un fournisseur de cloud sur lui-même.--register-node
- Enregistrement automatique avec le serveur API.--register-with-taints
- Enregistrez le noeud avec la liste donnée de marques (séparés par des virgules<key>=<value>:<effect>
). Sans effet siregister-node
est à false.--node-ip
- Adresse IP du noeud.--node-labels
- Labels à ajouter lors de l’enregistrement du noeud dans le cluster (voir Restrictions des labels appliquées par le plugin NodeRestriction admission dans les versions 1.13+).--node-status-update-frequency
- Spécifie la fréquence à laquelle kubelet publie le statut de nœud sur master.
Quand le mode autorisation de nœud et plugin NodeRestriction admission sont activés, les kubelets sont uniquement autorisés à créer / modifier leur propre ressource de noeud.
Administration manuelle de noeuds
Un administrateur de cluster peut créer et modifier des objets de nœud.
Si l'administrateur souhaite créer des objets de noeud manuellement, définissez l'argument de kubelet: --register-node=false
.
L'administrateur peut modifier les ressources du nœud (quel que soit le réglage de --register-node
).
Les modifications comprennent la définition de labels sur le nœud et son marquage comme non programmable.
Les étiquettes sur les nœuds peuvent être utilisées avec les sélecteurs de nœuds sur les pods pour contrôler la planification. Par exemple, pour contraindre un pod à ne pouvoir s'exécuter que sur un sous-ensemble de nœuds.
Marquer un nœud comme non planifiable empêche la planification de nouveaux pods sur ce nœud, mais n'affecte pas les pods existants sur le nœud. Ceci est utile comme étape préparatoire avant le redémarrage d'un nœud, etc. Par exemple, pour marquer un nœud comme non programmable, exécutez la commande suivante:
kubectl cordon $NODENAME
Capacité de nœud
La capacité du nœud (nombre de CPU et quantité de mémoire) fait partie de l’objet Node. Normalement, les nœuds s'enregistrent et indiquent leur capacité lors de la création de l'objet Node. Si vous faites une administration manuelle de nœud, alors vous devez définir la capacité du nœud lors de l'ajout d'un nœud.
Le scheduler Kubernetes veille à ce qu'il y ait suffisamment de ressources pour tous les pods d'un noeud. Il vérifie que la somme des demandes des conteneurs sur le nœud n'est pas supérieure à la capacité du nœud. Cela inclut tous les conteneurs lancés par le kubelet, mais pas les conteneurs lancés directement par le conteneur runtime, ni aucun processus exécuté en dehors des conteneurs.
Si vous souhaitez réserver explicitement des ressources pour des processus autres que Pod, suivez ce tutoriel pour: réserver des ressources pour les démons système.
API Object
L'objet Node est une ressource de niveau supérieur dans l'API REST de Kubernetes. Plus de détails sur l'objet API peuvent être trouvés à l'adresse suivante: Node API object.
3.2.2 - Communication Master-Node
Ce document répertorie les canaux de communication entre l'API du noeud maître (apiserver of master node en anglais) et le reste du cluster Kubernetes. L'objectif est de permettre aux utilisateurs de personnaliser leur installation afin de sécuriser la configuration réseau, de sorte que le cluster puisse être exécuté sur un réseau non approuvé (ou sur des adresses IP entièrement publiques d'un fournisseur de cloud).
Communication du Cluster vers le Master
Tous les canaux de communication du cluster au master se terminent à l'apiserver (aucun des autres composants principaux n'est conçu pour exposer des services distants). Dans un déploiement typique, l'apiserver est configuré pour écouter les connexions distantes sur un port HTTPS sécurisé (443) avec un ou plusieurs types d'authentification client. Une ou plusieurs formes d'autorisation devraient être activées, notamment si les requêtes anonymes ou jeton de compte de service sont autorisés.
Le certificat racine public du cluster doit être configuré pour que les nœuds puissent se connecter en toute sécurité à l'apiserver avec des informations d'identification client valides. Par exemple, dans un déploiement GKE par défaut, les informations d'identification client fournies au kubelet sont sous la forme d'un certificat client. Consultez amorçage TLS de kubelet pour le provisioning automatisé des certificats de client Kubelet.
Les pods qui souhaitent se connecter à l'apiserver peuvent le faire de manière sécurisée en utilisant un compte de service afin que Kubernetes injecte automatiquement le certificat racine public et un jeton de support valide dans le pod lorsqu'il est instancié.
Le service kubernetes
(dans tous les namespaces) est configuré avec une adresse IP virtuelle redirigée (via kube-proxy) vers le point de terminaison HTTPS sur l'apiserver.
Les composants du master communiquent également avec l'apiserver du cluster via le port sécurisé.
Par conséquent, le mode de fonctionnement par défaut pour les connexions du cluster (nœuds et pods s'exécutant sur les nœuds) au master est sécurisé par défaut et peut s'exécuter sur des réseaux non sécurisés et/ou publics.
Communication du Master vers le Cluster
Il existe deux voies de communication principales du master (apiserver) au cluster. La première est du processus apiserver au processus kubelet qui s'exécute sur chaque nœud du cluster. La seconde part de l'apiserver vers n'importe quel nœud, pod ou service via la fonctionnalité proxy de l'apiserver.
Communication de l'apiserver vers le kubelet
Les connexions de l'apiserver au kubelet sont utilisées pour:
- Récupérer les logs des pods.
- S'attacher (via kubectl) à des pods en cours d'exécution.
- Fournir la fonctionnalité de transfert de port du kubelet.
Ces connexions se terminent au point de terminaison HTTPS du kubelet. Par défaut, l'apiserver ne vérifie pas le certificat du kubelet, ce qui rend la connexion sujette aux attaques de type "man-in-the-middle", et non sûre sur des réseaux non approuvés et/ou publics.
Pour vérifier cette connexion, utilisez l'argument --kubelet-certificate-authority
pour fournir à l'apiserver un ensemble de certificats racine à utiliser pour vérifier le certificat du kubelet.
Si ce n'est pas possible, utilisez SSH tunneling entre l'apiserver et le kubelet si nécessaire pour éviter la connexion sur un réseau non sécurisé ou public.
Finalement, l'authentification et/ou autorisation du Kubelet devrait être activée pour sécuriser l'API kubelet.
apiserver vers nodes, pods et services
Les connexions de l'apiserver à un nœud, à un pod ou à un service sont définies par défaut en connexions HTTP.
Elles ne sont donc ni authentifiées ni chiffrées.
Elles peuvent être exécutées sur une connexion HTTPS sécurisée en préfixant https:
au nom du nœud, du pod ou du service dans l'URL de l'API.
Cependant ils ne valideront pas le certificat fourni par le point de terminaison HTTPS ni ne fourniront les informations d'identification du client.
De plus, aucune garantie d'intégrité n'est fournie.
Ces connexions ne sont actuellement pas sûres pour fonctionner sur des réseaux non sécurisés et/ou publics.
SSH Tunnels
Kubernetes prend en charge les tunnels SSH pour protéger les communications master -> cluster. Dans cette configuration, l'apiserver initie un tunnel SSH vers chaque nœud du cluster (en se connectant au serveur ssh sur le port 22) et transmet tout le trafic destiné à un kubelet, un nœud, un pod ou un service via un tunnel. Ce tunnel garantit que le trafic n'est pas exposé en dehors du réseau dans lequel les nœuds sont en cours d'exécution.
Les tunnels SSH étant actuellement obsolètes, vous ne devriez pas choisir de les utiliser à moins de savoir ce que vous faites. Un remplacement pour ce canal de communication est en cours de conception.
3.2.3 - Concepts sous-jacents au Cloud Controller Manager
Le concept de cloud controller manager (CCM) (ne pas confondre avec le binaire) a été créé à l'origine pour permettre au code de fournisseur spécifique de cloud et au noyau Kubernetes d'évoluer indépendamment les uns des autres. Le gestionnaire de contrôleur de cloud fonctionne aux côtés d'autres composants principaux, tels que le gestionnaire de contrôleur Kubernetes, le serveur d'API et le planificateur. Il peut également être démarré en tant qu’addon Kubernetes, auquel cas il s’exécute sur Kubernetes.
La conception du gestionnaire de contrôleur de cloud repose sur un mécanisme de plugin qui permet aux nouveaux fournisseurs de cloud de s'intégrer facilement à Kubernetes à l'aide de plugins. Des plans sont en place pour intégrer de nouveaux fournisseurs de cloud sur Kubernetes et pour migrer les fournisseurs de cloud de l'ancien modèle vers le nouveau modèle CCM.
Ce document discute des concepts derrière le cloud controller manager et donne des détails sur ses fonctions associées.
Voici l'architecture d'un cluster Kubernetes sans le cloud controller manager:
Conception
Dans le diagramme précédent, Kubernetes et le fournisseur de cloud sont intégrés via plusieurs composants différents:
- Kubelet
- Kubernetes controller manager
- Kubernetes API server
Le CCM consolide toute la logique dépendante du cloud des trois composants précédents pour créer un point d’intégration unique avec le cloud. La nouvelle architecture avec le CCM se présente comme suit:
Composants du CCM
Le CCM rompt certaines fonctionnalités du Kubernetes Controller Manager (KCM) et les exécute en tant que processus séparé. Plus précisément, il sépare les contrôleurs du KCM qui dépendent du cloud. Le KCM comporte les boucles de contrôle dépendant du cloud suivantes:
- Contrôleur de nœud
- Contrôleur de volume
- Contrôleur de route
- Contrôleur de service
Dans la version 1.9, le CCM exécute les contrôleurs suivants de la liste précédente:
- Contrôleur de nœud
- Contrôleur de route
- Contrôleur de service
Le plan initial de prise en charge des volumes à l'aide de CCM consistait à utiliser des volumes Flex pour prendre en charge des volumes pouvant être connectés. Cependant, un effort concurrentiel appelé CSI est prévu pour remplacer Flex.
Compte tenu de cette dynamique, nous avons décidé d'avoir une mesure de transition intermédiaire jusqu'à ce que le CSI soit prêt.
Fonctions du CCM
Le CCM hérite ses fonctions des composants de Kubernetes qui dépendent d'un fournisseur de cloud. Cette section est structurée en fonction de ces composants.
1. Kubernetes controller manager
La majorité des fonctions du CCM sont dérivées du KCM. Comme indiqué dans la section précédente, le CCM exécute les boucles de contrôle suivantes:
- Contrôleur de nœud
- Contrôleur de route
- Contrôleur de service
Contrôleur de nœud
Le contrôleur de noeud est responsable de l'initialisation d'un noeud en obtenant des informations sur les noeuds s'exécutant dans le cluster auprès du fournisseur de cloud. Le contrôleur de noeud exécute les fonctions suivantes:
- Il initialise le nœud avec des labels de zone/région spécifiques au cloud.
- Il initialise le nœud avec des détails d'instance spécifiques au cloud, tels que le type et la taille de l'instance.
- Il obtient les adresses réseau et le nom d'hôte du nœud.
- Si un nœud ne répond plus, le controlleur vérifie avec le cloud pour voir s'il a été supprimé du cloud. Si le nœud a été supprimé du cloud, le controlleur supprime l'objet Kubernetes Node.
Contrôleur de route
Le contrôleur de route est responsable de la configuration appropriée des itinéraires dans le cloud afin que les conteneurs situés sur différents nœuds du cluster Kubernetes puissent communiquer entre eux. Le contrôleur de route ne s'applique qu'aux clusters Google Compute Engine.
Contrôleur de service
Le contrôleur de service est chargé d'écouter les événements de création, de mise à jour et de suppression de service. En fonction de l'état actuel des services dans Kubernetes, il configure les équilibreurs de charge dans le cloud (tels que ELB, Google LB ou Oracle Cloud Infrastructure LB) pour refléter l'état des services dans Kubernetes. De plus, cela garantit que les services de base des services pour les load balancers dans le cloud sont à jour.
2. Kubelet
Le contrôleur de noeud contient les fonctionnalités du kubelet dépendant du cloud. Avant l'introduction du CCM, la sous-unité était responsable de l'initialisation d'un nœud avec des détails spécifiques au cloud, tels que les adresses IP, les étiquettes de région / zone et les informations de type d'instance. L’introduction du CCM a déplacé cette opération d’initialisation du kubelet vers le CCM.
Dans ce nouveau modèle, le kubelet initialise un nœud sans informations spécifiques au cloud. Cependant, il ajoute un marquage au nœud nouvellement créé, qui rend le nœud non planifiable jusqu'à ce que le CCM initialise le nœud avec des informations spécifiques au cloud. Il supprime ensuite ce marquage.
Mécanisme de plugin
Le cloud controller manager utilise des interfaces Go pour autoriser la mise en œuvre d'implémentations depuis n'importe quel cloud. Plus précisément, il utilise l'interface CloudProvider définie ici.
La mise en œuvre des quatre contrôleurs partagés soulignés ci-dessus, ainsi que certaines configurations ainsi que l'interface partagée du fournisseur de cloud, resteront dans le noyau Kubernetes. Les implémentations spécifiques aux fournisseurs de cloud seront construites en dehors du noyau et implémenteront les interfaces définies dans le noyau.
Pour plus d’informations sur le développement de plugins, consultez Developing Cloud Controller Manager.
Autorisation
Cette section détaille les accès requis par le CCM sur divers objets API pour effectuer ses opérations.
Contrôleur de nœud
Le contrôleur de noeud ne fonctionne qu'avec les objets de noeud. Il nécessite un accès complet aux objets Node via get, list, create, update, patch, watch et delete.
v1/Node:
- Get
- List
- Create
- Update
- Patch
- Watch
- Delete
Contrôleur de route
Le contrôleur de route écoute les évenements de création d'objet Node et configure les routes de manière appropriée. Cela nécessite un accès get aux objets Node.
v1/Node:
- Get
Contrôleur de Service
Le contrôleur de service écoute les évenements de création, suppression et mises à jour des objets Service et configure les endpoints pour ces Services de manière appropriée.
Pour accéder aux Services, il faut les accès list et watch. Pour mettre à jour les Services, il faut les accès patch et update.
Pour configurer des points de terminaison pour les services, vous devez avoir accès au create, list, get, watch, et update.
v1/Service:
- List
- Get
- Watch
- Patch
- Update
Autres
La mise en œuvre du CCM nécessite un accès pour créer des événements, et pour garantir un fonctionnement sécurisé, un accès est nécessaire pour créer ServiceAccounts.
v1/Event:
- Create
- Patch
- Update
v1/ServiceAccount:
- Create
Le ClusterRole RBAC pour le CCM ressemble à ceci:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cloud-controller-manager
rules:
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- update
- apiGroups:
- ""
resources:
- nodes
verbs:
- '*'
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
- apiGroups:
- ""
resources:
- services
verbs:
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- create
- apiGroups:
- ""
resources:
- persistentvolumes
verbs:
- get
- list
- update
- watch
- apiGroups:
- ""
resources:
- endpoints
verbs:
- create
- get
- list
- watch
- update
Implémentations des fournisseurs de cloud
Les fournisseurs de cloud suivants ont implémenté leur CCM:
Administration de cluster
Des instructions complètes pour la configuration et l'exécution du CCM sont fournies ici.
3.3 - Les conteneurs
3.3.1 - Images
Vous créez une image Docker et la poussez dans un registre avant de la référencer depuis un pod Kubernetes.
La propriété image
d'un conteneur utilise la même syntaxe que la commande docker
, y compris pour les registres privés et les tags.
Mettre à jour des images
La politique de récupération par défaut est IfNotPresent
, Kubelet ne récupère alors pas une image si elle est déjà présente sur le nœud.
Si vous voulez forcer une récupération à chaque fois, vous pouvez faire une des actions suivantes :
- définissez
imagePullPolicy
du conteneur àAlways
. - omettez
imagePullPolicy
et utilisez:latest
comme tag pour l'image à utiliser. - omettez
imagePullPolicy
et le tag de l'image à utiliser. - activez l'admission controller AlwaysPullImages.
Notez que vous devez éviter d'utiliser le tag :latest
, voir Bonnes pratiques pour la configuration pour plus d'informations.
Créer des images multi-architecture à partir de manifestes
La CLI Docker prend maintenant en charge la commande docker manifest
avec des sous-commandes comme create
, annotate
et push
. Ces commandes peuvent être utilisées pour construire et pousser les manifestes. Vous pouvez utiliser docker manifest inspect
pour voir le manifeste.
Vous pouvez voir la documentation Docker ici : https://docs.docker.com/edge/engine/reference/commandline/manifest/
Voici comment nous l'utilisons dans notre outil de build: https://cs.k8s.io/?q=docker%20manifest%20(create%7Cpush%7Cannotate)&i=nope&files=&repos=
Ces commandes se basent et sont implémentées purement sur la CLI Docker. Vous devrez soit éditer $HOME/.docker/config.json
et définir la clé experimental
à enabled
ou vous pouvez simplement définir la variable d'environnement DOCKER_CLI_EXPERIMENTAL
à enabled
lorsque vous appelez les commandes de la CLI.
experimental
pour la ligne de commande. Par exemple https://github.com/docker/cli/issues/1135 cause des problèmes sous containerd
.
Si vous avez des problèmes en téléchargeant des manifestes viciés, nettoyez les anciens manifestes dans $HOME/.docker/manifests
pour recommencer de zéro.
Pour Kubernetes, nous avons historiquement utilisé des images avec des suffixes -$(ARCH)
. Pour une rétrocompatibilité, veuillez générer les anciennes images avec des suffixes. Par exemple, l'image pause
qui a le manifeste pour toutes les architetures et l'image pause-amd64
qui est rétrocompatible
pour d'anciennes configurations ou des fichiers YAML qui auraient codé en dur les images avec des suffixes.
Utiliser un registre privé
Les registres privés peuvent demander des clés pour pouvoir lire leurs images.
Ces certificats peuvent être fournis de différentes manières :
- En utilisant la Google Container Registry
- par cluster
- automatiqueent configuré dans Google Compute Engine ou Google Kubernetes Engine
- tous les pods peuvent lire le registre privé du projet
- En utilisant Amazon Elastic Container Registry (ECR)
- utilise les rôles et politiques IAM pour contrôler l'accès aux dépôts ECR
- rafraîchit automatiquement les certificats de login ECR
- En utilisant Oracle Cloud Infrastructure Registry (OCIR)
- utilise les rôles et politiques IAM pour contrôler l'accès aux dépôts OCIR
- En utilisant Azure Container Registry (ACR)
- En utilisant IBM Cloud Container Registry
- utilise les rôles et politiques IAM pour contrôler l'accès à l'IBM Cloud Container Registry
- En configurant les nœuds pour s'authentifier auprès d'un registre privé
- tous les pods peuvent lire les registres privés configurés
- nécessite la configuration des nœuds par un administrateur du cluster
- En utilisant des images pré-chargées
- tous les pods peuvent utiliser toutes les images mises en cache sur un nœud
- nécessite l'accès root à tous les nœuds pour la mise en place
- En spécifiant ImagePullSecrets dans un Pod
- seuls les pods fournissant ses propres clés peuvent accéder au registre privé
Chaque option est décrite plus en détails ci-dessous.
Utiliser la Google Container Registry
Kubernetes prend en charge nativement la Google Container Registry (GCR), lorsqu'il s'exécute dans Google Compute Engine (GCE). Si vous exécutez votre cluster dans GCE ou Google Kubernetes Engine, utilisez simplement le nom complet de l'image (par ex. gcr.io/my_project/image:tag).
Tous les pods dans un cluster auront un accès en lecture aux images dans le registre.
Kubelet va s'authentifier auprès de GCR en utilisant le compte de service Google de l'instance.
Le compte de service dans l'instance aura un https://www.googleapis.com/auth/devstorage.read_only
,
afin qu'il puisse récupérer depuis le GCR du projet mais qu'il ne puisse pas pousser une image.
Utiliser Amazon Elastic Container Registry
Kubernetes prend en charge nativement Amazon Elastic Container Registry, lorsque les nœuds sont des instances de AWS EC2.
Utilisez simplement le nom complet de l'image (par ex. ACCOUNT.dkr.ecr.REGION.amazonaws.com/imagename:tag
)
dans la définition du Pod.
Tous les utilisateurs du cluster qui peuvent créer des pods auront la possibilité d'exécuter des pods qui utilisent n'importe quelle image du registre ECR.
Kubelet va aller chercher et rafraîchir périodiquement les certificats ECR. Les permissions suivantes sont requises par kubelet :
ecr:GetAuthorizationToken
ecr:BatchCheckLayerAvailability
ecr:GetDownloadUrlForLayer
ecr:GetRepositoryPolicy
ecr:DescribeRepositories
ecr:ListImages
ecr:BatchGetImage
Exigences :
- Vous devez utiliser kubelet version
v1.2.0
ou ultérieure. (exécutez par ex./usr/bin/kubelet --version=true
). - Si vos nœuds sont dans une région différente de votre registre, vous devez utiliser la version
v1.3.0
ou ultérieure. - ECR doit être disponible dans votre région.
Dépannage :
- Vérifiez toutes les exigences ci-dessus.
- Copiez les certificats de $REGION (par ex.
us-west-2
) sur votre poste de travail. Connectez-vous en SSH sur l'hôte et exécutez Docker manuellement avec ces certificats. Est-ce que ça marche ? - Vérifiez que kubelet s'exécute avec
--cloud-provider=aws
. - Augmentez la verbosité des logs de kubelet à au moins 3 et recherchez dans les logs de kubelet (par exemple avec
journalctl -u kubelet
) des lignes similaires à :
-
aws_credentials.go:109] unable to get ECR credentials from cache, checking ECR API
-
aws_credentials.go:116] Got ECR credentials from ECR API for <AWS account ID for ECR>.dkr.ecr.<AWS region>.amazonaws.com
Utiliser Azure Container Registry (ACR)
En utilisant Azure Container Registry vous pouvez vous authentifier en utilisant soit un utilisateur admin soit un service principal. Dans les deux cas, l'authentification est faite via l'authentification standard de Docker. Ces instructions assument l'outil en ligne de commande azure-cli.
Vous devez d'abord créer un registre et générer des certificats, la documentation complète pour cela peut être touvée dans la documentation de Azure container registry.
Une fois votre registre de conteneurs créé, vous utiliserez les certificats suivants pour vous connecter :
DOCKER_USER
: service principal ou utilisateur adminDOCKER_PASSWORD
: mot de passe du service principal ou utilisateur adminDOCKER_REGISTRY_SERVER
:${un-nom-de-registre}.azurecr.io
DOCKER_EMAIL
:${une-adresse-email}
Une fois que vous avez défini ces variables, vous pouvez configurer un Secret Kubernetes et l'utiliser pour déployer un Pod.
Utiliser IBM Cloud Container Registry
IBM Cloud Container Registry fournit un registre d'images multi-tenant privé que vous pouvez utiliser pour stocker et partager de manière sécurisée vos images. Par défaut, les images de votre registre privé sont scannées par le Vulnerability Advisor intégré pour détecter des failles de sécurité et des vulnérabilités potentielles. Les utilisateurs de votre compte IBM Cloud peuvent accéder à vos images, ou vous pouvez des rôles et politiques IAM pour fournir l'accès aux namespaces de l'IBM Cloud Container Registry.
Pour installer le plugin du CLI de IBM Cloud Container Registry et créer un namespace pour vos images, voir Débuter avec IBM Cloud Container Registry.
Si vous utilisez le même compte et la même région, vous pouvez déployer des images stockées dans IBM Cloud Container Registry vers la namespace default
de votre cluster IBM Cloud Kubernetes Service sans configuration supplémentaire, voir Construire des conteneurs à partir d'images. Pour les autres options de configuration, voir Comprendre comment autoriser votre cluster à télécharger des images depuis un registre.
Configurer les nœuds pour s'authentifier auprès d'un registre privé
.dockercfg
sur chaque nœud avec les certificats pour Google Container Registry. Vous ne pourrez pas utiliser cette méthode.
auths
et HttpHeaders
de la config docker. Cela veut dire que les aides aux certificats (credHelpers
ou credsStore
) ne sont pas pris en charge.
Docker stocke les clés pour les regisres privés dans le fichier $HOME/.dockercfg
ou $HOME/.docker/config.json
. Si vous placez le même fichier dans un des chemins de recherche ci-dessous, kubelet l'utilise comme fournisseur de clés lorsque les images sont récupérées.
{--root-dir:-/var/lib/kubelet}/config.json
{cwd of kubelet}/config.json
${HOME}/.docker/config.json
/.docker/config.json
{--root-dir:-/var/lib/kubelet}/.dockercfg
{cwd of kubelet}/.dockercfg
${HOME}/.dockercfg
/.dockercfg
HOME=/root
explicitement dans votre fichier d'environnement pour kubelet.
Voici les étapes recommandées pour configurer vos nœuds pour qu'ils utilisent un registre privé. Dans cet exemple, exécutez-les sur votre poste de travail :
- Exécutez
docker login [server]
pour chaque jeu de certificats que vous désirez utiliser. Ceci met à jour$HOME/.docker/config.json
. - Examinez
$HOME/.docker/config.json
dans un éditeur pour vous assurer qu'il contient uniquement les certificats que vous désirez utiliser. - Récupérez la liste de vos nœuds, par exemple :
- si vous voulez connaître les noms :
nodes=$(kubectl get nodes -o jsonpath='{range.items[*].metadata}{.name} {end}')
- si vous voulez connaître les IPs :
nodes=$(kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type=="ExternalIP")]}{.address} {end}')
- si vous voulez connaître les noms :
- Copiez votre fichier
.docker/config.json
local dans un des chemins de recherche ci-dessus.- par exemple :
for n in $nodes; do scp ~/.docker/config.json root@$n:/var/lib/kubelet/config.json; done
- par exemple :
Vérifiez en créant un pod utilisant une image privée, par ex. :
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: test-image-privee-1
spec:
containers:
- name: utilise-image-privee
image: $NOM_IMAGE_PRIVEE
imagePullPolicy: Always
command: [ "echo", "SUCCESS" ]
EOF
pod/test-image-privee-1 created
Si tout fonctionne, alors, après quelques instants, vous pouvez exécuter :
kubectl logs test-image-privee-1
et voir que la commande affiche :
SUCCESS
Si vous suspectez que la commande a échouée, vous pouvez exécuter :
kubectl describe pods/test-image-privee-1 | grep 'Failed'
En cas d'échec, l'affichage sera similaire à :
Fri, 26 Jun 2015 15:36:13 -0700 Fri, 26 Jun 2015 15:39:13 -0700 19 {kubelet node-i2hq} spec.containers{uses-private-image} failed Failed to pull image "user/privaterepo:v1": Error: image user/privaterepo:v1 not found
Vous devez vous assurer que tous les nœuds du cluster ont le même fichier .docker/config.json
. Dans le cas contraire, les pods vont s'exécuter sur certains nœuds et échouer sur d'autres. Par exemple, si vous utilisez l'autoscaling des nœuds, alors chaque modèle d'instance doit inclure le fichier .docker/config.json
ou monter un disque le contenant.
Tous les pods auront un accès en lecture aux images d'un registre privé dès que les clés du registre privé sont ajoutées au fichier .docker/config.json
.
Images pré-chargées
.dockercfg
sur chaque nœud avec les certificats pour Google Container Registry. Vous ne pourrez pas utiliser cette méthode.
Par défaut, kubelet essaiera de récupérer chaque image depuis le registre spécifié.
Cependant, si la propriété imagePullPolicy
du conteneur est IfNotPresent
ou Never
,
alors une image locale est utilisée (respectivement de préférence ou exclusivement).
Si vous désirez vous reposer sur des images pré-chargées pour éviter l'authentification à un registre, vous devez vous assurer que tous les nœuds du cluster ont les mêmes images pré-chargées.
Ceci peut être utilisé pour pré-charger certaines images pour gagner du temps, ou comme une alternative à l'authentification à un registre privé.
Tous les pods auront un accès en lecture aux images pré-chargées.
Spécifier ImagePullSecrets dans un Pod
Kubernetes permet de spécifier des clés de registre dans un pod.
Créer un Secret avec une config Docker
Exécutez la commande suivante, en substituant les valeurs en majuscule :
kubectl create secret docker-registry <name> --docker-server=SERVEUR_REGISTRE_DOCKER --docker-username=UTILISATEUR_DOCKER --docker-password=MOT_DE_PASSE_DOCKER --docker-email=EMAIL_DOCKER
secret/myregistrykey created.
Si vous avez déjà un fichier de clés Docker, alors, plutôt que d'utiliser la commande ci-dessus,
vous pouvez importer le fichier de clés comme un Secret Kubernetes.
Créer un Secret basé sur des clés Docker existantes explique comment s'y prendre.
Ceci est particulièrement utile si vous utilisez plusieurs registres privés, kubectl create secret docker-registry
créant un Secret ne fonctionnant qu'avec un seul registre privé.
Se référer à un imagePullSecrets dans un Pod
Vous pouvez maintenant créer des pods qui référencent ce secret en ajoutant une section imagePullSecrets
dans la définition du pod.
cat <<EOF > pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: foo
namespace: awesomeapps
spec:
containers:
- name: foo
image: janedoe/awesomeapp:v1
imagePullSecrets:
- name: myregistrykey
EOF
cat <<EOF >> ./kustomization.yaml
resources:
- pod.yaml
EOF
Ceci doit être fait pour chaque pod utilisant un registre privé.
Cependant, la définition de ce champ peut être automatisé en définissant imagePullSecrets
dans une ressource serviceAccount.
Voyez Ajouter un ImagePullSecrets à un Service Account pour des instructions détaillées.
Vous pouvez utiliser cette méthode en conjonction avec un .docker/config.json
par nœud. Les certificats seront alors regroupés. Cette approche fonctionnera dans Google Kubernetes Engine.
Cas d'utilisation
Il y a plusieurs solutions pour configurer des registres privés. Voici quelques cas d'utilisation classiques et des propositions de solutions.
- Cluster exécutant uniquement des images non propriétaires (par ex. open-source). Inutile de protéger les images.
- Utilisez des images publiques dans le Hub Docker.
- Pas de configuration requise.
- Dans GCE/Google Kubernetes Engine, un miroir local est automatiquement utilisé pour améliorer la vitesse et la disponibilité.
- Utilisez des images publiques dans le Hub Docker.
- Cluster exécutant quelques images propriétaires qui doivent être protégées de l'extérieur de l'entreprise, mais visibles pour tous les utilisteurs du cluster.
- Utilisez un registre Docker hébergé privé.
- Il peut être hébergé sur le Hub Docker, ou ailleurs.
- Configurez manuellement .docker/config.json sur caque nœud comme décrit ci-dessus.
- Ou, utilisez un registre privé interne derrière votre pare-feu avec un accès ouvert en lecture.
- Aucune configuration Kubernetes n'est nécessaire.
- Ou, dans GCE/Google Kubernetes Engine, utilisez le Google Container Registry du projet.
- Cela fonctionnera mieux pour l'autoscaling du cluster que la configuration manuelle des nœuds.
- Ou, dans un cluster où le changement de la configuration des nœuds est difficile, utilisez
imagePullSecrets
.
- Utilisez un registre Docker hébergé privé.
- Cluster avec des images propriétaires, dont quelques-unes nécessitent un contrôle d'accès plus strict.
- Assurez-vous que l'admission controller AlwaysPullImages est actif. Autrement, tous les Pods ont potentiellement accès à toutes les images.
- Déplacez les données sensibles dans une ressource "Secret", plutôt que de les intégrer dans une image.
- Un cluster multi-tenant où chaque tenant doit avoir son propre registre privé.
- Assurez-vous que l'admission controller AlwaysPullImages est actif. Autrement, tous les Pods ont potentiellement accès à toutes les images.
- Utilisez un registre privé nécessitant l'autorisation.
- Générez des certificats de registre pour chaque tenant, placez-les dans des secrets, et placez ces secrets dans les namespaces de chaque tenant. pod - Le tenant ajoute ce secret dans les imagePullSecrets de chaque pod.
Si vous devez accéder à plusieurs registres, vous pouvez créer un secret pour chaque registre.
Kubelet va fusionner tous les imagePullSecrets
dans un unique .docker/config.json
virtuel.
3.3.2 - Classe d'exécution (Runtime Class)
Kubernetes v1.12 [alpha]
Cette page décrit la ressource RuntimeClass et le mécanisme de sélection d'exécution (runtime).
Runtime Class
La RuntimeClass est une fonctionnalité alpha permettant de sélectionner la configuration d'exécution du conteneur à utiliser pour exécuter les conteneurs d'un pod.
Installation
En tant que nouvelle fonctionnalité alpha, certaines étapes de configuration supplémentaires doivent être suivies pour utiliser la RuntimeClass:
- Activer la fonctionnalité RuntimeClass (sur les apiservers et les kubelets, nécessite la version 1.12+)
- Installer la RuntimeClass CRD
- Configurer l'implémentation CRI sur les nœuds (dépend du runtime)
- Créer les ressources RuntimeClass correspondantes
1. Activer RuntimeClass feature gate (portail de fonctionnalité)
Voir Feature Gates pour une explication
sur l'activation des feature gates. La RuntimeClass
feature gate doit être activée sur les API servers et
les kubelets.
2. Installer la CRD RuntimeClass
La RuntimeClass CustomResourceDefinition (CRD) se trouve dans le répertoire addons du dépôt Git Kubernetes: kubernetes/cluster/addons/runtimeclass/runtimeclass_crd.yaml
Installer la CRD avec kubectl apply -f runtimeclass_crd.yaml
.
3. Configurer l'implémentation CRI sur les nœuds
Les configurations à sélectionner avec RuntimeClass dépendent de l'implémentation CRI. Consultez la documentation correspondante pour votre implémentation CRI pour savoir comment le configurer. Comme c'est une fonctionnalité alpha, tous les CRI ne prennent pas encore en charge plusieurs RuntimeClasses.
Les configurations ont un nom RuntimeHandler
correspondant , référencé par la RuntimeClass.
Le RuntimeHandler doit être un sous-domaine DNS valide selon la norme RFC 1123 (alphanumériques + -
et .
caractères).
4. Créer les ressources RuntimeClass correspondantes
Les configurations effectuées à l'étape 3 doivent chacune avoir un nom RuntimeHandler
associé, qui
identifie la configuration. Pour chaque RuntimeHandler (et optionellement les handlers vides ""
),
créez un objet RuntimeClass correspondant.
La ressource RuntimeClass ne contient actuellement que 2 champs significatifs: le nom RuntimeClass
(metadata.name
) et le RuntimeHandler (spec.runtimeHandler
). la définition de l'objet ressemble à ceci:
apiVersion: node.k8s.io/v1alpha1 # La RuntimeClass est définie dans le groupe d'API node.k8s.io
kind: RuntimeClass
metadata:
name: myclass # Le nom avec lequel la RuntimeClass sera référencée
# La RuntimeClass est une ressource non cantonnées à un namespace
spec:
runtimeHandler: myconfiguration # Le nom de la configuration CRI correspondante
Usage
Une fois que les RuntimeClasses sont configurées pour le cluster, leur utilisation est très simple.
Spécifiez runtimeClassName
dans la spécficiation du pod. Par exemple:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
runtimeClassName: myclass
# ...
Cela indiquera à la kubelet d'utiliser la RuntimeClass spécifiée pour exécuter ce pod. Si la
RuntimeClass n'existe pas, ou si la CRI ne peut pas exécuter le handler correspondant, le pod passera finalement à
l'état failed
. Recherchez
l'événement correspondant pour un
message d'erreur.
Si aucun runtimeClassName
n'est spécifié, le RuntimeHandler par défault sera utilisé, qui équivaut
au comportement lorsque la fonctionnalité RuntimeClass est désactivée.
3.3.3 - L'environnement du conteneur
Cette page décrit les ressources disponibles pour les conteneurs dans l'environnement de conteneur.
L'environnement du conteneur
L’environnement Kubernetes conteneur fournit plusieurs ressources importantes aux conteneurs:
- Un système de fichier, qui est une combinaison d'une image et un ou plusieurs volumes.
- Informations sur le conteneur lui-même.
- Informations sur les autres objets du cluster.
Informations sur le conteneur
Le nom d'hôte d'un conteneur est le nom du pod dans lequel le conteneur est en cours d'exécution.
Il est disponible via la commande hostname
ou
gethostname
dans libc.
Le nom du pod et le namespace sont disponibles en tant que variables d'environnement via l'API downward.
Les variables d'environnement définies par l'utilisateur à partir de la définition de pod sont également disponibles pour le conteneur, de même que toutes les variables d'environnement spécifiées de manière statique dans l'image Docker.
Informations sur le cluster
Une liste de tous les services en cours d'exécution lors de la création d'un conteneur est disponible pour ce conteneur en tant que variables d'environnement. Ces variables d'environnement correspondent à la syntaxe des liens Docker.
Pour un service nommé foo qui correspond à un conteneur bar, les variables suivantes sont définies:
FOO_SERVICE_HOST=<l'hôte sur lequel le service est exécuté>
FOO_SERVICE_PORT=<le port sur lequel le service fonctionne>
Les services ont des adresses IP dédiées et sont disponibles pour le conteneur avec le DNS, si le module DNS est activé.
A suivre
- En savoir plus sur les hooks du cycle de vie d'un conteneur.
- Acquérir une expérience pratique en attachant les handlers aux événements du cycle de vie du conteneur.
3.3.4 - Hooks de cycle de vie de conteneurs
Cette page décrit comment un conteneur pris en charge par kubelet peut utiliser le framework de Hooks de cycle de vie de conteneurs pour exécuter du code déclenché par des événements durant son cycle de vie.
Aperçu
De manière similaire à quantité de frameworks de langages de programmation qui ont des hooks de cycle de vie de composants, comme Angular, Kubernetes fournit aux conteneurs des hooks de cycle de vie. Les hooks permettent à un conteneur d'être au courant d'événements durant son cycle de vie et d'exécuter du code implémenté dans un handler lorsque le hook de cycle de vie correspondant est exécuté.
Hooks de conteneurs
Il existe deux hooks exposés aux conteneurs :
PostStart
Ce hook s'exécute immédiatement après qu'un conteneur soit créé. Cependant, il n'y a aucune garantie que le hook s'exécute avant l'ENTRYPOINT du conteneur. Aucun paramètre n'est passé au handler.
PreStop
Ce hook est appelé immédiatement avant qu'un conteneur se termine, en raison d'un appel à l'API ou d'un événement comme un échec de la liveness probe, un droit de préemption, un conflit de ressources ou autres. Un appel au hook preStop échoue si le conteneur est déjà dans l'état terminé ou complété. Il est bloquant, ce qui veut dire qu'il est synchrone, et doit donc se terminer avant que l'appel pour supprimer le conteneur soit envoyé. Aucun paramètre n'est passé au handler.
Une description plus précise du comportement de l'arrêt peut être trouvé dans Arrêt de Pods.
Implémentation d'un handler de hook
Les conteneurs peuvent accéder à un hook en implémentant et enregistrant un handler pour ce hook. Il existe deux types de handlers de hook pouvant être implémentés pour des conteneurs :
- Exec - Exécute une commande donnée, comme
pre-stop.sh
, dans les cgroups et namespaces du conteneur. Les ressources consommées par la commande sont comptabilisées pour le conteneur. - HTTP - Exécute une requête HTTP sur un endpoint spécifique du conteneur.
Exécution d'un handler de hook
Lorsqu'un hook de cycle de vie de conteneur est appelé, le système de gestion de Kubernetes exécute le handler dans le conteneur enregistré pour ce hook.
Les appels aux handlers de hook sont synchrones dans le contexte du pod contenant le conteneur.
Ceci veut dire que pour un hook PostStart
,
bien que l'ENTRYPOINT du conteneur et le hook soient lancés de manière asynchrone, si le hook prend trop de temps à s'exécuter ou se bloque,
le conteneur ne peut pas atteindre l'état running
.
Le comportement est similaire pour un hook PreStop
.
Si le hook se bloque durant l'exécution,
la phase du Pod reste en état Terminating
et le hook est tué après terminationGracePeriodSeconds
que le pod se termine.
Si un hook PostStart
ou PreStop
échoue,
le conteneur est tué.
Les utilisateurs doivent rendre leurs handlers de hook aussi légers que possible. Il existe des cas, cependant, où de longues commandes ont un intérêt, comme pour enregistrer un état avant de stopper un conteneur.
Garanties de déclenchement d'un hook
La politique de déclenchement d'un hook est au moins une fois,
ce qui veut dire qu'un hook peut être déclenché plus d'une fois pour un événement donné,
comme PostStart
ou PreStop
.
Il appartient à l'implémentation du hook de prendre en compte correctement ce comportement.
En général, un seul déclenchement est fait. Si, par exemple, un récepteur de hook HTTP est hors service et ne peut pas prendre en charge du trafic, il n'y a aucune tentative de renvoi. Dans quelques rares cas, cependant, un double envoi peut se produire. Par exemple, si kubelet redémarre au milieu d'un déclenchement de hook, le hook pourrait être re-déclenché après que kubelet redémarre.
Débugger des handlers de hook
Les logs pour un handler de hook ne sont pas exposés dans les événements du Pod.
Si un handler échoue pour une raison particulière, il envoie un événement.
Pour PostStart
, c'est l'événement FailedPostStartHook
et pour PreStop
, c'est l'événement FailedPreStopHook
.
Vous pouvez voir ces événements en exécutant kubectl describe pod <pod_name>
.
Voici un exemple d'affichage d'événements lors de l'exécution de cette commande :
Events:
FirstSeen LastSeen Count From SubObjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
1m 1m 1 {default-scheduler } Normal Scheduled Successfully assigned test-1730497541-cq1d2 to gke-test-cluster-default-pool-a07e5d30-siqd
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Pulling pulling image "test:1.0"
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Created Created container with docker id 5c6a256a2567; Security:[seccomp=unconfined]
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Pulled Successfully pulled image "test:1.0"
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Started Started container with docker id 5c6a256a2567
38s 38s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Killing Killing container with docker id 5c6a256a2567: PostStart handler: Error executing in Docker Container: 1
37s 37s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Killing Killing container with docker id 8df9fdfd7054: PostStart handler: Error executing in Docker Container: 1
38s 37s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} Warning FailedSync Error syncing pod, skipping: failed to "StartContainer" for "main" with RunContainerError: "PostStart handler: Error executing in Docker Container: 1"
1m 22s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Warning FailedPostStartHook
A suivre
- En savoir plus sur l'Environnement d'un conteneur.
- Entraînez-vous à attacher des handlers de conteneurs à des événements de cycle de vie.
3.4 - Workloads
Un workload (charge de travail) est une application fonctionnant sur Kubernetes. Que votre workload soit un composant unique ou un agrégat de composants, sur Kubernetes celui-ci fonctionnera dans une série de pods. Dans Kubernetes, un Pod represente un ensemble de conteneur (containers) en fonctionnement sur votre cluster.
Les pods Kubernetes ont un cycle de vie définit (defined lifecycle). Par exemple, quand un pod est en fonction sur votre cluster et qu’une panne critique survient sur le noeud (node) où se situe ce pod, tous les pods du noeud seront en échec. Kubernetes traite ce niveau d’échec comme un état final : Vous devez créer un nouveau Pod pour retrouver l’état initial même si le noeud redevient sain.
Cependant, pour vous simplifier la vie, vous n’avez pas a gérer chaque Pod directement. Vous pouvez utiliser une ressource workload qui gère votre groupe de pods à votre place. Ces ressources configurent des controleurs (controllers) qui s’assurent que le bon nombre et le bon type de pod soit en fonction pour égaler l’état que vous avez spécifié.
Kubernetes fournit plusieurs ressources workload pré-faites :
Deployment
etReplicaSet
(qui remplacent l’ancienne ressource ReplicationController)). LeDeployment
(déploiement) est une bonne approche pour manager une application stateless sur votre cluster, tous lesPods
d’unDeployment
sont interchangeables et peuvent être remplacés si besoin.- Le
StatefulSet
vous permet de lancer un ou plusieurs Pods en relation qui garde plus ou moins la trace de leurs état. Par exemple si votre workload enregistre des données de façon persistente, vous pouvez lancer unStatefulSet
qui fera le lien entre lesPods
et un volume persistent (PersistentVolume
). Votre code, présent dans lesPods
duStatefulSet
, peut répliquer des données dans les autresPods
qui sont dans le mêmeStatefulSet
, pour améliorer la résilience global. - Le
DaemonSet
permet de définir lesPods
qui effectuent des actions sur le noeud local. Ceux-ci peuvent être fondamental aux opérations de votre cluster, comme un outil d’aide réseau, ou peuvent faire part d’un module complémentaire (add-on). Pour chaque nouveau noeud ajouté au cluster, le controle plane organise l'ajout d'unPod
pour ceDaemonSet
sur le nouveau noeud. - Les
Job
etCronJob
sont des taches lancées jusqu’à accomplissement puis s’arrêtent. LesJobs
réprésentent une tâche ponctuelle, lesCronJob
sont des tâches récurrentes planifiés.
Dans l’écosystème étendu de Kubernetes, vous pouvez trouver des ressources workload de fournisseurs tiers qui offrent des fonctionnalités supplémentaires.
L’utilisation d’un CustomResourceDefinition
permet d’ajouter une ressource workload d’un fournisseur tiers si vous souhaitez rajouter une fonctionnalité ou un comportement spécifique qui ne fait pas partie du noyau de Kubernetes.
Par exemple, si vous voulez lancer un groupe de Pods
pour votre application mais que vous devez arrêter leurs fonctionnement tant qu’ils ne sont pas tous disponibles, alors vous pouvez implémenter ou installer une extension qui permet cette fonctionnalité.
A suivre
Vous pouvez continuer la lecture des ressources, vous pouvez aussi apprendre à connaitre les taches qui leurs sont liées :
- Lancer une application stateless en utilisant un
Deployment
. - Lancer une application statefull, soit comme instance unique ou alors comme un ensemble répliqué.
- Lancer une tâche automatisée avec un
CronJob
.
Pour en apprendre plus sur les méchanismes de Kubernetes, de séparation du code et de la configuration, allez voir Configuration.
Il y a deux concepts supportés qui fournissent un contexte sur le sujet : comment Kubernetes gère les pods pour les applications :
- Le ramasse-miettes, fait le ménage dans votre cluster après qu’une de vos ressource soit supprimé.
- Le temps de vie d’un controlleur éteint supprime les Jobs une fois qu’un temps définit soit passé après son accomplissement.
Une fois que votre application est lancée, vous souhaitez peut etre la rendre disponible sur internet comme un Service ou comme une application web uniquement en utilsant un Ingress.
3.4.1 - Pods
3.4.1.1 - Aperçu du Pod
Cette page fournit un aperçu du Pod
, l'objet déployable le plus petit dans le modèle d'objets Kubernetes.
Comprendre les Pods
Un Pod est l'unité d'exécution de base d'une application Kubernetes--l'unité la plus petite et la plus simple dans le modèle d'objets de Kubernetes--que vous créez ou déployez. Un Pod représente des process en cours d'exécution dans votre cluster.
Un Pod encapsule un conteneur applicatif (ou, dans certains cas, plusieurs conteneurs), des ressources de stockage, une identité réseau (adresse IP) unique, ainsi que des options qui contrôlent comment le ou les conteneurs doivent s'exécuter. Un Pod représente une unité de déploiement : une instance unique d'une application dans Kubernetes, qui peut consister soit en un unique container soit en un petit nombre de conteneurs qui sont étroitement liés et qui partagent des ressources.
Docker est le runtime de conteneurs le plus courant utilisé dans un Pod Kubernetes, mais les Pods prennent également en charge d'autres runtimes de conteneurs.
Les Pods dans un cluster Kubernetes peuvent être utilisés de deux manières différentes :
- les Pods exécutant un conteneur unique. Le modèle "un-conteneur-par-Pod" est le cas d'utilisation Kubernetes le plus courant ; dans ce cas, vous pouvez voir un Pod comme un wrapper autour d'un conteneur unique, et Kubernetes gère les Pods plutôt que directement les conteneurs.
- les Pods exécutant plusieurs conteneurs devant travailler ensemble. Un Pod peut encapsuler une application composée de plusieurs conteneurs co-localisés qui sont étroitement liés et qui doivent partager des ressources. Ces conteneurs co-localisés pourraient former une unique unité de service cohésive--un conteneur servant des fichiers d'un volume partagé au public, alors qu'un conteneur "sidecar" séparé rafraîchit ou met à jour ces fichiers. Le Pod enveloppe ensemble ces conteneurs et ressources de stockage en une entité maniable de base.
Chaque Pod est destiné à exécuter une instance unique d'une application donnée. Si vous désirez mettre à l'échelle votre application horizontalement, (pour fournir plus de ressources au global en exécutant plus d'instances), vous devez utiliser plusieurs Pods, un pour chaque instance. Dans Kubernetes, on parle typiquement de réplication. Des Pods répliqués sont en général créés et gérés en tant que groupe par une ressource de charge de travail et son _contrôleur_. Voir Pods et contrôleurs pour plus d'informations.
Comment les Pods gèrent plusieurs conteneurs
Les Pods sont conçus pour supporter plusieurs process coopérants (sous forme de conteneurs) qui forment une unité de service cohésive. Les conteneurs d'un même Pod sont automatiquement co-localisés et co-programmés sur la même machine physique ou virtuelle dans le cluster. Ces conteneurs peuvent partager des ressources et dépendances, communiquer entre eux, et coordonner quand et comment ils sont arrêtés.
Notez que grouper plusieurs conteneurs co-localisés et co-gérés dans un unique Pod est un cas d'utilisation relativement avancé. Vous devez utiliser ce pattern seulement dans des instances spécifiques dans lesquelles vos conteneurs sont étroitement liés. Par exemple, vous pourriez avoir un conteneur qui agit comme un serveur web pour des fichiers contenus dans un volume partagé, et un conteneur "sidecar" séparé qui met à jour ces fichiers depuis une source externe, comme dans le diagramme suivant :
Certains Pods ont des init containers en plus d'app containers. Les Init containers s'exécutent et terminent avant que les conteneurs d'application soient démarrés.
Les Pods fournissent deux types de ressources partagées pour leurs conteneurs : réseau et stockage.
Réseau
Chaque Pod se voit assigner une adresse IP unique pour chaque famille d'adresses. Tous les conteneurs d'un Pod partagent le même namespace réseau, y compris l'adresse IP et les ports réseau. Les conteneurs à l'intérieur d'un Pod peuvent communiquer entre eux en utilisant localhost
. Lorsque les conteneurs dans un Pod communiquent avec des entités en dehors du Pod, ils doivent coordonner comment ils utilisent les ressources réseau partagées (comme les ports).
Stockage
Un Pod peut spécifier un jeu de volumes de stockage partagés. Tous les conteneurs dans le Pod peuvent accéder aux volumes partagés, permettant à ces conteneurs de partager des données. Les volumes permettent aussi les données persistantes d'un Pod de survivre au cas où un des conteneurs doit être redémarré. Voir Volumes pour plus d'informations sur la façon dont Kubernetes implémente le stockage partagé dans un Pod.
Travailler avec des Pods
Vous aurez rarement à créer directement des Pods individuels dans Kubernetes--même des Pods à un seul conteneur. Ceci est dû au fait que les Pods sont conçus comme des entités relativement éphémères et jetables. Lorsqu'un Pod est créé (directement par vous ou indirectement par un _contrôleur_), il est programmé pour s'exécuter sur un Node dans votre cluster. Le Pod reste sur ce nœud jusqu'à ce que le process se termine, l'objet pod soit supprimé, le pod soit expulsé par manque de ressources, ou le nœud soit en échec.
Les Pods ne se guérissent pas par eux-mêmes. Si un Pod est programmé sur un Nœud qui échoue, ou si l'opération de programmation elle-même échoue, le Pod est supprimé ; de plus, un Pod ne survivra pas à une expulsion due à un manque de ressources ou une mise en maintenance du Nœud. Kubernetes utilise une abstraction de plus haut niveau, appelée un contrôleur, qui s'occupe de gérer les instances de Pods relativement jetables. Ainsi, même s'il est possible d'utiliser des Pods directement, il est beaucoup plus courant dans Kubernetes de gérer vos Pods en utilisant un contrôleur.
Pods et contrôleurs
Vous pouvez utiliser des ressources de charges de travail pour créer et gérer plusieurs Pods pour vous. Un contrôleur pour la ressource gère la réplication, le plan de déploiement et la guérison automatique en cas de problèmes du Pod. Par exemple, si un noeud est en échec, un contrôleur note que les Pods de ce noeud ont arrêté de fonctionner et créent des Pods pour les remplacer. L'ordonnanceur place le Pod de remplacement sur un noeud en fonctionnement.
Voici quelques exemples de ressources de charges de travail qui gèrent un ou plusieurs Pods :
Templates de Pod
Les Templates de Pod sont des spécifications pour créer des Pods, et sont inclus dans les ressources de charges de travail comme les Deployments, les Jobs et les DaemonSets.
Chaque contrôleur pour une ressource de charges de travail utilise le template de pod à l'intérieur de l'objet pour créer les Pods. Le template de pod fait partie de l'état désiré de la ressource de charges de travail que vous avez utilisé pour exécuter votre application.
L'exemple ci-dessous est un manifest pour un Job simple avec un template
qui démarre un conteneur. Le conteneur dans ce Pod affiche un message puis se met en pause.
apiVersion: batch/v1
kind: Job
metadata:
name: hello
spec:
template:
# Ceci est un template de pod
spec:
containers:
- name: hello
image: busybox
command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
restartPolicy: OnFailure
# Le template de pod se termine ici
Modifier le template de pod ou changer pour un nouvau template de pod n'a pas d'effet sur les pods déjà existants. Les Pods ne reçoivent pas une mise à jour du template directement ; au lieu de cela, un nouveau Pod est créé pour correspondre au nouveau template de pod.
Par exemple, un contrôleur de Deployment s'assure que les Pods en cours d'exécution correspondent au template de pod en cours. Si le template est mis à jour, le contrôleur doit supprimer les pods existants et créer de nouveaux Pods avec le nouveau template. Chaque contrôleur de charges de travail implémente ses propres règles pour gérer les changements du template de Pod.
Sur les noeuds, le kubelet n'observe ou ne gère pas directement les détails concernant les templates de pods et leurs mises à jours ; ces détails sont abstraits. Cette abstraction et cette séparation des préoccupations simplifie la sémantique du système, et rend possible l'extension du comportement du cluster sans changer le code existant.
A suivre
- En savoir plus sur les Pods
- The Distributed System Toolkit: Patterns for Composite Containers explique les dispositions courantes pour des Pods avec plusieurs conteneurs
- En savoir plus sur le comportement des Pods :
3.4.1.2 - Pods
Les Pods sont les plus petites unités informatiques déployables qui peuvent être créées et gérées dans Kubernetes.
Qu'est-ce qu'un pod ?
Un pod (terme anglo-saxon décrivant un groupe de baleines ou une gousse de pois) est un groupe d'un ou plusieurs conteneurs (comme des conteneurs Docker), ayant du stockage/réseau partagé, et une spécification sur la manière d'exécuter ces conteneurs. Les éléments d'un pod sont toujours co-localisés et co-ordonnancés, et s'exécutent dans un contexte partagé. Un pod modélise un "hôte logique" spécifique à une application - il contient un ou plusieurs conteneurs applicatifs qui sont étroitement liés — dans un monde pré-conteneurs, être exécuté sur la même machine physique ou virtuelle signifierait être exécuté sur le même hôte logique.
Bien que Kubernetes prenne en charge d'autres runtimes de conteneurs que Docker, Docker est le runtime le plus connu, et cela aide à décrire des pods en termes Docker.
Le contexte partagé d'un pod est un ensemble de namespaces Linux, cgroups, et potentiellement d'autres facettes d'isolation - les mêmes choses qui isolent un conteneur Docker. Dans le contexte d'un pod, les applications individuelles peuvent se voir appliquer d'autres sous-isolations.
Les conteneurs d'un pod partagent une adresse IP et un espace de ports, et peuvent communiquer via localhost
.
Ils peuvent aussi communiquer entre eux en utilisant des communications inter-process standard comme
les sémaphores SystemV ou la mémoire partagée POSIX. Les conteneurs appartenant à des pods distincts ont des adresses IP
distinctes et ne peuvent pas communiquer par IPC sans configuration spécifique. Ces conteneurs communiquent en général entre eux via les adresses IP de leurs pods.
Les applications à l'intérieur d'un pod ont aussi accès à des volumes partagés, qui sont définis dans le cadre d'un pod et sont mis à disposition pour être montés dans le système de fichiers de chaque application.
En terme de concepts Docker, un pod est modélisé par un groupe de conteneurs Docker ayant des namespaces et des volumes partagés.
Tout comme des conteneurs applicatifs individuels, les pods sont considérés comme des entités relativement éphémères (plutôt que durables). Comme discuté dans Cycle de vie d'un pod, les pods sont créés, des ID uniques (UID) leurs sont assignés, et ils sont ordonnancés sur des nœuds où il restent jusqu'à leur arrêt (selon la politique de redémarrage) ou suppression. Si un nœud meurt, les pods ordonnancés sur ce nœud sont programmés pour être terminés, après un délai d'attente. Un pod donné (défini par un UID) n'est pas "re-ordonnancé" sur un nouveau nœud ; par contre, il peut être remplacé par un pod identique, ayant le même nom si désiré, mais avec un nouvel UID (voir replication controller pour plus de détails).
Lorsque quelque chose, comme un volume, a le même cycle de vie qu'un pod, il existe aussi longtemps que le pod (avec l'UID donné) existe. Si ce pod est supprimé pour une quelconque raison, même si un remplaçant identique est recréé, la chose liée (par ex. le volume) est aussi détruite et créée à nouveau.
Un pod multi-conteneurs contenant un extracteur de fichiers et un serveur web utilisant un volume persistant comme espace de stockage partagé entre les conteneurs.
Intérêts des pods
Gestion
Les pods fournissent une unité de service cohérente afin d'avoir un modèle coopératif entre plusieurs processus. Ils simplifient le déploiement et la gestion d'applications en fournissant une abstraction de plus haut niveau que l'ensemble des applications les constituant. Les pods servent d'unité de déploiement, de mise à l'échelle horizontale, et de réplication. La co-localisation (co-ordonnancement), la fin partagée (par ex. l'arrêt), la réplication coordonnée, le partage de ressources et la gestion des dépendances sont traités automatiquement pour les conteneurs dans un pod.
Partage de ressources et communication
Les pods permettent le partage de ressources et la communication entre ses constituants.
Les applications dans un pod utilisent toutes le même réseau (même adresse IP et espace de ports)
et peuvent donc "se trouver" entre elles et communiquer en utilisant localhost
.
À cause de cela, les applications dans un pod doivent coordonner leurs usages de ports.
Chaque pod a une adresse IP dans un réseau plat partagé ayant un accès complet
aux autres hôtes et pods à travers le réseau.
Le nom d'hôte est défini avec le nom du pod pour les conteneurs applicatifs à l'intérieur du pod. Plus de détails sur le réseau.
En plus de définir les conteneurs applicatifs s'exécutant dans le pod, le pod spécifie un ensemble de volumes de stockage partagés. Les volumes permettent aux données de survivre aux redémarrages de conteneurs et d'être partagés entre les applications d'un même pod.
Cas d'utilisation de pods
Des pods peuvent être utilisés pour héberger verticalement des piles applicatives intégrées (par ex. LAMP), mais leur principal intérêt est la mise en place de programmes auxiliaires co-localisés et co-gérés, comme :
- systèmes de gestion de contenu, chargeurs de fichiers et de données, gestionnaires de cache local, etc.
- sauvegarde de log et checkpoint, compression, rotation, prise d'instantanés, etc.
- data change watchers, log tailers, adaptateurs de logs et monitoring, éditeurs d'événements, etc.
- proxies, bridges et adaptateurs
- contrôleurs, gestionnaires, configurateurs et gestionnaires de mise à jour
Des pods individuels ne sont pas destinés à exécuter plusieurs instances de la même application, en général.
Pour une explication plus détaillée, voir The Distributed System ToolKit: Patterns for Composite Containers.
Alternatives envisagées
Pourquoi ne pas simplement exécuter plusieurs programmes dans un unique conteneur (Docker) ?
- Transparence. Rendre les conteneurs à l'intérieur du pod visibles par l'infrastucture permet à l'infrastucture de fournir des services à ces conteneurs, comme la gestion des processus et le monitoring des ressources. Ceci apporte un certain nombre de facilités aux utilisateurs.
- Découpler les dépendances logicielles. Les conteneurs individuels peuvent être versionnés, reconstruits et redéployés de manière indépendante. Kubernetes pourrait même un jour prendre en charge la mise à jour à chaud de conteneurs individuels.
- Facilité d'utilisation. Les utilisateurs n'ont pas besoin d'exécuter leur propre gestionnaire de processus, de se soucier de la propagation de signaux et de codes de sortie, etc.
- Efficacité. L'infrastructure prenant plus de responsabilités, les conteneurs peuvent être plus légers.
Pourquoi ne pas prendre en charge le co-ordonnancement de conteneurs basé sur les affinités ?
Cette approche pourrait fournir la co-localisation, mais ne fournirait pas la plupart des bénéfices des pods, comme le partage de ressources, IPC, la garantie d'une fin partagée et une gestion simplifiée.
Durabilité des pods (ou manque de)
Les pods ne doivent pas être considérés comme des entités durables. Ils ne survivent pas à des erreurs d'ordonnancement, à un nœud en échec ou à d'autres expulsions, suite à un manque de ressources ou une mise en maintenance d'un nœud.
En général, les utilisateurs n'ont pas à créer directement des pods. Ils doivent presque toujours utiliser des contrôleurs, même pour des singletons, comme par exemple des Deployments. Les contrôleurs fournissent l'auto-guérison à l'échelle du cluster, ainsi que la réplication et la gestion des déploiements (rollout). Les contrôleurs comme StatefulSet peuvent aussi prendre en charge des pods avec état (stateful).
L'utilisation d'APIs collectives comme principale primitive exposée à l'utilisateur est courante dans les systèmes d'ordonnancement de clusters, comme Borg, Marathon, Aurora, et Tupperware.
Un Pod est exposé en tant que primitive afin de faciliter :
- la connexion du scheduler et du contrôleur
- la possibilité d'opérations au niveau du pod sans besoin de passer par des APIs au niveau du contrôleur
- le découplage du cycle de fin d'un pod de celui d'un contrôleur, comme pour l'amorçage (bootstrapping)
- le découplage des contrôleurs et des services — le contrôleur d'endpoints examine uniquement des pods
- la composition claire des fonctionnalités niveau Kubelet et des fonctionnalités niveau cluster — concrètement, Kubelet est le "contrôleur de pods"
- les applications hautement disponibles, qui attendront que les pods soient remplacés avant leur arrêt et au moins avant leur suppression, comme dans les cas d'éviction programmée ou de pré-chargement d'image.
Arrêt de pods
Les pods représentant des processus s'exécutant sur des nœuds d'un cluster, il est important de permettre à ces processus de se terminer proprement lorsqu'ils ne sont plus nécessaires (plutôt que d'être violemment tués avec un signal KILL et n'avoir aucune chance de libérer ses ressources). Les utilisateurs doivent pouvoir demander une suppression et savoir quand les processus se terminent, mais aussi être capable de s'assurer que la suppression est réellement effective. Lorsqu'un utilisateur demande la suppression d'un pod, le système enregistre le délai de grâce prévu avant que le pod puisse être tué de force, et qu'un signal TERM soit envoyé au processus principal de chaque conteneur. Une fois la période de grâce expirée, le signal KILL est envoyé à ces processus, et le pod est alors supprimé de l'API server. Si Kubelet ou le gestionnaire de conteneurs est redémarré lors de l'attente de l'arrêt des processus, l'arrêt sera réessayé avec la période de grâce complète.
Un exemple de déroulement :
- Un utilisateur envoie une commande pour supprimer un Pod, avec une période de grâce par défaut (30s)
- Le Pod dans l'API server est mis à jour avec le temps au delà duquel le Pod est considéré "mort" ainsi que la période de grâce.
- Le Pod est affiché comme "Terminating" dans les listes des commandes client
- (en même temps que 3) Lorsque Kubelet voit qu'un Pod a été marqué "Terminating", le temps ayant été mis en 2, il commence le processus de suppression du pod.
- Si un des conteneurs du Pod a défini un preStop hook, il est exécuté à l'intérieur du conteneur. Si le
preStop
hook est toujours en cours d'exécution à la fin de la période de grâce, l'étape 2 est invoquée avec une courte (2 secondes) période de grâce supplémentaire une seule fois. Vous devez modifierterminationGracePeriodSeconds
si le hookpreStop
a besoin de plus de temps pour se terminer. - Le signal TERM est envoyé aux conteneurs. Notez que tous les conteneurs du Pod ne recevront pas le signal TERM en même temps et il peut être nécessaire de définir des
preStop
hook si l'ordre d'arrêt est important.
- Si un des conteneurs du Pod a défini un preStop hook, il est exécuté à l'intérieur du conteneur. Si le
- (en même temps que 3) Le Pod est supprimé des listes d'endpoints des services, et n'est plus considéré comme faisant partie des pods en cours d'exécution pour les contrôleurs de réplication. Les Pods s'arrêtant lentement ne peuvent pas continuer à servir du trafic, les load balancers (comme le service proxy) les supprimant de leurs rotations.
- Lorsque la période de grâce expire, les processus s'exécutant toujours dans le Pod sont tués avec SIGKILL.
- Kubelet va supprimer le Pod dans l'API server en indiquant une période de grâce de 0 (suppression immédiate). Le Pod disparaît de l'API et n'est plus visible par le client.
Par défaut, toutes les suppressions ont une période de grâce de 30 secondes. La commande kubectl delete
prend en charge l'option --grace-period=<secondes>
permettant à l'utilisateur de spécifier sa propre valeur. La valeur 0
force la suppression du pod. Avec kubectl version >= 1.5, vous devez spécifier un flag supplémentaire --force
avec --grace-period=0
pour pouvoir forcer la suppression.
Suppression forcée de pods
La suppression forcée d'un pod est définie comme la suppression immédiate d'un pod de l'état du cluster et d'etcd. Lorqu'une suppression forcée est effectuée, l'apiserver n'attend pas la confirmation de kubelet que le pod a été terminé sur le nœud sur lequel il s'exécutait. Il supprime le pod de l'API immédiatement pour qu'un nouveau pod puisse être créé avec le même nom. Sur le nœud, les pods devant se terminer immédiatement se verront donner une courte période de grâce avant d'être tués de force.
Les suppressions forcées peuvent être potentiellement dangereuses pour certains pods et doivent être effectuées avec précaution. Dans le cas de pods d'un StatefulSet, veuillez vous référer à la documentation pour supprimer des Pods d'un StatefulSet.
Mode privilégié pour les conteneurs d'un pod
Depuis Kubernetes v1.1, tout conteneur d'un pod peut activer le mode privilégié, en utilisant le flag privileged
du SecurityContext
de la spec du conteneur. Ceci est utile pour les conteneurs voulant utiliser les capacités de Linux comme manipuler la pile réseau ou accéder aux périphériques. Les processus dans un tel conteneur ont pratiquement les mêmes privilèges que les processus en dehors d'un conteneur. En mode privilégié, il doit être plus facile d'écrire des plugins réseau et volume en tant que pods séparés ne devant pas être compilés dans kubelet.
Si le master exécute Kubernetes v1.1 ou supérieur, et les nœuds exécutent une version antérieure à v1.1, les nouveaux pods privilégiés seront acceptés par l'api-server, mais ne seront pas lancés. Il resteront en état "pending".
Si l'utilisateur appelle kubectl describe pod FooPodName
, l'utilisateur peut voir la raison pour laquelle le pod est en état "pending". La table d'événements dans la sortie de la commande "describe" indiquera :
Error validating pod "FooPodName"."FooPodNamespace" from api, ignoring: spec.containers[0].securityContext.privileged: forbidden '<*>(0xc2089d3248)true'
Si le master exécute une version antérieure à v1.1, les pods privilégiés ne peuvent alors pas être créés. Si l'utilisateur tente de créer un pod ayant un conteneur privilégié, l'utilisateur obtiendra l'erreur suivante :
The Pod "FooPodName" is invalid. spec.containers[0].securityContext.privileged: forbidden '<*>(0xc20b222db0)true'
Objet de l'API
Le Pod est une ressource au plus haut niveau dans l'API REST Kubernetes. Plus de détails sur l'objet de l'API peuvent être trouvés à : Objet de l'API Pod.
Lorsque vous créez un manifest pour un objet Pod, soyez certain que le nom spécifié est un nom de sous-domaine DNS valide.
3.4.1.3 - Cycle de vie d'un Pod
Cette page décrit le cycle de vie d'un Pod.
Phase du Pod
Le champ status
d'un Pod est un objet
PodStatus,
contenant un champ phase
.
La phase d'un Pod est un résumé simple et de haut niveau de l'étape à laquelle le Pod se trouve dans son cycle de vie. La phase n'est pas faite pour être un cumul complet d'observations de l'état du conteneur ou du Pod, ni pour être une machine à état compréhensible.
Le nombre et la signification des valeurs de phase d'un pod sont soigneusement gardés.
Hormis ce qui est documenté ici, rien ne doit être supposé sur des Pods
ayant une valeur de phase
donnée.
Voici les valeurs possibles pour phase
:
Valeur | Description |
---|---|
Pending |
Le Pod a été accepté par Kubernetes, mais une ou plusieurs images de conteneurs n'ont pas encore été créées. Ceci inclut le temps avant d'être affecté ainsi que le temps à télécharger les images à travers le réseau, ce qui peut prendre un certain temps. |
Running |
Le pod a été affecté à un nœud et tous les conteneurs ont été créés. Au moins un conteneur est toujours en cours d'exécution, ou est en train de démarrer ou redémarrer. |
Succeeded |
Tous les conteneurs du pod ont terminé avec succès et ne seront pas redémarrés. |
Failed |
Tous les conteneurs d'un pod ont terminé, et au moins un conteneur a terminé en échec : soit le conteneur a terminé avec un status non zéro, soit il a été arrêté par le système. |
Unknown |
Pour quelque raison l'état du pod ne peut pas être obtenu, en général en cas d'erreur de communication avec l'hôte du Pod. |
Conditions du Pod
Un Pod a un PodStatus, qui contient un tableau de PodConditions à travers lesquelles le Pod est ou non passé. Chaque élément du tableau de PodCondition a six champs possibles :
-
Le champ
lastProbeTime
fournit un timestamp auquel la condition du Pod a été sondée pour la dernière fois. -
Le champ
lastTransitionTime
fournit un timestamp auquel le Pod a changé de statut pour la dernière fois. -
Le champ
message
est un message lisible indiquant les détails de la transition. -
Le champ
reason
est une raison unique, en un seul mot et en CamelCase de la transition vers la dernière condition. -
Le champ
status
est une chaîne de caractères avec les valeurs possibles "True
", "False
", et "Unknown
". -
Le champ
type
est une chaîne de caractères ayant une des valeurs suivantes :PodScheduled
: le Pod a été affecté à un nœud ;Ready
: le Pod est prêt à servir des requêtes et doit être rajouté aux équilibreurs de charge de tous les Services correspondants ;Initialized
: tous les init containers ont démarré correctement ;ContainersReady
: tous les conteneurs du Pod sont prêts.
Sondes du Conteneur
Une Sonde (Probe) est un diagnostic exécuté périodiquement par kubelet sur un Conteneur. Pour exécuter un diagnostic, kubelet appelle un Handler implémenté par le Conteneur. Il existe trois types de handlers :
-
ExecAction: Exécute la commande spécifiée à l'intérieur du Conteneur. Le diagnostic est considéré réussi si la commande se termine avec un code de retour de 0.
-
TCPSocketAction: Exécute un contrôle TCP sur l'adresse IP du Conteneur et sur un port spécifié. Le diagnostic est considéré réussi si le port est ouvert.
-
HTTPGetAction: Exécute une requête HTTP Get sur l'adresse IP du Conteneur et sur un port et un chemin spécifiés. Le diagnostic est considéré réussi si la réponse a un code de retour supérieur ou égal à 200 et inférieur à 400.
Chaque sonde a un résultat parmi ces trois :
- Success: Le Conteneur a réussi le diagnostic.
- Failure: Le Conteneur a échoué au diagnostic.
- Unknown: L'exécution du diagnostic a échoué, et donc aucune action ne peut être prise.
kubelet peut optionnellement exécuter et réagir à trois types de sondes sur des conteneurs en cours d'exécution :
-
livenessProbe
: Indique si le Conteneur est en cours d'exécution. Si la liveness probe échoue, kubelet tue le Conteneur et le Conteneur est soumis à sa politique de redémarrage (restart policy). Si un Conteneur ne fournit pas de liveness probe, l'état par défaut estSuccess
. -
readinessProbe
: Indique si le Conteneur est prêt à servir des requêtes. Si la readiness probe échoue, le contrôleur de points de terminaison (Endpoints) retire l'adresse IP du Pod des points de terminaison de tous les Services correspodant au Pod. L'état par défaut avant le délai initial estFailure
. Si le Conteneur ne fournit pas de readiness probe, l'état par défaut estSuccess
. -
startupProbe
: Indique si l'application à l'intérieur du conteneur a démarré. Toutes les autres probes sont désactivées si une starup probe est fournie, jusqu'à ce qu'elle réponde avec succès. Si la startup probe échoue, le kubelet tue le conteneur, et le conteneur est assujetti à sa politique de redémarrage. Si un conteneur ne fournit pas de startup probe, l'état par défaut estSuccess
.
Quand devez-vous utiliser une liveness probe ?
Si le process de votre Conteneur est capable de crasher de lui-même lorsqu'il
rencontre un problème ou devient inopérant, vous n'avez pas forcément besoin
d'une liveness probe ; kubelet va automatiquement exécuter l'action correcte
en accord avec la politique de redémarrage (restartPolicy
) du Pod.
Si vous désirez que votre Conteneur soit tué et redémarré si une sonde échoue, alors
spécifiez une liveness probe et indiquez une valeur pour restartPolicy
à Always
ou OnFailure.
Quand devez-vous utiliser une readiness probe ?
Kubernetes v1.0 [stable]
Si vous voulez commencer à envoyer du trafic à un Pod seulement lorsqu'une sonde réussit, spécifiez une readiness probe. Dans ce cas, la readiness probe peut être la même que la liveness probe, mais l'existence de la readiness probe dans la spec veut dire que le Pod va démarrer sans recevoir aucun trafic et va commencer à recevoir du trafic après que la sonde réussisse. Si votre Conteneur doit charger une grande quantité de données, des fichiers de configuration ou exécuter des migrations au démarrage, spécifiez une readiness probe.
Si vous désirez que le Conteneur soit capable de se mettre en maintenance tout seul, vous pouvez spécifier une readiness probe qui vérifie un point de terminaison spécifique au readiness et différent de la liveness probe.
Notez que si vous voulez uniquement être capable de dérouter les requêtes lorsque le Pod est supprimé, vous n'avez pas forcément besoin d'une readiness probe; lors de sa suppression, le Pod se met automatiquement dans un état non prêt, que la readiness probe existe ou non. Le Pod reste dans le statut non prêt le temps que les Conteneurs du Pod s'arrêtent.
Quand devez-vous utiliser une startup probe ?
Kubernetes v1.16 [alpha]
Si votre conteneur démarre habituellement en plus de initialDelaySeconds + failureThreshold × periodSeconds
,
vous devriez spécifier une startup probe qui vérifie le même point de terminaison que la liveness probe. La valeur par défaut pour periodSeconds
est 30s.
Vous devriez alors mettre sa valeur failureThreshold
suffisamment haute pour permettre au conteneur de démarrer, sans changer les valeurs par défaut de la liveness probe. Ceci aide à se protéger de deadlocks.
Pour plus d'informations sur la manière de mettre en place une liveness, readiness ou startup probe, voir Configurer des Liveness, Readiness et Startup Probes.
Statut d'un Pod et d'un Conteneur
Pour des informations détaillées sur le statut d'un Pod et d'un Conteneur, voir PodStatus et ContainerStatus. Notez que l'information rapportée comme statut d'un Pod dépend du ContainerState actuel.
États d'un Conteneur
Une fois que le Pod est assigné à un nœud par le scheduler, kubelet commence
à créer les conteneurs en utilisant le runtime de conteneurs. Il existe trois états possibles
pour les conteneurs : en attente (Waiting), en cours d'exécution (Running) et terminé (Terminated). Pour vérifier l'état d'un conteneur, vous pouvez utiliser kubectl describe pod [POD_NAME]
. L'état est affiché pour chaque conteneur du Pod.
-
Waiting
: état du conteneur par défaut. Si le conteneur n'est pas dans un état Running ou Terminated, il est dans l'état Waiting. Un conteneur dans l'état Waiting exécute les opérations nécessaires, comme télécharger les images, appliquer des Secrets, etc. À côté de cet état, un message et une raison sur l'état sont affichés pour vous fournir plus d'informations.... State: Waiting Reason: ErrImagePull ...
-
Running
: Indique que le conteneur s'exécute sans problème. Le hookpostStart
(s'il existe) est exécuté avant que le conteneur entre dans l'état Running. Cet état affiche aussi le moment auquel le conteneur est entré dans l'état Running.... State: Running Started: Wed, 30 Jan 2019 16:46:38 +0530 ...
-
Terminated
: Indique que le conteneur a terminé son exécution et s'est arrêté. Un conteneur entre dans cet état lorsqu'il s'est exécuté avec succès ou lorsqu'il a échoué pour une raison quelconque. De plus, une raison et un code de retour sont affichés, ainsi que les moments de démarrage et d'arrêt du conteneur. Avant qu'un conteneur entre dans l'état Terminated, le hookpreStop
est exécuté (s'il existe).... State: Terminated Reason: Completed Exit Code: 0 Started: Wed, 30 Jan 2019 11:45:26 +0530 Finished: Wed, 30 Jan 2019 11:45:26 +0530 ...
Pod readiness
Kubernetes v1.14 [stable]
Votre application peut injecter des données dans PodStatus
.
Pod readiness. Pour utiliser cette fonctionnalité, remplissez readinessGates
dans le PodSpec avec
une liste de conditions supplémentaires que le kubelet évalue pour la disponibilité du Pod.
Les Readiness gates sont déterminées par l'état courant des champs status.condition
du Pod.
Si Kubernetes ne peut pas trouver une telle condition dans le champs status.conditions
d'un Pod, the statut de la condition
est mise par défaut à "False
".
Voici un exemple :
kind: Pod
...
spec:
readinessGates:
- conditionType: "www.example.com/feature-1"
status:
conditions:
- type: Ready # une PodCondition intégrée
status: "False"
lastProbeTime: null
lastTransitionTime: 2018-01-01T00:00:00Z
- type: "www.example.com/feature-1" # une PodCondition supplémentaire
status: "False"
lastProbeTime: null
lastTransitionTime: 2018-01-01T00:00:00Z
containerStatuses:
- containerID: docker://abcd...
ready: true
...
Les conditions du Pod que vous ajoutez doivent avoir des noms qui sont conformes au format des étiquettes de Kubernetes.
Statut de la disponibilité d'un Pod
La commande kubectl patch
ne peut pas patcher le statut d'un objet.
Pour renseigner ces status.conditions
pour le pod, les applications et
operators doivent utiliser l'action PATCH
.
Vous pouvez utiliser une bibliothèque client Kubernetes pour
écrire du code qui renseigne les conditions particulières pour la disponibilité dun Pod.
Pour un Pod utilisant des conditions particulières, ce Pod est considéré prêt seulement lorsque les deux déclarations ci-dessous sont vraies :
- Tous les conteneurs du Pod sont prêts.
- Toutes les conditions spécifiées dans
ReadinessGates
sontTrue
.
Lorsque les conteneurs d'un Pod sont prêts mais qu'au moins une condition particulière
est manquante ou False
, le kubelet renseigne la condition du Pod à ContainersReady
.
Politique de redémarrage
La structure PodSpec a un champ restartPolicy
avec comme valeur possible
Always, OnFailure et Never. La valeur par défaut est Always.
restartPolicy
s'applique à tous les Conteneurs du Pod. restartPolicy
s'applique
seulement aux redémarrages des Conteneurs par kubelet sur le même nœud. Des conteneurs
terminés qui sont redémarrés par kubelet sont redémarrés avec un délai exponentiel
(10s, 20s, 40s ...) plafonné à cinq minutes, qui est réinitialisé après dix minutes
d'exécution normale. Comme discuté dans le
document sur les Pods,
une fois attaché à un nœud, un Pod ne sera jamais rattaché à un autre nœud.
Durée de vie d'un Pod
En général, les Pods restent jusqu'à ce qu'un humain ou un process de contrôleur les supprime explicitement.
Le plan de contrôle nettoie les Pods terminés (avec une phase à Succeeded
ou
Failed
), lorsque le nombre de Pods excède le seuil configuré
(determiné par terminated-pod-gc-threshold
dans le kube-controller-manager).
Ceci empêche une fuite de ressources lorsque les Pods sont créés et supprimés au fil du temps.
Il y a différents types de ressources pour créer des Pods :
-
Utilisez un Déploiement, ReplicaSet ou StatefulSet pour les Pods qui ne sont pas censés terminer, par exemple des serveurs web.
-
Utilisez un Job pour les Pods qui sont censés se terminer une fois leur tâche accomplie. Les Jobs sont appropriés seulement pour des Pods ayant
restartPolicy
égal à OnFailure ou Never. -
Utilisez un DaemonSet pour les Pods qui doivent s'exécuter sur chaque noeud éligible.
Toutes les ressources de charges de travail contiennent une PodSpec. Il est recommandé de créer la ressource de charges de travail appropriée et laisser le contrôleur de la ressource créer les Pods pour vous, plutôt que de créer directement les Pods vous-même.
Si un nœud meurt ou est déconnecté du reste du cluster, Kubernetes applique
une politique pour mettre la phase
de tous les Pods du nœud perdu à Failed.
Exemples
Exemple avancé de liveness probe
Les Liveness probes sont exécutées par kubelet, toutes les requêtes sont donc faites dans l'espace réseau de kubelet.
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- args:
- /server
image: k8s.gcr.io/liveness
livenessProbe:
httpGet:
# lorsque "host" n'est pas défini, "PodIP" sera utilisé
# host: my-host
# lorsque "scheme" n'est pas défini, "HTTP" sera utilisé. "HTTP" et "HTTPS" sont les seules valeurs possibles
# scheme: HTTPS
path: /healthz
port: 8080
httpHeaders:
- name: X-Custom-Header
value: Awesome
initialDelaySeconds: 15
timeoutSeconds: 1
name: liveness
Exemples d'états
-
Un Pod est en cours d'exécution et a un Conteneur. Le conteneur se termine avec succès.
- Écriture d'un événement de complétion.
- Si
restartPolicy
est :- Always : Redémarrage du Conteneur ; la
phase
du Pod reste à Running. - OnFailure : la
phase
du Pod passe à Succeeded. - Never : la
phase
du Pod passe à Succeeded.
- Always : Redémarrage du Conteneur ; la
-
Un Pod est en cours d'exécution et a un Conteneur. Le conteneur se termine en erreur.
- Écriture d'un événement d'échec.
- Si
restartPolicy
est :- Always : Redémarrage du Conteneur ; la
phase
du Pod reste à Running. - OnFailure : Redémarrage du Conteneur ; la
phase
du Pod reste à Running. - Never : la
phase
du Pod passe à Failed.
- Always : Redémarrage du Conteneur ; la
-
Un Pod est en cours d'exécution et a deux Conteneurs. Le conteneur 1 termine en erreur.
- Écriture d'un événement d'échec.
- Si
restartPolicy
est :- Always : Redémarrage du Conteneur ; la
phase
du Pod reste à Running. - OnFailure : Redémarrage du Conteneur ; la
phase
du Pod reste à Running. - Never : Le Conteneur n'est pas redémarré ; la
phase
du Pod reste à Running.
- Always : Redémarrage du Conteneur ; la
- Si Container 1 est arrêté, et Conteneur 2 se termine :
- Écriture d'un événement d'échec.
- Si
restartPolicy
est :- Always : Redémarrage du Conteneur ; la
phase
du Pod reste à Running. - OnFailure : Redémarrage du Conteneur ; la
phase
du Pod reste à Running. - Never : la
phase
du Pod passe à Failed.
- Always : Redémarrage du Conteneur ; la
-
Un Pod est en cours d'exécution et a un Conteneur. Le Conteneur n'a plus assez de mémoire.
- Le Conteneur se termine en erreur.
- Écriture d'un événement OOM.
- Si
restartPolicy
est :- Always : Redémarrage du Conteneur ; la
phase
du Pod reste à Running. - OnFailure : Redémarrage du Conteneur ; la
phase
du Pod reste à Running. - Never : Écriture d'un événement d'erreur ; la
phase
du Pod passe à Failed.
- Always : Redémarrage du Conteneur ; la
-
Le Pod est en cours d'exécution, et un disque meurt.
- Tous les conteneurs sont tués.
- Écriture d'un événement approprié.
- La
phase
du Pod devient Failed. - Si le Pod s'exécute sous un contrôleur, le Pod est recréé ailleurs.
-
Le Pod est en cours d'exécution et son nœud est segmenté.
- Le contrôleur de Nœud attend un certain temps.
- Le contrôleur de Nœud passe la
phase
du Pod à Failed. - Si le Pod s'exécute sous un contrôleur, le Pod est recréé ailleurs.
A suivre
-
Apprenez par la pratique attacher des handlers à des événements de cycle de vie d'un conteneur.
-
Apprenez par la pratique configurer des liveness, readiness et startup probes.
-
En apprendre plus sur les hooks de cycle de vie d'un Conteneur.
3.4.1.4 - Contraintes de propagation de topologie pour les Pods
Kubernetes v1.18 [beta]
Vous pouvez utiliser des contraintes de propagation de topologie pour contrôler comment les Pods sont propagés à travers votre cluster parmi les domaines de défaillance comme les régions, zones, noeuds et autres domaines de topologie définis par l'utilisateur. Ceci peut aider à mettre en place de la haute disponibilité et à utiliser efficacement les ressources.
Conditions préalables
Autoriser la Feature Gate
La feature gate EvenPodsSpread
doit être autorisée pour
l'API Server et le
scheduler.
Labels de noeuds
Les contraintes de propagation de topologie reposent sur les labels de noeuds pour identifier le ou les domaines de topologie dans lesquels se trouve chacun des noeuds. Par exemple, un noeud pourrait avoir les labels: node=node1,zone=us-east-1a,region=us-east-1
Supposons que vous ayez un cluster de 4 noeuds ayant les labels suivants:
NAME STATUS ROLES AGE VERSION LABELS
node1 Ready <none> 4m26s v1.16.0 node=node1,zone=zoneA
node2 Ready <none> 3m58s v1.16.0 node=node2,zone=zoneA
node3 Ready <none> 3m17s v1.16.0 node=node3,zone=zoneB
node4 Ready <none> 2m43s v1.16.0 node=node4,zone=zoneB
Une vue logique du cluster est celle-ci :
+---------------+---------------+
| zoneA | zoneB |
+-------+-------+-------+-------+
| node1 | node2 | node3 | node4 |
+-------+-------+-------+-------+
Plutôt que d'appliquer des labels manuellement, vous pouvez aussi réutiliser les labels réputés qui sont créés et renseignés automatiquement dans la plupart des clusters.
Contraintes de propagation pour les Pods
API
Le champ pod.spec.topologySpreadConstraints
est introduit dans 1.16 comme suit :
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
topologySpreadConstraints:
- maxSkew: <integer>
topologyKey: <string>
whenUnsatisfiable: <string>
labelSelector: <object>
Vous pouvez définir une ou plusieurs topologySpreadConstraint
pour indiquer au kube-scheduler comment placer chaque nouveau Pod par rapport aux Pods déjà existants dans votre cluster. Les champs sont :
- maxSkew décrit le degré avec lequel les Pods peuvent être inégalement distribués. C'est la différence maximale permise entre le nombre de Pods correspondants entre deux quelconques domaines de topologie d'un type donné. Il doit être supérieur à zéro.
- topologyKey est la clé des labels de noeuds. Si deux noeuds sont étiquettés avec cette clé et ont des valeurs égales pour ce label, le scheduler considère les deux noeuds dans la même topologie. Le scheduler essaie de placer un nombre équilibré de Pods dans chaque domaine de topologie.
- whenUnsatisfiable indique comment traiter un Pod qui ne satisfait pas les contraintes de propagation :
DoNotSchedule
(défaut) indique au scheduler de ne pas le programmer.ScheduleAnyway
indique au scheduler de le programmer, tout en priorisant les noeuds minimisant le biais (skew).
- labelSelector est utilisé pour touver les Pods correspondants. Les Pods correspondants à ce sélecteur de labels sont comptés pour déterminer le nombre de Pods dans leurs domaines de topologie correspodants. Voir Sélecteurs de labels pour plus de détails.
Vous pouvez en savoir plus sur ces champ en exécutant kubectl explain Pod.spec.topologySpreadConstraints
.
Exemple : Une TopologySpreadConstraint
Supposons que vous ayez un cluster de 4 noeuds où 3 Pods étiquettés foo:bar
sont placés sur node1, node2 et node3 respectivement (P
représente un Pod) :
+---------------+---------------+
| zoneA | zoneB |
+-------+-------+-------+-------+
| node1 | node2 | node3 | node4 |
+-------+-------+-------+-------+
| P | P | P | |
+-------+-------+-------+-------+
Si nous voulons qu'un nouveau Pod soit uniformément réparti avec les Pods existants à travers les zones, la spec peut être :
kind: Pod
apiVersion: v1
metadata:
name: mypod
labels:
foo: bar
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
foo: bar
containers:
- name: pause
image: k8s.gcr.io/pause:3.1
topologyKey: zone
implique que la distribution uniforme sera uniquement appliquée pour les noeuds ayant le label "zone:<any value>" présent. whenUnsatisfiable: DoNotSchedule
indique au scheduler de laisser le Pod dans l'état Pending si le Pod entrant ne peut pas satisfaire la contrainte.
Si le scheduler plaçait ce Pod entrant dans "zoneA", la distribution des Pods deviendrait [3, 1], et le biais serait de 2 (3 - 1) - ce qui va à l'encontre de maxSkew: 1
. Dans cet exemple, le Pod entrant peut uniquement être placé dans "zoneB":
+---------------+---------------+ +---------------+---------------+
| zoneA | zoneB | | zoneA | zoneB |
+-------+-------+-------+-------+ +-------+-------+-------+-------+
| node1 | node2 | node3 | node4 | OR | node1 | node2 | node3 | node4 |
+-------+-------+-------+-------+ +-------+-------+-------+-------+
| P | P | P | P | | P | P | P P | |
+-------+-------+-------+-------+ +-------+-------+-------+-------+
Vous pouvez ajuster la spec du Pod pour pour répondre à divers types d'exigences :
- Changez
maxSkew
pour une valeur plus grande comme "2" pour que le Pod entrant puisse aussi être placé dans la "zoneA". - Changez
topologyKey
pour "node" pour distribuer les Pods uniformément à travers les noeuds et non plus les zones. Dans l'exemple ci-dessus, simaxSkew
reste à "1", le Pod entrant peut être uniquement placé dans "node4". - Changez
whenUnsatisfiable: DoNotSchedule
enwhenUnsatisfiable: ScheduleAnyway
pour s'assurer que le Pod est toujours programmable (en supposant que les autres APIs de scheduling soient satisfaites). Cependant, il sera de préférence placé dans la topologie de domaine ayant le moins de Pods correspondants. (Prenez note que cette préférence est normalisée conjointement avec d'autres priorités de scheduling interne comme le ratio d'usage de ressources, etc.)
Example: Plusieurs TopologySpreadConstraints
Cela s'appuie sur l'exemple précédent. Supposons que vous ayez un cluster de 4 noeuds où 3 Pods étiquetés foo:bar
sont placés sur node1, node2 et node3 respectivement (P
représente un Pod):
+---------------+---------------+
| zoneA | zoneB |
+-------+-------+-------+-------+
| node1 | node2 | node3 | node4 |
+-------+-------+-------+-------+
| P | P | P | |
+-------+-------+-------+-------+
Vous pouvez utiliser 2 TopologySpreadConstraints pour contrôler la répartition des Pods aussi bien dans les zones que dans les noeuds :
kind: Pod
apiVersion: v1
metadata:
name: mypod
labels:
foo: bar
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
foo: bar
- maxSkew: 1
topologyKey: node
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
foo: bar
containers:
- name: pause
image: k8s.gcr.io/pause:3.1
Dans ce cas, pour satisfaire la première contrainte, le Pod entrant peut uniquement être placé dans "zoneB" ; alors que pour satisfaire la seconde contrainte, le Pod entrant peut uniquement être placé dans "node4". Le résultat étant l'intersection des résultats des 2 contraintes, l'unique option possible est de placer le Pod entrant dans "node4".
Plusieurs contraintes peuvent entraîner des conflits. Supposons que vous ayez un cluster de 3 noeuds couvrant 2 zones :
+---------------+-------+
| zoneA | zoneB |
+-------+-------+-------+
| node1 | node2 | node3 |
+-------+-------+-------+
| P P | P | P P |
+-------+-------+-------+
Si vous appliquez "two-constraints.yaml" à ce cluster, vous noterez que "mypod" reste dans l'état Pending
. Cela parce que : pour satisfaire la première contrainte, "mypod" peut uniquement être placé dans "zoneB"; alors que pour satisfaire la seconde contrainte, "mypod" peut uniquement être placé sur "node2". Ainsi, le résultat de l'intersection entre "zoneB" et "node2" ne retourne rien.
Pour surmonter cette situation, vous pouvez soit augmenter maxSkew
, soit modifier une des contraintes pour qu'elle utilise whenUnsatisfiable: ScheduleAnyway
.
Conventions
Il existe quelques conventions implicites qu'il est intéressant de noter ici :
-
Seuls le Pods du même espace de noms que le Pod entrant peuvent être des candidats pour la correspondance.
-
Les noeuds sans label
topologySpreadConstraints[*].topologyKey
seront ignorés. Cela induit que :- les Pods localisés sur ces noeuds n'impactent pas le calcul de
maxSkew
- dans l'exemple ci-dessus, supposons que "node1" n'a pas de label "zone", alors les 2 Pods ne seront pas comptés, et le Pod entrant sera placé dans "zoneA". - le Pod entrant n'a aucune chance d'être programmé sur ce type de noeuds - dans l'exemple ci-dessus, supposons qu'un "node5" portant un label
{zone-typo: zoneC}
joigne le cluster ; il sera ignoré, en raison de l'absence de label "zone".
- les Pods localisés sur ces noeuds n'impactent pas le calcul de
-
Faites attention à ce qui arrive lorsque le
topologySpreadConstraints[*].labelSelector
du Pod entrant ne correspond pas à ses propres labels. Dans l'exemple ci-dessus, si nous supprimons les labels du Pod entrant, il sera toujours placé dans "zoneB" car les contraintes sont toujours satisfaites. Cependant, après le placement, le degré de déséquilibre du cluster reste inchangé - zoneA contient toujours 2 Pods ayant le label {foo:bar}, et zoneB contient 1 Pod cayant le label {foo:bar}. Si ce n'est pas ce que vous attendez, nous recommandons quetopologySpreadConstraints[*].labelSelector
du workload corresponde à ses propres labels. -
Si le Pod entrant a défini
spec.nodeSelector
ouspec.affinity.nodeAffinity
, les noeuds non correspondants seront ignorés.Supposons que vous ayez un cluster de 5 noeuds allant de zoneA à zoneC :
+---------------+---------------+-------+ | zoneA | zoneB | zoneC | +-------+-------+-------+-------+-------+ | node1 | node2 | node3 | node4 | node5 | +-------+-------+-------+-------+-------+ | P | P | P | | | +-------+-------+-------+-------+-------+
et vous savez que "zoneC" doit être exclue. Dans ce cas, vous pouvez écrire le yaml ci-dessous, pour que "mypod" soit placé dans "zoneB" plutôt que dans "zoneC".
spec.nodeSelector
est pris en compte de la même manière.kind: Pod apiVersion: v1 metadata: name: mypod labels: foo: bar spec: topologySpreadConstraints: - maxSkew: 1 topologyKey: zone whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: foo: bar affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: zone operator: NotIn values: - zoneC containers: - name: pause image: k8s.gcr.io/pause:3.1
Contraintes par défaut au niveau du cluster
Kubernetes v1.18 [alpha]
Il est possible de définir des contraintes de propagation de topologie par défaut pour un cluster. Les contraintes de propagation de topologie sont appliquées à un Pod si et seulement si :
- Il ne définit aucune contrainte dans son
.spec.topologySpreadConstraints
. - Il appartient à un service, replication controller, replica set ou stateful set.
Les contraintes par défaut peuvent être définies comme arguments du plugin PodTopologySpread
dans un profil de scheduling.
Les contraintes sont spécifiées avec la même API ci-dessus, à l'exception que
labelSelector
doit être vide. Les sélecteurs sont calculés à partir des services,
replication controllers, replica sets ou stateful sets auxquels le Pod appartient.
Un exemple de configuration pourrait ressembler à :
apiVersion: kubescheduler.config.k8s.io/v1alpha2
kind: KubeSchedulerConfiguration
profiles:
- pluginConfig:
- name: PodTopologySpread
args:
defaultConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
DefaultPodTopologySpread
.
Il est recommandé de désactiver ce plugin dans le profil de scheduling lorsque vous utilisez des contraintes
par défaut pour PodTopologySpread
.
Comparaison avec PodAffinity/PodAntiAffinity
Dans Kubernetes, les directives relatives aux "Affinités" contrôlent comment les Pods sont programmés - plus regroupés ou plus dispersés.
- Pour
PodAffinity
, vous pouvez essayer de regrouper un certain nombre de Pods dans des domaines de topologie qualifiés, - Pour
PodAntiAffinity
, seulement un Pod peut être programmé dans un domaine de topologie unique.
La fonctionnalité "EvenPodsSpread" fournit des options flexibles pour distribuer des Pods uniformément sur différents domaines de topologie - pour mettre en place de la haute disponibilité ou réduire les coûts. Cela peut aussi aider au rolling update des charges de travail et à la mise à l'échelle de réplicas. Voir Motivations pour plus de détails.
Limitations connues
En version 1.18, pour laquelle cette fonctionnalité est en Beta, il y a quelques limitations connues :
- Réduire un Déploiement peut résulter en une distrubution désiquilibrée des Pods.
- Les Pods correspondants sur des noeuds taintés sont respectés. Voir Issue 80921
3.4.1.5 - Init Containers
Cette page fournit une vue d'ensemble des conteneurs d'initialisation (init containers) : des conteneurs spécialisés qui s'exécutent avant les conteneurs d'application dans un Pod. Les init containers peuvent contenir des utilitaires ou des scripts d'installation qui ne sont pas présents dans une image d'application.
Vous pouvez spécifier des init containers dans la spécification du Pod à côté du tableau containers
(qui décrit les conteneurs d'application)
Comprendre les init containers
Un Pod peut avoir plusieurs conteneurs exécutant des applications mais peut aussi avoir un ou plusieurs init containers, qui sont exécutés avant que les conteneurs d'application ne démarrent.
Les init containers se comportent comme les conteneurs réguliers, avec quelques différences :
- Les init containers s'exécutent toujours jusqu'à la complétion.
- Chaque init container doit se terminer avec succès avant que le prochain ne démarre.
Si le init container d'un Pod échoue, Kubernetes redémarre le Pod à répétition jusqu'à ce que le init container se termine avec succès.
Cependant, si le Pod a une restartPolicy
à "Never", Kubernetes ne redémarre pas le Pod.
Afin de spécifier un init container pour un Pod, il faut ajouter le champ initContainers
dans la spécification du Pod, comme un
tableau d'objets de type Container, au même niveau que le tableau d'applications containers
.
Le statut des init containers est retourné dans le champ .status.initContainerStatuses
comme un tableau des statuts du conteneur (comparable au champ .status.containerStatuses
).
Différences avec les conteneurs réguliers
Les init containers supportent tous les champs et fonctionnalités des conteneurs d'application incluant les limites de ressources, les volumes et les paramètres de sécurité. Cependant, les demandes de ressources pour un init container sont gérées différemment des limites de ressources, tel que documenté dans Ressources.
De plus, les init containers ne supportent pas les readiness probes parce que ces conteneurs s'exécutent jusqu'au bout avant que le Pod soit prêt.
Si l'on spécifie plusieurs init containers pour un Pod, Kubelet exécute chaque init container de manière séquentielle. Chaque init container doit se terminer avec succès avant que le prochain ne puisse s'exécuter. Lorsque tous les init containers se sont exécutés jusqu'au bout, Kubelet initialise les conteneurs d'application pour le Pod et les exécute comme d'habitude.
Utiliser les init containers
Puisque les init containers ont des images séparées des conteneurs d'application, ils apportent certains avantages pour du code de mise en route :
- Les init containers peuvent contenir des utilitaires ou du code de configuration personnalisé
qui ne sont pas présents dans une image d'application.
Par exemple, il n'y a pas besoin de faire hériter une image d'une autre (
FROM
) seulement pour utiliser un outil commesed
,awk
,python
, oudig
pendant l'installation. - Les init containers peuvent exécuter en toute sécurité des utilitaires qui rendraient moins sécurisée une image de conteneur d'application.
- Les rôles "builder" et "deployer" d'une image d'application peuvent travailler indépendamment sans qu'il n'y ait besoin de créer conjointement une seule image d'application.
- Les init containers peuvent s'exécuter avec une vue du système de fichiers différente de celle des conteneurs d'application dans le même Pod. Par conséquent, on peut leur donner accès aux Secrets, auxquels les conteneurs d'application n'ont pas accès.
- Puisque les init containers s'exécutent jusqu'à la complétion avant qu'un conteneur d'application ne démarre, les init containers offrent un mécanisme pour bloquer ou retarder le démarrage d'un conteneur d'application tant qu'un ensemble de préconditions n'est pas respecté. Une fois que les préconditions sont respectées, tous les conteneurs d'application dans un Pod peuvent démarrer en parallèle.
Exemples
Voici plusieurs idées pour utiliser les init containers :
-
Attendre qu'un Service soit créé, en utilisant une commande shell d'une ligne telle que :
for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; exit 1
-
Enregistrer ce Pod à un serveur distant depuis l'API downward avec une commande telle que :
curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$(<POD_NAME>)&ip=$(<POD_IP>)'
-
Attendre un certain temps avant de démarrer le conteneur d'application avec une commande telle que :
sleep 60
-
Cloner un dépôt Git dans un Volume
-
Placer des valeurs dans un fichier de configuration et exécuter un outil de templating pour générer dynamiquement un fichier de configuration pour le conteneur d'application principal. Par exemple, placer la valeur
POD_IP
dans une configuration et générer le fichier de configuration de l'application principale en utilisant Jinja.
Les init containers en utilisation
Cet exemple définit un simple Pod possédant deux init containers.
Le premier attend myservice
et le second attend mydb
. Une fois que les deux
init containers terminent leur exécution, le Pod exécute le conteneur d'application décrit dans sa section spec
.
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo "L''app s''exécute!" && sleep 3600']
initContainers:
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo en attente de myservice; sleep 2; done"]
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo en attente de mydb; sleep 2; done"]
Les fichiers YAML suivants résument les services mydb
et myservice
:
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
Vous pouvez démarrer ce Pod en exécutant :
kubectl apply -f myapp.yaml
pod/myapp-pod created
Et vérifier son statut avec :
kubectl get -f myapp.yaml
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 Init:0/2 0 6m
ou pour plus de détails :
kubectl describe -f myapp.yaml
Name: myapp-pod
Namespace: default
[...]
Labels: app=myapp
Status: Pending
[...]
Init Containers:
init-myservice:
[...]
State: Running
[...]
init-mydb:
[...]
State: Waiting
Reason: PodInitializing
Ready: False
[...]
Containers:
myapp-container:
[...]
State: Waiting
Reason: PodInitializing
Ready: False
[...]
Events:
FirstSeen LastSeen Count From SubObjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
16s 16s 1 {default-scheduler } Normal Scheduled Successfully assigned myapp-pod to 172.17.4.201
16s 16s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulling pulling image "busybox"
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulled Successfully pulled image "busybox"
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Created Created container with docker id 5ced34a04634; Security:[seccomp=unconfined]
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Started Started container with docker id 5ced34a04634
Pour voir les logs des init containers dans ce Pod, exécuter :
kubectl logs myapp-pod -c init-myservice # Inspecter le premier init container
kubectl logs myapp-pod -c init-mydb # Inspecter le second init container
À ce stade, ces init containers attendent de découvrir les services nommés
mydb
et myservice
.
Voici une configuration que vous pouvez utiliser pour faire apparaître ces Services :
---
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
Pour créer les services mydb
et myservice
:
kubectl apply -f services.yaml
service/myservice created
service/mydb created
Vous verrez ensuite que ces init containers se terminent et que le Pod myapp-pod
évolue vers l'état "Running" (en exécution) :
kubectl get -f myapp.yaml
NAME READY STATUS RESTARTS AGE
myapp-pod 1/1 Running 0 9m
Cet exemple simple devrait suffire à vous inspirer pour créer vos propres init containers. A suivre contient un lien vers un exemple plus détaillé.
Comportement détaillé
Pendant le démarrage d'un Pod, chaque init container démarre en ordre, après que le réseau
et les volumes ont été initialisés. Chaque conteneur doit se terminer avec succès avant que le prochain
ne démarre. Si un conteneur n'arrive pas à démarrer à cause d'un problème d'exécution ou
se termine avec un échec, il est redémarré selon la restartPolicy
du Pod.
Toutefois, si la restartPolicy
du Pod est configurée à "Always", les init containers utilisent la restartPolicy
"OnFailure".
Un Pod ne peut pas être Ready
tant que tous les init containers ne se sont pas exécutés avec succès.
Les ports d'un init container ne sont pas agrégés sous un Service. Un Pod qui s'initialise
est dans l'état Pending
mais devrait avoir une condition Initialized
configurée à "true".
Si le Pod redémarre ou est redémarré, tous les init containers doivent s'exécuter à nouveau.
Les changements aux spec d'un init containers sont limités au champ image du conteneur. Changer le champ image d'un init container équivaut à redémarrer le Pod.
Puisque les init containers peuvent être redémarrés, réessayés ou ré-exécutés,
leur code doit être idempotent. En particulier, le code qui écrit dans des fichiers sur EmptyDirs
devrait être préparé à la possibilité qu'un fichier de sortie existe déjà.
Les init containers ont tous les champs d'un conteneur d'application.
Cependant, Kubernetes interdit l'utilisation de readinessProbe
parce que les init containers
ne peuvent pas définir une "readiness" distincte de la complétion. Ceci est appliqué lors de la validation.
L'utilisation de activeDeadlineSeconds
sur le Pod et livenessProbe
sur le conteneur
permet d'empêcher les init containers d'échouer tout le temps.
La deadline active inclut les init containers.
Le nom de chaque application et init container dans un Pod doit être unique; une erreur de validation est générée pour tout conteneur partageant un nom avec un autre.
Ressources
Étant donné l'ordonnancement et l'exécution des init containers, les règles suivantes s'appliquent pour l'utilisation des ressources :
- La plus haute requête ou limite particulière de ressource définie pour tous les init containers est la limite/requête d'initialisation effective
- La limite/requête effective d'un Pod pour une ressource est la plus haute parmis :
- la somme de toutes les requêtes/limites des conteneurs d'application pour une ressource
- la limite/requête d'initialisation effective pour une ressource
- Le Scheduling est effectué sur la base des requêtes/limites effectives, ce qui signifie que les init containers peuvent réserver des ressources pour l'initialisation qui ne sont pas utilisées durant le cycle de vie du Pod.
- La QoS (qualité de service) tierce de la QoS tierce effective d'un Pod est la QoS tierce aussi bien pour les init containers que pour les conteneurs d'application.
Les quotas et limites sont appliqués sur la base de la requête/limite effective d'un Pod.
Les groupes de contrôle au niveau du Pod (cgroups) sont basés sur la requête/limite effective de Pod, la même que celle du scheduler.
Raisons du redémarrage d'un Pod
Un Pod peut redémarrer, ce qui cause la ré-exécution des init containers, pour les raisons suivantes :
- Un utilisateur met à jour les spécifications du Pod, ce qui cause le changement de l'image de l'init container. Tout changement à l'image du init container redémarre le Pod. Les changements au conteneur d'application entraînent seulement le redémarrage du conteneur d'application.
- Le conteneur d'infrastructure Pod est redémarré. Ceci est peu commun et serait effectué par une personne ayant un accès root aux nœuds.
- Tous les conteneurs dans un Pod sont terminés tandis que
restartPolicy
est configurée à "Always", ce qui force le redémarrage, et l'enregistrement de complétion du init container a été perdu à cause d'une opération de garbage collection (récupération de mémoire).
A suivre
- Lire à propos de la création d'un Pod ayant un init container
- Apprendre à debugger les init containers
3.4.2 - Contrôleurs
3.4.2.1 - ReplicaSet
Un ReplicaSet (ensemble de réplicas en français) a pour but de maintenir un ensemble stable de Pods à un moment donné. Cet objet est souvent utilisé pour garantir la disponibilité d'un certain nombre identique de Pods.
Comment un ReplicaSet fonctionne
Un ReplicaSet est défini avec des champs, incluant un selecteur qui spécifie comment identifier les Pods qu'il peut posséder, un nombre de replicas indiquant le nombre de Pods qu'il doit maintenir et un modèle de Pod spécifiant les données que les nouveaux Pods que le replicatSet va créer jusqu'au nombre de replicas demandé.
Un ReplicaSet va atteindre son objectif en créant et supprimant des Pods pour atteindre le nombre de réplicas désirés. Quand un ReplicaSet a besoin de créer de nouveaux Pods, il utilise alors son Pod template.
Le lien d'un ReplicaSet à ses Pods est fait par le champ metadata.ownerReferences, qui spécifie la ressource de l'objet par lequel il est détenu. Tous les Pods acquis par un ReplicaSet ont leurs propres informations d'identification de leur Replicaset, avec leur propre champ ownerReferences. C'est par ce lien que le ReplicaSet connait l'état des Pods qu'il maintient et agit en fonction de ces derniers.
Un ReplicaSet identifie des nouveaux Pods à acquérir en utilisant son selecteur. Si il y a un Pod qui n'a pas de OwnerReference ou que OwnerReference n'est pas un controller et qu'il correspond à un sélecteur de ReplicaSet, il va immédiatement être acquis par ce ReplicaSet.
Quand utiliser un ReplicaSet ?
Un ReplicaSet garantit qu’un nombre spécifié de réplicas de Pod soient exécutés à un moment donné. Cependant, un Deployment est un concept de plus haut niveau qui gère les ReplicaSets et fournit des mises à jour déclaratives aux Pods ainsi que de nombreuses autres fonctionnalités utiles. Par conséquent, nous vous recommandons d’utiliser des Deployments au lieu d’utiliser directement des ReplicaSets, sauf si vous avez besoin d'une orchestration personnalisée des mises à jour ou si vous n'avez pas besoin de mises à jour.
Cela signifie qu'il est possible que vous n'ayez jamais besoin de manipuler des objets ReplicaSet : utilisez plutôt un déploiement et définissez votre application dans la section spec.
Exemple
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
# modify replicas according to your case
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3
Enregistrer ce manifeste dans frontend.yaml
et le soumettre à un cluster Kubernetes va créer le ReplicaSet défini et les pods qu’il gère.
kubectl apply -f https://kubernetes.io/examples/controllers/frontend.yaml
Vous pouvez ensuite récupérer les ReplicaSets actuellement déployés :
kubectl get rs
Et voir le frontend que vous avez créé :
NAME DESIRED CURRENT READY AGE
frontend 3 3 3 6s
Vous pouvez également vérifier l'état du ReplicaSet :
kubectl describe rs/frontend
Et vous verrez une sortie similaire à :
Name: frontend
Namespace: default
Selector: tier=frontend,tier in (frontend)
Labels: app=guestbook
tier=frontend
Annotations: <none>
Replicas: 3 current / 3 desired
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=guestbook
tier=frontend
Containers:
php-redis:
Image: gcr.io/google_samples/gb-frontend:v3
Port: 80/TCP
Requests:
cpu: 100m
memory: 100Mi
Environment:
GET_HOSTS_FROM: dns
Mounts: <none>
Volumes: <none>
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-qhloh
1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-dnjpy
1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-9si5l
Et enfin, vous pourrez afficher les Pods déployés :
kubectl get Pods
Vous devriez voir des informations sur les Pods avec une sortie similaire à :
NAME READY STATUS RESTARTS AGE
frontend-9si5l 1/1 Running 0 1m
frontend-dnjpy 1/1 Running 0 1m
frontend-qhloh 1/1 Running 0 1m
Vous pouvez également vérifier que la OwnerReference de ces pods est définie sur le frontend ReplicaSet. Pour ce faire, récupérez le yaml de l’un des pods :
kubectl get pods frontend-9si5l -o yaml
La sortie sera similaire à celle-ci, avec les informations de l'interface ReplicaSet frontend définies dans le champ ownerReferences des métadonnées:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: 2019-01-31T17:20:41Z
generateName: frontend-
labels:
tier: frontend
name: frontend-9si5l
namespace: default
ownerReferences:
- apiVersion: extensions/v1beta1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: frontend
uid: 892a2330-257c-11e9-aecd-025000000001
...
Acquisitions de Pod en dehors du template
Bien que vous puissiez créer des pods manuellement sans problème, il est fortement recommandé de s’assurer que ces pods n'ont pas de labels correspondant au sélecteur de l’un de vos ReplicaSets. Car un ReplicaSet n’est pas limité à posséder les pods spécifiés par son modèle - il peut acquérir d’autres pods de la manière spécifiée dans les sections précédentes.
Prenez l'exemple précédent de ReplicaSet, ainsi que les pods spécifiés dans le manifeste suivant :
apiVersion: v1
kind: Pod
metadata:
name: pod1
labels:
tier: frontend
spec:
containers:
- name: hello1
image: gcr.io/google-samples/hello-app:2.0
---
apiVersion: v1
kind: Pod
metadata:
name: pod2
labels:
tier: frontend
spec:
containers:
- name: hello2
image: gcr.io/google-samples/hello-app:1.0
Ces pods n’ayant pas de contrôleur (ni d’objet) en tant que référence propriétaire, ils correspondent au sélecteur de du ReplicaSet frontend, ils seront donc immédiatement acquis par ce ReplicaSet.
Supposons que vous créiez les pods une fois le ReplicaSet frontend déployé et qui a déjà déployé ses replicas de Pods initiaux afin de remplir son exigence de nombre de replicas :
kubectl apply -f https://kubernetes.io/examples/pods/pod-rs.yaml
Les nouveaux pods seront acquis par le ReplicaSet, puis immédiatement terminés car le ReplicaSet dépasserait alors le compte désiré.
En récupérant les pods :
kubectl get Pods
La sortie montre que les nouveaux pods sont soit déjà terminés, soit en voie de l'être :
NAME READY STATUS RESTARTS AGE
frontend-9si5l 1/1 Running 0 1m
frontend-dnjpy 1/1 Running 0 1m
frontend-qhloh 1/1 Running 0 1m
pod2 0/1 Terminating 0 4s
Cependant, si vous créez d'abord les pods :
kubectl apply -f https://kubernetes.io/examples/pods/pod-rs.yaml
Et puis créez le ReplicaSet :
kubectl apply -f https://kubernetes.io/examples/controllers/frontend.yaml
Vous verrez que le ReplicaSet a acquis les pods et n'a créé que les nouveaux Pods manquants, conformément à ses spécifications, jusqu'au nombre souhaité de Pods. En récupérant les Pods :
kubectl get Pods
La sortie va donner :
NAME READY STATUS RESTARTS AGE
frontend-pxj4r 1/1 Running 0 5s
pod1 1/1 Running 0 13s
pod2 1/1 Running 0 13s
De cette manière, un ReplicaSet peut avoir un ensemble de Pods hétérogène.
Écrire un manifest de ReplicaSet
Comme avec tous les autres objets API Kubernetes, un ReplicaSet a besoin des champs apiVersion
, kind
et metadata
.
Pour ReplicaSets, l'attribut kind
est toujours ReplicaSet.
Dans Kubernetes 1.9, la version de l'API apps/v1
pour le type ReplicaSet est la version actuelle et activée par défaut. La version de l'API apps/v1beta2
est obsolète.
Reportez-vous aux premières lignes de l'exemple frontend.yaml
pour obtenir des conseils.
Un ReplicaSet a également besoin de .spec
section.
Pod Template
L'attribut .spec.template
est un modèle de pod qui requiert d'avoir des labels. Dans notre exemple frontend.yaml
, nous avons un label : tier: frontend
.
Il faut faire attention à ne pas avoir des selecteurs que d'autres controllers utilisent, afin d'éviter que le ReplicaSet n'adopte ce pod.
Pour le champ restart policy,
.spec.template.spec.restartPolicy
, la seule valeur autorisée est Always
, qui est la valeur par défaut.
Sélecteur de Pod
Le champ .spec.selector
est un label selector. Tel que discuté
précédemment, ce sont les labels utilisés pour identifier les Pods potentiels à acquérir. Dans notre
exemple avec frontend.yaml
, le sélecteur était :
matchLabels:
tier: frontend
Dans le ReplicaSet, .spec.template.metadata.labels
doit correspondre à spec.selector
, ou sinon il sera rejeté par l'API.
.spec.selector
mais différents .spec.template.metadata.labels
et .spec.template.spec
, chaque ReplicaSet ignore les pods créés par l'autre ReplicaSet.
Replicas
Vous pouvez spécifier le nombre de pods à exécuter simultanément en définissant .spec.replicas
. Le ReplicaSet va créer/supprimer
ses pods pour correspondre à ce nombre.
Si vous ne spécifiez pas .spec.replicas
, la valeur par défaut est 1.
Travailler avec des ReplicaSets
Suppression d'un ReplicaSet et de ses pods
Pour supprimer un ReplicaSet et tous ses pods, utilisez kubectl delete
. The Garbage collector supprime automatiquement tous les pods associés par défaut.
Lors de l’utilisation de l’API REST ou de la bibliothèque client-go
, vous devez définir propagationPolicy
sur Background
ou Foreground
dans
l'option -d.
Par exemple :
kubectl proxy --port=8080
curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \
> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \
> -H "Content-Type: application/json"
Supprimer juste un ReplicaSet
Vous pouvez supprimer un ReplicaSet sans affecter ses pods à l’aide de kubectl delete
avec l'option --cascade=false
.
Lorsque vous utilisez l'API REST ou la bibliothèque client-go
, vous devez définir propagationPolicy
sur Orphan
.
Par exemple :
kubectl proxy --port=8080
curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \
> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \
> -H "Content-Type: application/json"
Une fois l’original supprimé, vous pouvez créer un nouveau ReplicaSet pour le remplacer. Tant que l'ancien et le nouveau .spec.selector
sont identiques, le nouveau adoptera les anciens Pods.
Cependant, le ReplicaSet ne fera aucun effort pour que les pods existants correspondent à un nouveau Pod template.
Pour mettre à jour les Pods à une nouvelle spec de manière contrôlée, utilisez un
Deployment, car les ReplicaSets ne supportent pas de rolling update directement.
Isoler les pods d'un ReplicaSet
Vous pouvez supprimer les pods d'un ReplicaSet en modifiant leurs labels. Cette technique peut être utilisée pour enlever les pods pour le débogage, récupération de données, etc. Les pods ainsi supprimés seront automatiquement remplacés (en supposant que le nombre de réplicas n’est pas également modifié).
Scaling d'un ReplicaSet
Un ReplicaSet peut facilement être scalé en mettant simplement à jour le champ .spec.replicas
. Le contrôleur ReplicaSet
garantit que le nombre souhaité de pods avec un sélecteur de label correspondant soient disponibles et opérationnels.
ReplicaSet en tant que Horizontal Pod Autoscaler Target
Un ReplicaSet peut également être une cible pour Horizontal Pod Autoscalers (HPA). Un ReplicaSet peut être mis à l'échelle automatiquement par un HPA. Voici un exemple HPA qui cible le ReplicaSet que nous avons créé dans l'exemple précédent.
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: frontend-scaler
spec:
scaleTargetRef:
kind: ReplicaSet
name: frontend
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 50
Enregistrer ce manifeste dans hpa-rs.yaml
et le soumettre à un cluster Kubernetes devrait
créer le HPA défini qui scale automatiquement le ReplicaSet cible en fonction de l'utilisation du processeur
des pods répliqués.
kubectl apply -f https://k8s.io/examples/controllers/hpa-rs.yaml
Vous pouvez aussi utiliser la commande kubectl autoscale
pour accomplir la même chose.
(et c'est plus facile !)
kubectl autoscale rs frontend --max=10
Alternatives au ReplicaSet
Deployment (recommandé)
Le Deployment
est un object qui peut posséder les ReplicaSets et les mettres à jour ainsi que leurs Pods de façon déclarative, côté serveur et avec des rolling updates.
Alors que les ReplicaSets peuvent être utilisés indépendamment, ils sont principalement utilisés aujourd'hui par Deployments comme mécanisme pour orchestrer la création, suppresion et mises à jour des Pods. Lorsque vous utilisez des Deployments, vous n’aurez plus à vous soucier de la gestion des ReplicaSets ainsi créés. Les déploiements possèdent et gèrent leurs ReplicaSets. C'est pourquoi il est recommandé d’utiliser les déploiements lorsque vous voulez des ReplicaSets.
Pods nus
Contrairement au cas où un utilisateur a créé directement des pods, un ReplicaSet remplace les pods supprimés ou terminés pour quelque raison que ce soit, par exemple en cas de défaillance d'un nœud ou de maintenance de nœud perturbateur, telle qu'une mise à jour kernel. Pour cette raison, nous vous recommandons d'utiliser un ReplicaSet même si votre application ne nécessite qu'un seul pod. Pensez-y de la même manière qu’un superviseur de processus, mais il supervise plusieurs pods sur plusieurs nœuds au lieu de processus individuels sur un seul nœud. Un ReplicaSet délègue les redémarrages de conteneurs locaux à un agent du nœud (par exemple, Kubelet ou Docker).
Job
Utilisez un Job
au lieu d'un ReplicaSet pour les pods qui doivent se terminer seuls
(c'est à dire des batch jobs).
DaemonSet
Utilisez un DaemonSet
au lieu d’un ReplicaSet pour les pods qui fournissent une
fonction au niveau du noeud, comme le monitoring ou la gestion des logs de ce noeud. Ces pods ont une durée de vie qui est liée
durée de vie d’une machine : le pod doit être en cours d’exécution sur la machine avant le démarrage des autres Pods et sont
sûrs de se terminer lorsque la machine est prête à être redémarrée/arrêtée.
ReplicationController
Les ReplicaSets sont les successeurs de ReplicationControllers. Les deux servent le même objectif et se comportent de la même manière, à la différence près que ReplicationController ne prend pas en charge les les exigences de sélecteur décrites dans le labels user guide. En tant que tels, les ReplicaSets sont préférés aux ReplicationControllers.
3.4.2.2 - Déploiements
Un Deployment (déploiement en français) fournit des mises à jour déclaratives pour Pods et ReplicaSets.
Vous décrivez un état désiré dans un déploiement et le controlleur déploiement change l'état réel à l'état souhaité à un rythme contrôlé. Vous pouvez définir des Deployments pour créer de nouveaux ReplicaSets, ou pour supprimer des déploiements existants et adopter toutes leurs ressources avec de nouveaux déploiements.
Cas d'utilisation
Voici des cas d'utilisation typiques pour les déploiements:
- Créer un déploiement pour déployer un ReplicaSet. Le ReplicaSet crée des pods en arrière-plan. Vérifiez l'état du déploiement pour voir s'il réussit ou non.
- Déclarez le nouvel état des Pods en mettant à jour le PodTemplateSpec du déploiement. Un nouveau ReplicaSet est créé et le déploiement gère le déplacement des pods de l'ancien ReplicaSet vers le nouveau à un rythme contrôlé. Chaque nouveau ReplicaSet met à jour la révision du déploiement.
- Revenir à une révision de déploiement antérieure si l'état actuel du déploiement n'est pas stable. Chaque restauration met à jour la révision du déploiement.
- Augmentez le déploiement pour traiter plus de charge.
- Suspendre le déploiement d'appliquer plusieurs correctifs à son PodTemplateSpec, puis de le reprendre pour démarrer un nouveau déploiement.
- Utiliser l'état du déploiement comme indicateur qu'un déploiement est bloqué.
- Nettoyer les anciens ReplicaSets dont vous n'avez plus besoin.
Création d'un déploiement
Voici un exemple de déploiement.
Il crée un ReplicaSet pour faire apparaître trois pods nginx
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
Dans cet exemple:
-
Un déploiement nommé
nginx-deployment
est créé, indiqué par le champ.metadata.name
. -
Le déploiement crée trois pods répliqués, indiqués par le champ
replicas
. -
Le champ
selector
définit comment le déploiement trouve les pods à gérer. Dans ce cas, vous sélectionnez simplement un label définie dans le template de pod (app:nginx
). Cependant, des règles de sélection plus sophistiquées sont possibles, tant que le modèle de pod satisfait lui-même la règle.Note: Le champmatchLabels
est une table de hash {clé, valeur}. Une seule {clé, valeur} dans la tablematchLabels
est équivalente à un élément dematchExpressions
, dont le champ clé est "clé", l'opérateur est "In" et le tableau de valeurs contient uniquement "valeur". Toutes les exigences, à la fois dematchLabels
et dematchExpressions
, doivent être satisfaites pour correspondre. -
Le champ
template
contient les sous-champs suivants:- Les Pods reçoivent le label
app:nginx
dans le champlabels
. - La spécification du template de pod dans le champ
.template.spec
, indique que les pods exécutent un conteneur,nginx
, qui utilise l'imagenginx
Docker Hub à la version 1.7.9. - Créez un conteneur et nommez-le
nginx
en utilisant le champname
.
- Les Pods reçoivent le label
Suivez les étapes ci-dessous pour créer le déploiement ci-dessus:
Avant de commencer, assurez-vous que votre cluster Kubernetes est opérationnel.
-
Créez le déploiement en exécutant la commande suivante:
Note: Vous pouvez spécifier l'indicateur--record
pour écrire la commande exécutée dans l'annotation de ressourcekubernetes.io/change-cause
. C'est utile pour une future introspection. Par exemple, pour voir les commandes exécutées dans chaque révision de déploiement.kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
-
Exécutez
kubectl get deployments
pour vérifier si le déploiement a été créé. Si le déploiement est toujours en cours de création, la sortie est similaire à:NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 0/3 0 0 1s
Lorsque vous inspectez les déploiements de votre cluster, les champs suivants s'affichent:
NAME
répertorie les noms des déploiements dans le cluster.DESIRED
affiche le nombre souhaité de répliques de l'application, que vous définissez lorsque vous créez le déploiement. C'est l'état désiré.CURRENT
affiche le nombre de réplicas en cours d'exécution.UP-TO-DATE
affiche le nombre de réplicas qui ont été mises à jour pour atteindre l'état souhaité.AVAILABLE
affiche le nombre de réplicas de l'application disponibles pour vos utilisateurs.AGE
affiche la durée d'exécution de l'application.
Notez que le nombre de réplicas souhaitées est de 3 selon le champ
.spec.replicas
. -
Pour voir l'état du déploiement, exécutez:
kubectl rollout status deployment.v1.apps/nginx-deployment
La sortie est similaire à ceci:
Waiting for rollout to finish: 2 out of 3 new replicas have been updated... deployment "nginx-deployment" successfully rolled out
-
Exécutez à nouveau
kubectl get deployments
quelques secondes plus tard. La sortie est similaire à ceci:NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 3/3 3 3 18s
Notez que le déploiement a créé les trois répliques et que toutes les répliques sont à jour (elles contiennent le dernier modèle de pod) et disponibles.
-
Pour voir le ReplicaSet (
rs
) créé par le déploiement, exécutezkubectl get rs
. La sortie est similaire à ceci:NAME DESIRED CURRENT READY AGE nginx-deployment-75675f5897 3 3 3 18s
Notez que le nom du ReplicaSet est toujours formaté comme:
[DEPLOYMENT-NAME]-[RANDOM-STRING]
. La chaîne aléatoire est générée aléatoirement et utilise le pod-template-hash comme graine. -
Pour voir les labels générées automatiquement pour chaque Pod, exécutez
kubectl get pods --show-labels
. La sortie est similaire à ceci:NAME READY STATUS RESTARTS AGE LABELS nginx-deployment-75675f5897-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453 nginx-deployment-75675f5897-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453 nginx-deployment-75675f5897-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
Le ReplicaSet créé garantit qu'il y a trois pods nginx
.
app: nginx
).
Ne superposez pas les étiquettes ou les sélecteurs avec d'autres contrôleurs (y compris d'autres déploiements et StatefulSets).
Kubernetes n'empêche pas les chevauchements de noms, et si plusieurs contrôleurs ont des sélecteurs qui se chevauchent, ces contrôleurs peuvent entrer en conflit et se comporter de façon inattendue.
Étiquette pod-template-hash
Le label pod-template-hash
est ajoutée par le contrôleur de déploiement à chaque ReplicaSet créé ou adopté par un déploiement.
Ce label garantit que les ReplicaSets enfants d'un déploiement ne se chevauchent pas.
Il est généré en hachant le PodTemplate
du ReplicaSet et en utilisant le hachage résultant comme valeur de label qui est ajoutée au sélecteur ReplicaSet, aux labels de template de pod et dans tous les pods existants que le ReplicaSet peut avoir.
Mise à jour d'un déploiement
.spec.template
) est modifié, par exemple si les labels ou les images de conteneur du template sont mis à jour.
D'autres mises à jour, telles que la mise à l'échelle du déploiement, ne déclenchent pas de rollout.
Suivez les étapes ci-dessous pour mettre à jour votre déploiement:
-
Mettons à jour les pods nginx pour utiliser l'image
nginx: 1.9.1
au lieu de l'imagenginx: 1.7.9
.kubectl --record deployment.apps/nginx-deployment set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1
ou utilisez la commande suivante:
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 --record
La sortie est similaire à ceci:
deployment.apps/nginx-deployment image updated
Alternativement, vous pouvez
éditer
le déploiement et changer.spec.template.spec.containers[0].image
denginx: 1.7.9
ànginx: 1.9.1
:kubectl edit deployment.v1.apps/nginx-deployment
La sortie est similaire à ceci:
deployment.apps/nginx-deployment edited
-
Pour voir l'état du déploiement, exécutez:
kubectl rollout status deployment.v1.apps/nginx-deployment
La sortie est similaire à ceci:
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
ou
deployment "nginx-deployment" successfully rolled out
Obtenez plus de détails sur votre déploiement mis à jour:
-
Une fois le déploiement réussi, vous pouvez afficher le déploiement en exécutant
kubectl get deployments
. La sortie est similaire à ceci:NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 3/3 3 3 36s
-
Exécutez
kubectl get rs
pour voir que le déploiement a mis à jour les pods en créant un nouveau ReplicaSet et en le redimensionnant jusqu'à 3 replicas, ainsi qu'en réduisant l'ancien ReplicaSet à 0 réplicas.kubectl get rs
La sortie est similaire à ceci:
NAME DESIRED CURRENT READY AGE nginx-deployment-1564180365 3 3 3 6s nginx-deployment-2035384211 0 0 0 36s
-
L'exécution de
kubectl get pods
ne devrait désormais afficher que les nouveaux pods:kubectl get pods
La sortie est similaire à ceci:
NAME READY STATUS RESTARTS AGE nginx-deployment-1564180365-khku8 1/1 Running 0 14s nginx-deployment-1564180365-nacti 1/1 Running 0 14s nginx-deployment-1564180365-z9gth 1/1 Running 0 14s
La prochaine fois que vous souhaitez mettre à jour ces pods, il vous suffit de mettre à jour le modèle de pod de déploiement à nouveau.
Le déploiement garantit que seul un certain nombre de pods sont en panne pendant leur mise à jour. Par défaut, il garantit qu'au moins 75% du nombre souhaité de pods sont en place (25% max indisponible).
Le déploiement garantit également que seul un certain nombre de pods sont créés au-dessus du nombre souhaité de pods. Par défaut, il garantit qu'au plus 125% du nombre de pods souhaité sont en hausse (surtension maximale de 25%).
Par exemple, si vous regardez attentivement le déploiement ci-dessus, vous verrez qu'il a d'abord créé un nouveau pod, puis supprimé certains anciens pods et en a créé de nouveaux. Il ne tue pas les anciens Pods tant qu'un nombre suffisant de nouveaux Pods n'est pas apparu, et ne crée pas de nouveaux Pods tant qu'un nombre suffisant de Pods anciens n'a pas été tué. Il s'assure qu'au moins 2 pods sont disponibles et qu'au maximum 4 pods au total sont disponibles.
-
Obtenez les détails de votre déploiement:
kubectl describe deployments
La sortie est similaire à ceci:
Name: nginx-deployment Namespace: default CreationTimestamp: Thu, 30 Nov 2017 10:56:25 +0000 Labels: app=nginx Annotations: deployment.kubernetes.io/revision=2 Selector: app=nginx Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=nginx Containers: nginx: Image: nginx:1.9.1 Port: 80/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: nginx-deployment-1564180365 (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 2m deployment-controller Scaled up replica set nginx-deployment-2035384211 to 3 Normal ScalingReplicaSet 24s deployment-controller Scaled up replica set nginx-deployment-1564180365 to 1 Normal ScalingReplicaSet 22s deployment-controller Scaled down replica set nginx-deployment-2035384211 to 2 Normal ScalingReplicaSet 22s deployment-controller Scaled up replica set nginx-deployment-1564180365 to 2 Normal ScalingReplicaSet 19s deployment-controller Scaled down replica set nginx-deployment-2035384211 to 1 Normal ScalingReplicaSet 19s deployment-controller Scaled up replica set nginx-deployment-1564180365 to 3 Normal ScalingReplicaSet 14s deployment-controller Scaled down replica set nginx-deployment-2035384211 to 0
Ici, vous voyez que lorsque vous avez créé le déploiement pour la première fois, il a créé un ReplicaSet (nginx-deployment-2035384211) et l'a mis à l'échelle directement jusqu'à 3 réplicas. Lorsque vous avez mis à jour le déploiement, il a créé un nouveau ReplicaSet (nginx-deployment-1564180365) et l'a mis à l'échelle jusqu'à 1, puis a réduit l'ancien ReplicaSet à 2, de sorte qu'au moins 2 pods étaient disponibles et au plus 4 pods ont été créés à chaque fois. Il a ensuite poursuivi la montée en puissance du nouveau et de l'ancien ReplicaSet, avec la même stratégie de mise à jour continue. Enfin, vous aurez 3 réplicas disponibles dans le nouveau ReplicaSet, et l'ancien ReplicaSet est réduit à 0.
Rollover (alias plusieurs mises à jour en vol)
Chaque fois qu'un nouveau déploiement est observé par le contrôleur de déploiement, un ReplicaSet est créé pour afficher les pods souhaités.
Si le déploiement est mis à jour, le ReplicaSet existant qui contrôle les pods dont les étiquettes correspondent à .spec.selector
mais dont le modèle ne correspond pas à .spec.template
est réduit.
Finalement, le nouveau ReplicaSet est mis à l'échelle à .spec.replicas
et tous les anciens ReplicaSets sont mis à l'échelle à 0.
Si vous mettez à jour un déploiement alors qu'un déploiement existant est en cours, le déploiement crée un nouveau ReplicaSet conformément à la mise à jour et commence à le mettre à l'échelle, et arrête de mettre à jour le ReplicaSet qu'il augmentait précédemment - il l'ajoutera à sa liste de anciens ReplicaSets et commencera à le réduire.
Par exemple, supposons que vous créez un déploiement pour créer 5 répliques de nginx: 1.7.9
, puis mettez à jour le déploiement pour créer 5 répliques de nginx: 1.9.1
, alors que seulement 3 répliques de nginx:1.7.9
avait été créés.
Dans ce cas, le déploiement commence immédiatement à tuer les 3 pods nginx: 1.7.9
qu'il avait créés et commence à créer des pods nginx: 1.9.1
.
Il n'attend pas que les 5 répliques de nginx: 1.7.9
soient créées avant de changer de cap.
Mises à jour du sélecteur de labels
Il est généralement déconseillé de mettre à jour le sélecteur de labels et il est suggéré de planifier vos sélecteurs à l'avance. Dans tous les cas, si vous devez effectuer une mise à jour du sélecteur de labels, soyez très prudent et assurez-vous d'avoir saisi toutes les implications.
apps/v1
, le sélecteur de label d'un déploiement est immuable après sa création.
- Les ajouts de sélecteur nécessitent que les labels de template de pod dans la spécification de déploiement soient également mises à jour avec les nouveaux labels, sinon une erreur de validation est renvoyée. Cette modification ne se chevauche pas, ce qui signifie que le nouveau sélecteur ne sélectionne pas les ReplicaSets et les pods créés avec l'ancien sélecteur, ce qui entraîne la perte de tous les anciens ReplicaSets et la création d'un nouveau ReplicaSet.
- Les mises à jour du sélecteur modifient la valeur existante dans une clé de sélection - entraînent le même comportement que les ajouts.
- La suppression de sélecteur supprime une clé existante du sélecteur de déploiement - ne nécessite aucune modification dans les labels du template de pod. Les ReplicaSets existants ne sont pas orphelins et aucun nouveau ReplicaSet n'est créé, mais notez que le label supprimé existe toujours dans tous les Pods et ReplicaSets existants.
Annulation d'un déploiement
Parfois, vous souhaiterez peut-être annuler un déploiement; par exemple, lorsque le déploiement n'est pas stable, comme en cas d'échecs à répétition (CrashLoopBackOff). Par défaut, tout l'historique des déploiements d'un déploiement est conservé dans le système afin que vous puissiez le restaurer à tout moment (vous pouvez le modifier en modifiant la limite de l'historique des révisions).
.spec.template
) est modifié, par exemple si vous mettez à jour les labels ou les images de conteneur du template.
D'autres mises à jour, telles que la mise à l'échelle du déploiement, ne créent pas de révision de déploiement, de sorte que vous puissiez faciliter la mise à l'échelle manuelle ou automatique simultanée.
Cela signifie que lorsque vous revenez à une révision antérieure, seule la partie du template de pod de déploiement est annulée.
-
Supposons que vous ayez fait une faute de frappe lors de la mise à jour du déploiement, en mettant le nom de l'image sous la forme
nginx:1.91
au lieu denginx: 1.9.1
:kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 --record=true
La sortie est similaire à ceci:
deployment.apps/nginx-deployment image updated
-
Le déploiement est bloqué. Vous pouvez le vérifier en vérifiant l'état du déploiement:
kubectl rollout status deployment.v1.apps/nginx-deployment
La sortie est similaire à ceci:
Waiting for rollout to finish: 1 out of 3 new replicas have been updated...
-
Appuyez sur Ctrl-C pour arrêter la surveillance d'état de déploiement ci-dessus. Pour plus d'informations sur les déploiements bloqués, en savoir plus ici.
-
Vous voyez que le nombre d'anciens réplicas (
nginx-deployment-1564180365
etnginx-deployment-2035384211
) est 2, et les nouveaux réplicas (nginx-deployment-3066724191
) est 1.kubectl get rs
La sortie est similaire à ceci:
NAME DESIRED CURRENT READY AGE nginx-deployment-1564180365 3 3 3 25s nginx-deployment-2035384211 0 0 0 36s nginx-deployment-3066724191 1 1 0 6s
-
En regardant les pods créés, vous voyez que 1 pod créé par le nouveau ReplicaSet est coincé dans une boucle pour récupérer son image:
kubectl get pods
La sortie est similaire à ceci:
NAME READY STATUS RESTARTS AGE nginx-deployment-1564180365-70iae 1/1 Running 0 25s nginx-deployment-1564180365-jbqqo 1/1 Running 0 25s nginx-deployment-1564180365-hysrc 1/1 Running 0 25s nginx-deployment-3066724191-08mng 0/1 ImagePullBackOff 0 6s
Note: Le contrôleur de déploiement arrête automatiquement le mauvais déploiement et arrête la mise à l'échelle du nouveau ReplicaSet. Cela dépend des paramètres rollingUpdate (maxUnavailable
spécifiquement) que vous avez spécifiés. Kubernetes définit par défaut la valeur à 25%. -
Obtenez la description du déploiement:
kubectl describe deployment
La sortie est similaire à ceci:
Name: nginx-deployment Namespace: default CreationTimestamp: Tue, 15 Mar 2016 14:48:04 -0700 Labels: app=nginx Selector: app=nginx Replicas: 3 desired | 1 updated | 4 total | 3 available | 1 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=nginx Containers: nginx: Image: nginx:1.91 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True ReplicaSetUpdated OldReplicaSets: nginx-deployment-1564180365 (3/3 replicas created) NewReplicaSet: nginx-deployment-3066724191 (1/1 replicas created) Events: FirstSeen LastSeen Count From SubObjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 1m 1m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-2035384211 to 3 22s 22s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 1 22s 22s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 2 22s 22s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 2 21s 21s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 1 21s 21s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 3 13s 13s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 0 13s 13s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 1
Pour résoudre ce problème, vous devez revenir à une version précédente de Deployment qui est stable.
Vérification de l'historique de déploiement d'un déploiement
Suivez les étapes ci-dessous pour vérifier l'historique de déploiement:
-
Tout d'abord, vérifiez les révisions de ce déploiement:
kubectl rollout history deployment.v1.apps/nginx-deployment
La sortie est similaire à ceci:
deployments "nginx-deployment" REVISION CHANGE-CAUSE 1 kubectl apply --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml --record=true 2 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true 3 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 --record=true
CHANGE-CAUSE
est copié de l'annotation de déploiementkubernetes.io/change-cause
dans ses révisions lors de la création. Vous pouvez spécifier le messageCHANGE-CAUSE
en:- Annoter le déploiement avec
kubectl annotate deployment.v1.apps/nginx-deployment kubernetes.io/change-cause="image mis à jour en 1.9.1"
- Ajoutez le drapeau
--record
pour enregistrer la commandekubectl
qui apporte des modifications à la ressource. - Modification manuelle du manifeste de la ressource.
- Annoter le déploiement avec
-
Pour voir les détails de chaque révision, exécutez:
kubectl rollout history deployment.v1.apps/nginx-deployment --revision=2
La sortie est similaire à ceci:
deployments "nginx-deployment" revision 2 Labels: app=nginx pod-template-hash=1159050644 Annotations: kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true Containers: nginx: Image: nginx:1.9.1 Port: 80/TCP QoS Tier: cpu: BestEffort memory: BestEffort Environment Variables: <none> No volumes.
Revenir à une révision précédente
Suivez les étapes ci-dessous pour restaurer le déploiement de la version actuelle à la version précédente, qui est la version 2.
-
Vous avez maintenant décidé d'annuler le déploiement actuel et le retour à la révision précédente:
kubectl rollout undo deployment.v1.apps/nginx-deployment
La sortie est similaire à ceci:
deployment.apps/nginx-deployment
Alternativement, vous pouvez revenir à une révision spécifique en la spécifiant avec
--to-revision
:kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=2
La sortie est similaire à ceci:
deployment.apps/nginx-deployment
Pour plus de détails sur les commandes liées au déploiement, lisez
kubectl rollout
.Le déploiement est maintenant rétabli à une précédente révision stable. Comme vous pouvez le voir, un événement
DeploymentRollback
pour revenir à la révision 2 est généré à partir du contrôleur de déploiement. -
Vérifiez si la restauration a réussi et que le déploiement s'exécute comme prévu, exécutez:
kubectl get deployment nginx-deployment
La sortie est similaire à ceci:
NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 3/3 3 3 30m
-
Obtenez la description du déploiement:
kubectl describe deployment nginx-deployment
La sortie est similaire à ceci:
Name: nginx-deployment Namespace: default CreationTimestamp: Sun, 02 Sep 2018 18:17:55 -0500 Labels: app=nginx Annotations: deployment.kubernetes.io/revision=4 kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true Selector: app=nginx Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=nginx Containers: nginx: Image: nginx:1.9.1 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: nginx-deployment-c4747d96c (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 12m deployment-controller Scaled up replica set nginx-deployment-75675f5897 to 3 Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set nginx-deployment-c4747d96c to 1 Normal ScalingReplicaSet 11m deployment-controller Scaled down replica set nginx-deployment-75675f5897 to 2 Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set nginx-deployment-c4747d96c to 2 Normal ScalingReplicaSet 11m deployment-controller Scaled down replica set nginx-deployment-75675f5897 to 1 Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set nginx-deployment-c4747d96c to 3 Normal ScalingReplicaSet 11m deployment-controller Scaled down replica set nginx-deployment-75675f5897 to 0 Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set nginx-deployment-595696685f to 1 Normal DeploymentRollback 15s deployment-controller Rolled back deployment "nginx-deployment" to revision 2 Normal ScalingReplicaSet 15s deployment-controller Scaled down replica set nginx-deployment-595696685f to 0
Mise à l'échelle d'un déploiement
Vous pouvez mettre à l'échelle un déploiement à l'aide de la commande suivante:
kubectl scale deployment.v1.apps/nginx-deployment --replicas=10
La sortie est similaire à ceci:
deployment.apps/nginx-deployment scaled
En supposant que l'horizontal Pod autoscaling est activé dans votre cluster, vous pouvez configurer une mise à l'échelle automatique pour votre déploiement et choisir le nombre minimum et maximum de pods que vous souhaitez exécuter en fonction de l'utilisation du processeur de vos pods existants.
kubectl autoscale deployment.v1.apps/nginx-deployment --min=10 --max=15 --cpu-percent=80
La sortie est similaire à ceci:
deployment.apps/nginx-deployment scaled
Mise à l'échelle proportionnelle
Les déploiements RollingUpdate prennent en charge l'exécution simultanée de plusieurs versions d'une application. Lorsque vous ou un autoscaler mettez à l'échelle un déploiement RollingUpdate qui se trouve au milieu d'un déploiement (en cours ou en pause), le contrôleur de déploiement équilibre les réplicas supplémentaires dans les ReplicaSets actifs existants (ReplicaSets avec pods) afin d'atténuer le risque. Ceci est appelé mise à l'échelle proportionnelle.
Par exemple, vous exécutez un déploiement avec 10 réplicas, maxSurge=3, et maxUnavailable=2.
-
Assurez-vous que les 10 réplicas de votre déploiement sont en cours d'exécution.
kubectl get deploy
La sortie est similaire à ceci:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 10 10 10 10 50s
-
Vous effectuez une mise à jour vers une nouvelle image qui s'avère impossible à résoudre depuis l'intérieur du cluster.
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:sometag
La sortie est similaire à ceci:
deployment.apps/nginx-deployment image updated
-
La mise à jour de l'image démarre un nouveau déploiement avec ReplicaSet
nginx-deployment-1989198191
, mais elle est bloquée en raison de l'exigencemaxUnavailable
que vous avez mentionnée ci-dessus. Découvrez l'état du déploiement:kubectl get rs
La sortie est similaire à ceci:
NAME DESIRED CURRENT READY AGE nginx-deployment-1989198191 5 5 0 9s nginx-deployment-618515232 8 8 8 1m
-
Ensuite, une nouvelle demande de mise à l'échelle pour le déploiement arrive. La mise à l'échelle automatique incrémente les réplicas de déploiement à 15. Le contrôleur de déploiement doit décider où ajouter ces 5 nouvelles répliques. Si vous n'utilisiez pas la mise à l'échelle proportionnelle, les 5 seraient ajoutés dans le nouveau ReplicaSet. Avec une mise à l'échelle proportionnelle, vous répartissez les répliques supplémentaires sur tous les ReplicaSets. Des proportions plus importantes vont aux ReplicaSets avec le plus de répliques et des proportions plus faibles vont aux ReplicaSets avec moins de replicas. Tous les restes sont ajoutés au ReplicaSet avec le plus de répliques. Les ReplicaSets avec zéro réplicas ne sont pas mis à l'échelle.
Dans notre exemple ci-dessus, 3 répliques sont ajoutées à l'ancien ReplicaSet et 2 répliques sont ajoutées au nouveau ReplicaSet. Le processus de déploiement devrait éventuellement déplacer toutes les répliques vers le nouveau ReplicaSet, en supposant que les nouvelles répliques deviennent saines. Pour confirmer cela, exécutez:
kubectl get deploy
La sortie est similaire à ceci:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 15 18 7 8 7m
Le statut de déploiement confirme la façon dont les réplicas ont été ajoutés à chaque ReplicaSet.
kubectl get rs
La sortie est similaire à ceci:
NAME DESIRED CURRENT READY AGE
nginx-deployment-1989198191 7 7 0 7m
nginx-deployment-618515232 11 11 11 7m
Pause et reprise d'un déploiement
Vous pouvez suspendre un déploiement avant de déclencher une ou plusieurs mises à jour, puis le reprendre. Cela vous permet d'appliquer plusieurs correctifs entre la pause et la reprise sans déclencher de déploiements inutiles.
-
Par exemple, avec un déploiement qui vient d'être créé: Obtenez les détails du déploiement:
kubectl get deploy
La sortie est similaire à ceci:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx 3 3 3 3 1m
Obtenez le statut de déploiement:
kubectl get rs
La sortie est similaire à ceci:
NAME DESIRED CURRENT READY AGE nginx-2142116321 3 3 3 1m
-
Mettez le déploiement en pause en exécutant la commande suivante:
kubectl rollout pause deployment.v1.apps/nginx-deployment
La sortie est similaire à ceci:
deployment.apps/nginx-deployment paused
-
Mettez ensuite à jour l'image du déploiement:
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1
La sortie est similaire à ceci:
deployment.apps/nginx-deployment image updated
-
Notez qu'aucun nouveau déploiement n'a commencé:
kubectl rollout history deployment.v1.apps/nginx-deployment
La sortie est similaire à ceci:
deployments "nginx" REVISION CHANGE-CAUSE 1 <none>
-
Obtenez l'état de déploiement pour vous assurer que le déploiement est correctement mis à jour:
kubectl get rs
La sortie est similaire à ceci:
NAME DESIRED CURRENT READY AGE nginx-2142116321 3 3 3 2m
-
Vous pouvez effectuer autant de mises à jour que vous le souhaitez, par exemple, mettre à jour les ressources qui seront utilisées:
kubectl set resources deployment.v1.apps/nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi
La sortie est similaire à ceci:
deployment.apps/nginx-deployment resource requirements updated
L'état initial du déploiement avant de le suspendre continuera de fonctionner, mais les nouvelles mises à jour du déploiement n'auront aucun effet tant que le déploiement sera suspendu.
-
Finalement, reprenez le déploiement et observez un nouveau ReplicaSet à venir avec toutes les nouvelles mises à jour:
kubectl rollout resume deployment.v1.apps/nginx-deployment
La sortie est similaire à ceci:
deployment.apps/nginx-deployment resumed
-
Regardez l'état du déploiement jusqu'à ce qu'il soit terminé.
kubectl get rs -w
La sortie est similaire à ceci:
NAME DESIRED CURRENT READY AGE nginx-2142116321 2 2 2 2m nginx-3926361531 2 2 0 6s nginx-3926361531 2 2 1 18s nginx-2142116321 1 2 2 2m nginx-2142116321 1 2 2 2m nginx-3926361531 3 2 1 18s nginx-3926361531 3 2 1 18s nginx-2142116321 1 1 1 2m nginx-3926361531 3 3 1 18s nginx-3926361531 3 3 2 19s nginx-2142116321 0 1 1 2m nginx-2142116321 0 1 1 2m nginx-2142116321 0 0 0 2m nginx-3926361531 3 3 3 20s
-
Obtenez le statut du dernier déploiement:
kubectl get rs
La sortie est similaire à ceci:
NAME DESIRED CURRENT READY AGE nginx-2142116321 0 0 0 2m nginx-3926361531 3 3 3 28s
Statut de déploiement
Un déploiement entre dans différents états au cours de son cycle de vie. Il peut être progressant lors du déploiement d'un nouveau ReplicaSet, il peut être effectué, ou il peut ne pas progresser.
Progression du déploiement
Kubernetes marque un déploiement comme progressing lorsqu'une des tâches suivantes est effectuée:
- Le déploiement crée un nouveau ReplicaSet.
- Le déploiement augmente son nouveau ReplicaSet.
- Le déploiement réduit ses anciens ReplicaSet.
- De nouveaux pods deviennent prêts ou disponibles (prêt pour au moins MinReadySeconds).
Vous pouvez surveiller la progression d'un déploiement à l'aide de kubectl rollout status
.
Déploiement effectué
Kubernetes marque un déploiement comme effectué lorsqu'il présente les caractéristiques suivantes:
- Toutes les répliques associées au déploiement ont été mises à jour vers la dernière version que vous avez spécifiée, ce qui signifie que toutes les mises à jour que vous avez demandées ont été effectuées.
- Toutes les répliques associées au déploiement sont disponibles.
- Aucune ancienne réplique pour le déploiement n'est en cours d'exécution.
Vous pouvez vérifier si un déploiement est terminé en utilisant kubectl rollout status
.
Si le déploiement s'est terminé avec succès, kubectl rollout status
renvoie un code de sortie de 0.
kubectl rollout status deployment.v1.apps/nginx-deployment
La sortie est similaire à ceci:
Waiting for rollout to finish: 2 of 3 updated replicas are available...
deployment "nginx-deployment" successfully rolled out
$ echo $?
0
Déploiement échoué
Votre déploiement peut rester bloqué en essayant de déployer son nouveau ReplicaSet sans jamais terminer. Cela peut se produire en raison de certains des facteurs suivants:
- Quota insuffisant
- Échecs de la sonde de préparation
- Erreurs d'extraction d'image
- Permissions insuffisantes
- Plages limites
- Mauvaise configuration de l'exécution de l'application
Vous pouvez détecter cette condition en spécifiant un paramètre d'échéance dans votre spécification de déploiement:
(.spec.progressDeadlineSeconds
).
.spec.progressDeadlineSeconds
indique le nombre de secondes pendant lesquelles le contrôleur de déploiement attend avant d'indiquer (dans l'état de déploiement) que la progression du déploiement est au point mort.
La commande kubectl
suivante définit la spécification avec progressDeadlineSeconds
pour que le contrôleur signale l'absence de progression pour un déploiement après 10 minutes:
kubectl patch deployment.v1.apps/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}'
La sortie est similaire à ceci:
deployment.apps/nginx-deployment patched
Une fois le délai dépassé, le contrôleur de déploiement ajoute un DeploymentCondition
avec les attributs suivants aux .status.conditions
du déploiement:
- Type=Progressing
- Status=False
- Reason=ProgressDeadlineExceeded
Voir les conventions Kubernetes API pour plus d'informations sur les conditions d'état.
Reason=ProgressDeadlineExceeded
.
Les orchestrateurs de niveau supérieur peuvent en tirer parti et agir en conséquence, par exemple, restaurer le déploiement vers sa version précédente.
Vous pouvez rencontrer des erreurs transitoires avec vos déploiements, soit en raison d'un délai d'attente bas que vous avez défini, soit en raison de tout autre type d'erreur pouvant être traité comme transitoire. Par exemple, supposons que votre quota soit insuffisant. Si vous décrivez le déploiement, vous remarquerez la section suivante:
kubectl describe deployment nginx-deployment
La sortie est similaire à ceci:
<...>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True ReplicaSetUpdated
ReplicaFailure True FailedCreate
<...>
Si vous exécutez kubectl get deployment nginx-deployment -o yaml
, l'état de déploiement est similaire à ceci:
status:
availableReplicas: 2
conditions:
- lastTransitionTime: 2016-10-04T12:25:39Z
lastUpdateTime: 2016-10-04T12:25:39Z
message: Replica set "nginx-deployment-4262182780" is progressing.
reason: ReplicaSetUpdated
status: "True"
type: Progressing
- lastTransitionTime: 2016-10-04T12:25:42Z
lastUpdateTime: 2016-10-04T12:25:42Z
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
- lastTransitionTime: 2016-10-04T12:25:39Z
lastUpdateTime: 2016-10-04T12:25:39Z
message: 'Error creating: pods "nginx-deployment-4262182780-" is forbidden: exceeded quota:
object-counts, requested: pods=1, used: pods=3, limited: pods=2'
reason: FailedCreate
status: "True"
type: ReplicaFailure
observedGeneration: 3
replicas: 2
unavailableReplicas: 2
Finalement, une fois la date limite de progression du déploiement dépassée, Kubernetes met à jour le statut et la raison de la condition de progression:
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing False ProgressDeadlineExceeded
ReplicaFailure True FailedCreate
Vous pouvez résoudre un problème de quota insuffisant en réduisant votre déploiement, en réduisant d'autres contrôleurs que vous exécutez ou en augmentant le quota de votre namespace.
Si vous remplissez les conditions de quota et que le contrôleur de déploiement termine ensuite le déploiement de déploiement, vous verrez la mise à jour de l'état du déploiement avec une condition réussie (Status=True
et Reason=NewReplicaSetAvailable
).
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
Type=Available
avec Status=True
signifie que votre déploiement a une disponibilité minimale.
La disponibilité minimale est dictée par les paramètres spécifiés dans la stratégie de déploiement.
Type=Progressing
avec Status=True
signifie que votre déploiement est soit au milieu d'un déploiement et qu'il progresse ou qu'il a terminé avec succès sa progression et que les nouvelles répliques minimales requises sont disponibles (voir la raison de la condition pour les détails - dans notre cas, Reason=NewReplicaSetAvailable
signifie que le déploiement est terminé).
Vous pouvez vérifier si un déploiement n'a pas pu progresser en utilisant kubectl rollout status
.
kubectl rollout status
renvoie un code de sortie différent de zéro si le déploiement a dépassé le délai de progression.
kubectl rollout status deployment.v1.apps/nginx-deployment
La sortie est similaire à ceci:
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
error: deployment "nginx" exceeded its progress deadline
$ echo $?
1
Agir sur un déploiement échoué
Toutes les actions qui s'appliquent à un déploiement complet s'appliquent également à un déploiement ayant échoué. Vous pouvez le mettre à l'échelle à la hausse/baisse, revenir à une révision précédente ou même la suspendre si vous devez appliquer plusieurs réglages dans le modèle de pod de déploiement.
Politique de nettoyage
Vous pouvez définir le champ .spec.revisionHistoryLimit
dans un déploiement pour spécifier le nombre d'anciens ReplicaSets pour ce déploiement que vous souhaitez conserver.
Le reste sera effacé en arrière-plan.
Par défaut, c'est 10.
Déploiement des Canaries
Si vous souhaitez déployer des versions sur un sous-ensemble d'utilisateurs ou de serveurs à l'aide du déploiement, vous pouvez créer plusieurs déploiements, un pour chaque version, en suivant le modèle canari décrit dans gestion des ressources.
Écriture d'une spécification de déploiement
Comme pour toutes les autres configurations Kubernetes, un déploiement a besoin des champs apiVersion
, kind
et metadata
.
Pour des informations générales sur l'utilisation des fichiers de configuration, voir déploiement d'applications, configuration des conteneurs, et Utilisation de kubectl pour gérer les ressources.
Un déploiement nécessite également un .spec
section.
Pod Template
Les .spec.template
et .spec.selector
sont les seuls champs obligatoires du .spec
.
Le .spec.template
est un Pod template.
Il a exactement le même schéma qu'un Pod, sauf qu'il est imbriqué et n'a pas de apiVersion
ou de kind
.
En plus des champs obligatoires pour un pod, un Pod Template dans un déploiement doit spécifier des labels appropriées et une stratégie de redémarrage appropriée. Pour les labels, assurez-vous de ne pas chevaucher l'action d'autres contrôleurs. Voir sélecteur).
Seulement un .spec.template.spec.restartPolicy
égal à Always
est autorisé, ce qui est la valeur par défaut s'il n'est pas spécifié.
Répliques
.spec.replicas
est un champ facultatif qui spécifie le nombre de pods souhaités.
Il vaut par défaut 1.
Sélecteur
.spec.selector
est un champ obligatoire qui spécifie un sélecteur de labels pour les pods ciblés par ce déploiement.
.spec.selector
doit correspondre .spec.template.metadata.labels
, ou il sera rejeté par l'API.
Dans la version d'API apps/v1
, .spec.selector
et .metadata.labels
ne sont pas définis par défaut sur .spec.template.metadata.labels
s'ils ne sont pas définis.
Ils doivent donc être définis explicitement.
Notez également que .spec.selector
est immuable après la création du déploiement dans apps/v1
.
Un déploiement peut mettre fin aux pods dont les étiquettes correspondent au sélecteur si leur modèle est différent de .spec.template
ou si le nombre total de ces pods dépasse .spec.replicas
.
Il fait apparaître de nouveaux pods avec .spec.template
si le nombre de pods est inférieur au nombre souhaité.
Si vous avez plusieurs contrôleurs qui ont des sélecteurs qui se chevauchent, les contrôleurs se battront entre eux et ne se comporteront pas correctement.
Stratégie
.spec.strategy
spécifie la stratégie utilisée pour remplacer les anciens pods par de nouveaux.
.spec.strategy.type
peut être "Recreate" ou "RollingUpdate".
"RollingUpdate" est la valeur par défaut.
Déploiment Recreate
Tous les pods existants sont tués avant que de nouveaux ne soient créés lorsque .spec.strategy.type==Recreate
.
Déploiement de mise à jour continue
Le déploiement met à jour les pods dans une mise à jour continue quand .spec.strategy.type==RollingUpdate
.
Vous pouvez spécifier maxUnavailable
et maxSurge
pour contrôler le processus de mise à jour continue.
Max non disponible
.spec.strategy.rollingUpdate.maxUnavailable
est un champ facultatif qui spécifie le nombre maximal de pods qui peuvent être indisponibles pendant le processus de mise à jour.
La valeur peut être un nombre absolu (par exemple, 5) ou un pourcentage des pods souhaités (par exemple, 10%).
Le nombre absolu est calculé à partir du pourcentage en arrondissant vers le bas.
La valeur ne peut pas être 0 si .spec.strategy.rollingUpdate.maxSurge
est 0.
La valeur par défaut est 25%.
Par exemple, lorsque cette valeur est définie sur 30%, l'ancien ReplicaSet peut être réduit à 70% des pods souhaités immédiatement au démarrage de la mise à jour continue. Une fois que les nouveaux pods sont prêts, l'ancien ReplicaSet peut être réduit davantage, suivi d'une augmentation du nouveau ReplicaSet, garantissant que le nombre total de pods disponibles à tout moment pendant la mise à jour est d'au moins 70% des pods souhaités.
Max Surge
.spec.strategy.rollingUpdate.maxSurge
est un champ facultatif qui spécifie le nombre maximal de pods pouvant être créés sur le nombre de pods souhaité.
La valeur peut être un nombre absolu (par exemple, 5) ou un pourcentage des pods souhaités (par exemple, 10%).
La valeur ne peut pas être 0 si MaxUnavailable
est 0.
Le nombre absolu est calculé à partir du pourcentage en arrondissant.
La valeur par défaut est 25%.
Par exemple, lorsque cette valeur est définie sur 30%, le nouveau ReplicaSet peut être mis à l'échelle immédiatement au démarrage de la mise à jour continue, de sorte que le nombre total d'anciens et de nouveaux pods ne dépasse pas 130% des pods souhaités. Une fois que les anciens pods ont été détruits, le nouveau ReplicaSet peut être augmenté davantage, garantissant que le nombre total de pods en cours d'exécution à tout moment pendant la mise à jour est au maximum de 130% des pods souhaités.
Progress Deadline Seconds
.spec.progressDeadlineSeconds
est un champ facultatif qui spécifie le nombre de secondes pendant lesquelles vous souhaitez attendre que votre déploiement progresse avant que le système ne signale que le déploiement a échoué - refait surface comme une condition avec Type=Progressing
, Status=False
et Reason=ProgressDeadlineExceeded
dans l'état de la ressource.
Le contrôleur de déploiement continuera de réessayer le déploiement.
À l'avenir, une fois la restauration automatique implémentée, le contrôleur de déploiement annulera un déploiement dès qu'il observera une telle condition.
S'il est spécifié, ce champ doit être supérieur à .spec.minReadySeconds
.
Min Ready Seconds
.spec.minReadySeconds
est un champ facultatif qui spécifie le nombre minimum de secondes pendant lequel un pod nouvellement créé doit être prêt sans qu'aucun de ses conteneurs ne plante, pour qu'il soit considéré comme disponible.
Cette valeur par défaut est 0 (le pod sera considéré comme disponible dès qu'il sera prêt).
Pour en savoir plus sur le moment où un pod est considéré comme prêt, consultez Sondes de conteneur.
Rollback To
Le champ .spec.rollbackTo
est obsolète dans les versions d'API extensions/v1beta1
et apps/v1beta1
et n'est plus pris en charge dans les versions d'API commençant par apps/v1beta2
.
Utilisez, kubectl rollout undo
pour Revenir à une révision précédente.
Limite de l'historique des révisions
L'historique de révision d'un déploiement est stocké dans les ReplicaSets qu'il contrôle.
.spec.revisionHistoryLimit
est un champ facultatif qui spécifie le nombre d'anciens ReplicaSets à conserver pour permettre la restauration.
Ces anciens ReplicaSets consomment des ressources dans etcd
et encombrent la sortie de kubectl get rs
.
La configuration de chaque révision de déploiement est stockée dans ses ReplicaSets; par conséquent, une fois un ancien ReplicaSet supprimé, vous perdez la possibilité de revenir à cette révision du déploiement.
Par défaut, 10 anciens ReplicaSets seront conservés, mais sa valeur idéale dépend de la fréquence et de la stabilité des nouveaux déploiements.
Plus précisément, la définition de ce champ à zéro signifie que tous les anciens ReplicaSets avec 0 réplicas seront nettoyés. Dans ce cas, un nouveau panneau déroulant Déploiement ne peut pas être annulé, car son historique de révision est nettoyé.
Paused
.spec.paused
est un champ booléen facultatif pour suspendre et reprendre un déploiement.
La seule différence entre un déploiement suspendu et un autre qui n'est pas suspendu, c'est que toute modification apportée au PodTemplateSpec
du déploiement suspendu ne déclenchera pas de nouveaux déploiements tant qu'il sera suspendu.
Un déploiement n'est pas suspendu par défaut lors de sa création.
Alternative aux déploiements
kubectl rolling-update
kubectl rolling-update
met à jour les pods et les ReplicationControllers de la même manière.
Mais les déploiements sont recommandés, car ils sont déclaratifs, côté serveur et ont des fonctionnalités supplémentaires, telles que la restauration de toute révision précédente même après la mise à jour progressive..
3.4.2.3 - StatefulSets
StatefulSet est l'objet de l'API de charge de travail utilisé pour gérer des applications avec état (stateful).
Gère le déploiement et la mise à l'échelle d'un ensemble de Pods, et fournit des garanties sur l'ordre et l'unicité de ces Pods.
Comme un Déploiement, un StatefulSet gère des Pods qui sont basés sur une même spécification de conteneur. Contrairement à un Deployment, un StatefulSet maintient une identité pour chacun de ces Pods. Ces Pods sont créés à partir de la même spec, mais ne sont pas interchangeables : chacun a un identifiant persistant qu'il garde à travers tous ses re-scheduling.
Si vous voulez utiliser des volumes de stockage pour fournir de la persistance à votre charge de travail, vous pouvez utiliser un StatefulSet comme partie de la solution. Même si des Pods individuels d'un StatefulSet sont susceptibles d'échouer, les identifiants persistants des Pods rendent plus facile de faire correspondre les volumes existants aux nouveaux Pods remplaçant ceux ayant échoué.
Utiliser des StatefulSets
Les StatefulSets sont utiles pour des applications qui nécessitent une ou plusieurs des choses suivantes :
- Des identifiants réseau stables et uniques.
- Un stockage persistant stable.
- Un déploiement et une mise à l'échelle ordonnés et contrôlés.
- Des mises à jour continues (rolling update) ordonnées et automatisées.
Ci-dessus, stable est synonyme de persistance suite au (re)scheduling de Pods. Si une application ne nécessite aucun identifiant stable ou de déploiement, suppression ou mise à l'échelle stables, vous devriez déployer votre application en utilisant un objet de charge de travail fournissant un ensemble de réplicas sans état (stateless).
Un Deployment ou ReplicaSet peut être mieux adapté pour vos applications sans état.
Limitations
- Le stockage pour un Pod donné doit être provisionné soit par un approvisionneur de PersistentVolume basé sur un
storage class
donné, soit pré-provisionné par un admin. - Supprimer et/ou réduire l'échelle d'un StatefulSet à zéro ne supprimera pas les volumes associés avec le StatefulSet. Ceci est fait pour garantir la sécurité des données, ce qui a généralement plus de valeur qu'une purge automatique de toutes les ressources relatives à un StatefulSet.
- Les StatefulSets nécessitent actuellement un Service Headless qui est responsable de l'identité réseau des Pods. Vous êtes responsable de la création de ce Service.
- Les StatefulSets ne fournissent aucune garantie de la terminaison des pods lorsqu'un StatefulSet est supprimé. Pour avoir une terminaison ordonnée et maîtrisée des pods du StatefulSet, il est possible de réduire l'échelle du StatefulSet à 0 avant de le supprimer.
- Lors de l'utilisation de Rolling Updates avec la
Politique de gestion des Pods par défaut (
OrderedReady
), il est possible de tomber dans un état indéfini nécessitant une intervention manuelle pour réparer.
Composants
L'exemple ci-dessous décrit les composants d'un StatefulSet.
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # doit correspondre à .spec.template.metadata.labels
serviceName: "nginx"
replicas: 3 # est 1 par défaut
template:
metadata:
labels:
app: nginx # doit correspondre à .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "my-storage-class"
resources:
requests:
storage: 1Gi
Dans l'exemple ci-dessus :
- Un Service Headless, appelé
nginx
, est utilisé pour contrôler le domaine réseau. - Le StatefulSet, appelé
web
, a une Spec indiquant que 3 réplicas du container nginx seront démarrés dans des Pods. - Le
volumeClaimTemplates
fournira un stockage stable utilisant des PersistentVolumes provisionnés par un approvisionneur de PersistentVolume.
Le nom d'un objet StatefulSet doit être un nom de sous-domaine DNS valide.
Sélecteur de Pod
Vous devez renseigner le champ .spec.selector
d'un StatefulSet pour qu'il corresponde aux labels de son .spec.template.metadata.labels
. Avant Kubernetes 1.8, le champ .spec.selector
était mis par défaut s'il était omis. Pour les versions 1.8 et ultérieures, ne pas spécifier de sélecteur de Pod résulte en une erreur de validation lors de la création du StatefulSet.
Identité du Pod
Les Pods d'un StatefulSet ont une identité unique comprenant un ordinal, une identité réseau stable et un stockage stable. L'identité est accrochée au Pod, indépendamment du noeud sur lequel il est (re)programmé.
Index Ordinal
Pour un StatefulSet avec N réplicas, chaque Pod du StatefulSet se verra assigné un ordinal entier, de 0 à N-1, unique sur l'ensemble des pods.
ID réseau stable
Chaque Pod dans un StatefulSet dérive son nom d'hôte du nom du StatefulSet
et de l'ordinal du Pod. Le modèle pour le nom d'hôte généré est
$(nom statefulset)-$(ordinal)
. L'exemple ci-dessus créera trois Pods
nommés web-0,web-1,web-2
.
Un StatefulSet peut utiliser un Service Headless
pour contrôler le domaine de ses Pods. Le domaine pris en charge par ce Service prend la forme :
$(nom service).$(namespace).svc.cluster.local
, où "cluster.local" est le domaine du cluster.
Chaque fois qu'un Pod est créé, il obtient un sous-domaine DNS correspondant, prenant la forme :
$(nom pod).$(domaine du service gouvernant)
, où le service gouvernant est défini par le
champ serviceName
du StatefulSet.
En fonction de la façon dont est configuré le DNS dans votre cluster, vous ne pourrez peut-être pas rechercher immédiatement le nom DNS d'un pod nouvellement exécuté. Ce problème peut se produire lorsque d'autres clients dans le cluster ont déjà envoyé des requêtes pour le nom d'hôte du Pod avant sa création. La mise en cache négative (normale pour le DNS) signifie que les résultats des recherches précédentes ayant échoué sont mémorisés et réutilisés, même après que le Pod ait démarré, pendant au moins quelques secondes.
Si vous avez besoin de découvrir les Pods rapidement après leur création, vous avez plusieurs options :
- Interrogez directement l'API Kubernetes (par exemple, à l'aide d'un watch) plutôt que de vous fier aux recherches DNS.
- Réduisez le temps de mise en cache dans votre fournisseur de DNS Kubernetes (cela signifie généralement modifier le ConfigMap de CoreDNS, qui met actuellement en cache pendant 30 secondes).
Comme mentionné dans la section limitations, vous êtes responsable de créer le Service Headless responsable de l'identité réseau des Pods.
Voici quelques exemples de choix pour le domaine du cluster, le nom du service, le nom du StatefulSet et comment cela affecte les noms DNS des pods du StatefulSet.
Domaine Cluster | Service (ns/nom) | StatefulSet (ns/nom) | Domaine StatefulSet | DNS Pod | Nom d'hôte |
---|---|---|---|---|---|
cluster.local | default/nginx | default/web | nginx.default.svc.cluster.local | web-{0..N-1}.nginx.default.svc.cluster.local | web-{0..N-1} |
cluster.local | foo/nginx | foo/web | nginx.foo.svc.cluster.local | web-{0..N-1}.nginx.foo.svc.cluster.local | web-{0..N-1} |
kube.local | foo/nginx | foo/web | nginx.foo.svc.kube.local | web-{0..N-1}.nginx.foo.svc.kube.local | web-{0..N-1} |
cluster.local
à moins qu'il soit
configuré autrement.
Stockage stable
Kubernetes crée un PersistentVolume pour chaque
VolumeClaimTemplate. Dans l'exemple nginx ci-dessus, chaque Pod se verra affecter un unique PersistentVolume
avec un StorageClass de my-storage-class
et 1 Gib de stockage provisionné. Si aucun StorageClass
n'est spécifié, alors le StorageClass par défaut sera utilisé. Lorsqu'un Pod est (re)schedulé
sur un noeud, ses volumeMounts
montent les PersistentVolumes associés aux
PersistentVolumeClaims. Notez que les PersistentVolumes associés avec les PersistentVolumeClaims des Pods
ne sont pas supprimés lorsque les Pods, ou le StatefulSet, sont supprimés.
Ceci doit être fait manuellement.
Étiquette du nom de Pod
Lorsque le StatefulSet Contrôleur crée un Pod,
il ajoute une étiquette, statefulset.kubernetes.io/pod-name
, renseignée avec le nom du Pod.
Cette étiquette vous permet d'attacher un Service à un Pod spécifique du StatefulSet.
Garanties de déploiement et de mise à l'échelle
- Pour un StatefulSet avec N réplicas, lorsque les Pods sont déployés, ils sont créés de manière séquentielle, dans l'ordre {0..N-1}.
- Lorsque les Pods sont supprimés, ils sont terminés dans l'ordre inverse, {N-1..0}.
- Avant qu'une opération de mise à l'échelle soit appliquée à un Pod, tous ses prédécesseurs doivent être Running et Ready.
- Avant qu'un Pod soit terminé, tous ses successeurs doivent être complètement arrêtés.
Le StatefulSet ne devrait pas spécifier un pod.Spec.TerminationGracePeriodSeconds
à 0. Cette pratique
est dangereuse et fortement déconseillée. Pour plus d'explications, veuillez vous référer à forcer la suppression de Pods de StatefulSet.
Lorsque l'exemple nginx ci-dessus est créé, trois Pods seront déployés dans l'ordre web-0, web-1, web-2. web-1 ne sera pas déployé avant que web-0 soit Running et Ready, et web-2 ne sera pas déployé avant que web-1 soit Running et Ready. Si web-0 venait à échouer, après que web-1 soit Running et Ready, mais avant que web-2 soit lancé, web-2 ne serait pas lancé avant que web-0 soit correctement relancé et redevienne Running et Ready.
Si un utilisateur venait à mettre à l'échelle l'exemple déployé en patchant le StatefulSet pour que
replicas=1
, web-2 serait terminé en premier. web-1 ne serait pas terminé avant que web-2
ne soit complètement arrêté et supprimé. Si web-0 venait à échouer après que web-2 soit terminé et complètement arrêté,
mais avant que web-1 soit terminé, web-1 ne serait pas terminé avant que web-0 soit Running et Ready.
Politiques de gestion d'un Pod
Dans Kubernetes 1.7 et ultérieurs, le StatefulSet vous permet d'assouplir ses garanties d'ordre,
tout en préservant ses garanties d'unicité et d'identité via son champ .spec.podManagementPolicy
.
Gestion de Pod OrderedReady
La gestion de Pod OrderedReady
est la valeur par défaut pour les StatefulSets. Il implémente le comportement décrit ci-dessus.
Gestion de Pod Parallel
La gestion de Pod Parallel
indique au contrôleur de StatefulSet de lancer ou
terminer tous les Pods en parallèle, et de ne pas attendre que les Pods deviennent Running
et Ready ou complètement terminés avant de lancer ou terminer un autre
Pod. Cette option affecte seulement le comportement pour les opérations de mise à l'échelle.
Les mises à jour ne sont pas affectées.
Stratégies de mise à jour
Dans Kubernetes 1.7 et ultérieurs, le champ .spec.updateStrategy
d'un StatefulSet vous permet
de configurer et désactiver les rolling updates automatisés pour les conteneurs, étiquettes,
requête/limites de ressources, et annotations pour les Pods d'un StatefulSet.
On Delete
La stratégie de mise à jour OnDelete
implémente l'ancien comportement (1.6 et précédents). Lorsque
.spec.updateStrategy.type
d'un StatefulSet est mis à OnDelete
, le contrôleur de StatefulSet
ne mettra pas à jour automatiquement les Pods dans un StatefulSet.
Les utilisateurs doivent supprimer manuellement les Pods pour forcer le contrôleur à créer de nouveaux
Pods qui réflètent les modifications faites à un .spec.template
d'un StatefulSet.
Rolling Updates
La stratégie de mise à jour RollingUpdate
implémente le rolling update automatisé pour les Pods d'un
StatefulSet. C'est la stratégie par défaut lorsque .spec.updateStrategy
n'est pas spécifié.
Lorsqu'un .spec.updateStrategy.type
d'un StatefulSet est mis à RollingUpdate
, le contrôleur de
StatefulSet va supprimer et recréer chaque Pod d'un StatefulSet. Il va procéder dans le même ordre
que pour la terminaison d'un Pod (de l'ordinal le plus grand au plus petit), mettant à jour chaque Pod,
un seul à la fois. Il va attendre qu'un Pod mis à jour soit Running et Ready avant de mettre à jour
son prédécesseur.
Partitions
La stratégie de mise à jour RollingUpdate
peut être partitionnée, en spécifiant une
.spec.updateStrategy.rollingUpdate.partition
. Si une partition est spécifiée, tous les Pods ayant un
ordinal plus grand ou égal à la partition seront mis à jour lorsque le
.spec.template
du StatefulSet sera mis à jour. Tous les Pods ayant un ordinal inférieur à la partition
ne sera pas mis à jour, et, même s'ils sont supprimés, ils seront recréés avec l'ancienne version. Si une
.spec.updateStrategy.rollingUpdate.partition
d'un StatefulSet est plus grand que son .spec.replicas
,
les mises à jour de son .spec.template
ne seront pas propagés à ses Pods.
Dans la plupart des cas vous n'aurez pas à utiliser de partition, mais elles sont utiles si vous désirez
organiser une mise à jour, déployer une version canari, ou effectuer un déploiement par étapes.
Rollback forcé
En utilisant des Rolling Updates avec la
politique de gestion d'un Pod par défaut (OrderedReady
),
il est possible de se retrouver dans un état inconsistant nécessitant une intervention manuelle pour réparation.
Si vous mettez à jour le template de Pod dans une configuration qui ne devient jamais Running et Ready (par exemple, du fait d'un mauvais binaire ou d'une erreur de configuration au niveau de l'application), le StatefulSet va arrêter le rollout et attendre.
Dans cet état, il n'est pas suffisant de revenir à une bonne configuration du template de Pod. En raison d'une erreur connue, le StatefulSet va continuer à attendre que le Pod en échec Pod devienne Ready (ce qui n'arrive jamais) avant qu'il tente de revenir à la bonne configuration.
Après être revenu au bon template, vous devez aussi supprimer tous les Pods que le StatefulSet avait déjà essayé de démarrer avec la mauvaise configuration. Le StatefulSet va alors commencer à recréer les Pods en utilisant le bon template.
A suivre
- Suivre un exemple de déploiement d'une application stateful.
- Suivre un exemple de déploiement de Cassandra avec des Stateful Sets.
- Suivre un exemple d'exécution d'une application stateful redondante.
3.5 - Services, Equilibreur de charge, et Réseau
3.5.1 - EndpointSlices
Kubernetes v1.17 [beta]
EndpointSlices offrent une méthode simple pour suivre les Endpoints d'un réseau au sein d'un cluster de Kubernetes. Ils offrent une alternative plus évolutive et extensible aux Endpoints.
Ressource pour EndpointSlice
Dans Kubernetes, un EndpointSlice contient des références à un ensemble de Endpoints. Le controleur d'EndpointSlice crée automatiquement des EndpointSlices pour un Service quand un sélecteur est spécifié. Ces EndpointSlices vont inclure des références à n'importe quels Pods qui correspondent aux selecteurs de Service. EndpointSlices groupent ensemble les Endpoints d'un réseau par combinaisons uniques de Services et de Ports.
Par exemple, voici un échantillon d'une ressource EndpointSlice pour le Kubernetes Service exemple
.
apiVersion: discovery.k8s.io/v1beta1
kind: EndpointSlice
metadata:
name: exemple-abc
labels:
kubernetes.io/service-name: exemple
addressType: IPv4
ports:
- name: http
protocol: TCP
port: 80
endpoints:
- addresses:
- "10.1.2.3"
conditions:
ready: true
hostname: pod-1
topology:
kubernetes.io/hostname: node-1
topology.kubernetes.io/zone: us-west2-a
Les EndpointSlices gérés par le contrôleur d'EndpointSlice n'auront, par défaut, pas plus de 100 Endpoints chacun. En dessous de cette échelle, EndpointSlices devraient mapper 1:1 les Endpoints et les Services et devraient avoir une performance similaire.
EndpointSlices peuvent agir en tant que source de vérité pour kube-proxy quand il s'agit du routage d'un trafic interne. Lorsqu'ils sont activés, ils devraient offrir une amélioration de performance pour les services qui ont une grand quantité d'Endpoints.
Types d'addresses
Les EndpointSlices supportent 3 types d'addresses :
- IPv4
- IPv6
- FQDN (Fully Qualified Domain Name) - [nom de domaine entièrement qualifié]
Topologie
Chaque Endpoint dans un EndpointSlice peut contenir des informations de topologie pertinentes. Ceci est utilisé pour indiquer où se trouve un Endpoint, qui contient les informations sur le Node, zone et région correspondantes. Lorsque les valeurs sont disponibles, les labels de Topologies suivants seront définis par le contrôleur EndpointSlice:
kubernetes.io/hostname
- Nom du Node sur lequel l'Endpoint se situe.topology.kubernetes.io/zone
- Zone dans laquelle l'Endpoint se situe.topology.kubernetes.io/region
- Région dans laquelle l'Endpoint se situe.
Le contrôleur EndpointSlice surveille les Services et les Pods pour assurer que leurs correspondances avec les EndpointSlices sont à jour. Le contrôleur gère les EndpointSlices pour tous les Services qui ont un sélecteur - [référence: sélecteur] - specifié. Celles-ci représenteront les IPs des Pods qui correspondent au sélecteur.
Capacité d'EndpointSlices
Les EndpointSlices sont limités à une capacité de 100 Endpoints chacun, par défaut. Vous pouvez configurer ceci avec l'indicateur --max-endpoints-per-slice
kube-controller-manager jusqu'à un maximum de 1000.
Distribution d'EndpointSlices
Chaque EndpointSlice a un ensemble de ports qui s'applique à tous les Endpoints dans la ressource. Lorsque les ports nommés sont utilisés pour un Service, les Pods peuvent se retrouver avec différents ports cibles pour le même port nommé, nécessitant différents EndpointSlices.
Le contrôleur essaie de remplir les EndpointSlices aussi complètement que possible, mais ne les rééquilibre pas activement. La logique du contrôleur est assez simple:
- Itérer à travers les EndpointSlices existants, retirer les Endpoints qui ne sont plus voulus et mettre à jour les Endpoints qui ont changé.
- Itérer à travers les EndpointSlices qui ont été modifiés dans la première étape et les remplir avec n'importe quel Endpoint nécéssaire.
- S'il reste encore des Endpoints nouveaux à ajouter, essayez de les mettre dans une slice qui n'a pas été changée et/ou en créer une nouvelle.
Par-dessus tout, la troisième étape priorise la limitation de mises à jour d'EndpointSlice sur une distribution complètement pleine d'EndpointSlices. Par exemple, s'il y avait 10 nouveaux Endpoints à ajouter et 2 EndpointSlices qui peuvent contenir 5 Endpoints en plus chacun; cette approche créera un nouveau EndpointSlice au lieu de remplir les EndpointSlice existants. C'est à dire, une seule création EndpointSlice est préférable à plusieurs mises à jour d'EndpointSlices.
Avec kube-proxy exécuté sur chaque Node et surveillant EndpointSlices, chaque changement d'un EndpointSlice devient relativement coûteux puisqu'ils seront transmis à chaque Node du cluster. Cette approche vise à limiter le nombre de modifications qui doivent être envoyées à chaque Node, même si ça peut causer plusieurs EndpointSlices non remplis.
En pratique, cette distribution bien peu idéale devrait être rare. La plupart des changements traités par le contrôleur EndpointSlice seront suffisamment petits pour tenir dans un EndpointSlice existant, et sinon, un nouveau EndpointSlice aurait probablement été bientôt nécessaire de toute façon. Les mises à jour continues des déploiements fournissent également une compaction naturelle des EndpointSlices avec tous leurs pods et les Endpoints correspondants qui se feront remplacer.
Motivation
L'API des Endpoints fournit une méthode simple et facile à suivre pour les Endpoints dans Kubernetes. Malheureusement, comme les clusters Kubernetes et Services sont devenus plus grands, les limitations de cette API sont devenues plus visibles. Plus particulièrement, celles-ci comprennent des limitations liées au dimensionnement vers un plus grand nombre d'Endpoints d'un réseau.
Puisque tous les Endpoints d'un réseau pour un Service ont été stockés dans une seule ressource Endpoints, ces ressources pourraient devenir assez lourdes. Cela affecte les performances des composants Kubernetes (notamment le plan de contrôle) et cause une grande quantité de trafic réseau et de traitements lorsque les Endpoints changent. Les EndpointSlices aident à atténuer ces problèmes ainsi qu'à fournir une plate-forme extensible pour des fonctionnalités supplémentaires telles que le routage topologique.
A suivre
3.5.2 - Service
Une manière abstraite d'exposer une application s'exécutant sur un ensemble de Pods en tant que service réseau.Avec Kubernetes, vous n'avez pas besoin de modifier votre application pour utiliser un mécanisme de découverte de services inconnu. Kubernetes donne aux pods leurs propres adresses IP et un nom DNS unique pour un ensemble de pods, et peut équilibrer la charge entre eux.
Motivation
Les Pods Kubernetes sont mortels. Ils naissent et lorsqu'ils meurent, ils ne ressuscitent pas. Si vous utilisez un Déploiement pour exécuter votre application, il peut créer et détruire dynamiquement des pods.
Chaque pod obtient sa propre adresse IP, mais dans un déploiement, l'ensemble de pods s'exécutant en un instant peut être différent de l'ensemble de pods exécutant cette application un instant plus tard.
Cela conduit à un problème: si un ensemble de pods (appelez-les «backends») fournit des fonctionnalités à d'autres pods (appelez-les «frontends») à l'intérieur de votre cluster, comment les frontends peuvent-ils trouver et suivre l'adresse IP à laquelle se connecter, afin que le frontend puisse utiliser la partie backend de la charge de travail?
C'est là où les Services rentrent en jeu.
La ressource Service
Dans Kubernetes, un service est une abstraction qui définit un ensemble logique de pods et une politique permettant d'y accéder (parfois ce modèle est appelé un micro-service). L'ensemble des pods ciblés par un service est généralement déterminé par un selector (voir ci-dessous pourquoi vous voudrez peut-être un service sans un sélecteur).
Par exemple, considérons un backend de traitement d'image sans état qui s'exécute avec 3 replicas. Ces réplicas sont fongibles et les frontends ne se soucient pas du backend qu'ils utilisent. Bien que les pods réels qui composent l'ensemble backend puissent changer, les clients frontends ne devraient pas avoir besoin de le savoir, pas plus qu'ils ne doivent suivre eux-mêmes l'ensemble des backends.
L'abstraction du service permet ce découplage.
Découverte de services native du cloud
Si vous pouvez utiliser les API Kubernetes pour la découverte de services dans votre application, vous pouvez interroger l'API server pour les Endpoints, qui sont mis à jour chaque fois que l'ensemble des pods d'un service change.
Pour les applications non natives, Kubernetes propose des moyens de placer un port réseau ou un load balancer entre votre application et les modules backend.
Définition d'un service
Un service dans Kubernetes est un objet REST, semblable à un pod.
Comme tous les objets REST, vous pouvez effectuer un POST
d'une définition de service sur le serveur API pour créer une nouvelle instance.
Par exemple, supposons que vous ayez un ensemble de pods qui écoutent chacun sur le port TCP 9376 et portent une étiquette app=MyApp
:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
Cette spécification crée un nouvel objet Service nommé «my-service», qui cible le port TCP 9376 sur n'importe quel pod avec l'étiquette «app=MyApp».
Kubernetes attribue à ce service une adresse IP (parfois appelé l'"IP cluster"), qui est utilisé par les proxies Service (voir IP virtuelles et proxy de service).
Le contrôleur de service recherche en continu les pods qui correspondent à son sélecteur, puis POST toutes les mises à jour d'un objet Endpoint également appelé "my-service".
port
entrant vers un targetPort
.
Par défaut et pour plus de commodité, le targetPort
a la même valeur que le champ port
.
Les définitions de port dans les pods ont des noms, et vous pouvez référencer ces noms dans l'attribut targetPort
d'un service.
Cela fonctionne même s'il existe un mélange de pods dans le service utilisant un seul nom configuré, avec le même protocole réseau disponible via différents numéros de port.
Cela offre beaucoup de flexibilité pour déployer et faire évoluer vos services.
Par exemple, vous pouvez modifier les numéros de port que les pods exposent dans la prochaine version de votre logiciel principal, sans casser les clients.
Le protocole par défaut pour les services est TCP; vous pouvez également utiliser tout autre protocole pris en charge.
Comme de nombreux services doivent exposer plus d'un port, Kubernetes prend en charge plusieurs définitions de port sur un objet Service. Chaque définition de port peut avoir le même protocole, ou un autre.
Services sans sélecteurs
Les services abritent le plus souvent l'accès aux pods Kubernetes, mais ils peuvent également abstraire d'autres types de backends. Par exemple:
- Vous voulez avoir un cluster de base de données externe en production, mais dans votre environnement de test, vous utilisez vos propres bases de données.
- Vous souhaitez pointer votre service vers un service dans un autre Namespace ou sur un autre cluster.
- Vous migrez une charge de travail vers Kubernetes. Lors de l'évaluation de l'approche, vous exécutez uniquement une partie de vos backends dans Kubernetes.
Dans n'importe lequel de ces scénarios, vous pouvez définir un service sans un sélecteur de pod. Par exemple:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
Étant donné que ce service n'a pas de sélecteur, l'objet Endpoint correspondant n'est pas créé automatiquement. Vous pouvez mapper manuellement le service à l'adresse réseau et au port où il s'exécute, en ajoutant manuellement un objet Endpoint:
apiVersion: v1
kind: Endpoints
metadata:
name: my-service
subsets:
- addresses:
- ip: 192.0.2.42
ports:
- port: 9376
Les IP de noeud final ne doivent pas être: loopback (127.0.0.0/8 pour IPv4, ::1/128 pour IPv6), ou link-local (169.254.0.0/16 et 224.0.0.0/24 pour IPv4, fe80::/64 pour IPv6).
Les adresses IP de noeud final ne peuvent pas être les adresses IP de cluster d'autres services Kubernetes, car kube-proxy ne prend pas en charge les adresses IP virtuelles en tant que destination.
L'accès à un service sans sélecteur fonctionne de la même manière que s'il avait un sélecteur.
Dans l'exemple ci-dessus, le trafic est routé vers le Endpoint unique défini dans le YAML: 192.0.2.42:9376
(TCP).
Un service ExternalName est un cas spécial de service qui n'a pas de sélecteurs et utilise des noms DNS à la place. Pour plus d'informations, consultez la section ExternalName plus loin dans ce document.
Endpoint Slices
Kubernetes v1.17 [beta]
Un Endpoint Slices est une ressource API qui peut fournir une alternative plus évolutive au Endpoints. Bien que conceptuellement assez similaire aux Endpoints, les Endpoint Slices permettent la distribution des endpoints réseau sur plusieurs ressources. Par défaut, un Endpoint Slice est considéré comme "plein" une fois qu'il atteint 100 endpoints, au delà, des Endpoint Slices addtionnels seront crées pour stocker tout autre endpoints.
Les Endpoint Slices fournissent des attributs et des fonctionnalités supplémentaires qui sont décrits en détail dans Endpoint Slices.
IP virtuelles et proxy de service
Chaque nœud d'un cluster Kubernetes exécute un kube-proxy
.
kube-proxy
est responsable de l'implémentation d'une forme d'IP virtuelle pour les Services
qui ne sont pas de type ExternalName
.
Pourquoi ne pas utiliser le DNS round-robin ?
Une question qui apparaît de temps en temps est pourquoi Kubernetes s'appuie sur le proxy pour transférer le trafic entrant vers les backends. Et les autres approches? Par exemple, serait-il possible de configurer des enregistrements DNS qui ont plusieurs valeurs A (ou AAAA pour IPv6), et de s'appuyer sur la résolution de nom à tour de rôle (round-robin)?
Il existe plusieurs raisons d'utiliser le proxy pour les services:
- Il existe une longue histoire d'implémentations DNS ne respectant pas les TTL d'enregistrement et mettant en cache les résultats des recherches de noms après leur expiration.
- Certaines applications n'effectuent des recherches DNS qu'une seule fois et mettent en cache les résultats indéfiniment.
- Même si les applications et les bibliothèques ont fait une bonne résolution, les TTL faibles ou nuls sur les enregistrements DNS pourraient imposer une charge élevée sur DNS qui devient alors difficile à gérer.
User space proxy mode
Dans ce mode, kube-proxy surveille le maître Kubernetes pour l'ajout et la suppression d'objets Service et Endpoint.
Pour chaque service, il ouvre un port (choisi au hasard) sur le nœud local.
Toutes les connexions à ce "port proxy" sont transmises par proxy à l'un des modules backend du service (comme indiqué via les Endpoints).
kube-proxy prend en compte le paramètre SessionAffinity
du service pour décider quel pod backend utiliser.
Enfin, le proxy de l'espace utilisateur installe des règles iptables qui capturent le trafic vers le service clusterIP
(qui est virtuel) et port
.
Les règles redirigent ce trafic vers le port proxy qui fait office de proxy pour le Pod de backend.
Par défaut, kube-proxy en mode espace utilisateur choisit un backend via un algorithme round-robin.
iptables
proxy mode
Dans ce mode, kube-proxy surveille le plan de contrôle Kubernetes pour l'ajout et la suppression d'objets Service et Endpoint. Pour chaque service, il installe des règles iptables, qui capturent le trafic vers le «clusterIP» et le «port» du service, et redirigent ce trafic vers l'un des ensembles principaux du service. Pour chaque objet Endpoint, il installe des règles iptables qui sélectionnent un Pod de backend.
Par défaut, kube-proxy en mode iptables choisit un backend au hasard.
L'utilisation d'iptables pour gérer le trafic a un coût système inférieur, car le trafic est géré par Linux netfilter sans avoir besoin de basculer entre l'espace utilisateur et l'espace noyau. Cette approche est également susceptible d'être plus fiable.
Si kube-proxy s'exécute en mode iptables et que le premier pod sélectionné ne répond pas, la connexion échoue. C'est différent du mode espace utilisateur: dans ce scénario, kube-proxy détecterait que la connexion au premier pod avait échoué et réessayerait automatiquement avec un pod backend différent.
Vous pouvez utiliser les readiness probes d'un Pod pour vérifier que les pods backend fonctionnent correctement, de sorte que kube-proxy en mode iptables ne voit que les backends testés comme sains. Cela signifie que vous évitez d'envoyer du trafic via kube-proxy vers un pod connu pour avoir échoué.
IPVS proxy mode
Kubernetes v1.11 [stable]
En mode ipvs
, kube-proxy surveille les Services et Endpoints Kubernetes. kube-proxy appelle l'interface netlink
pour créer les règles IPVS en conséquence et synchronise périodiquement les règles IPVS avec les Services et Endpoints Kubernetes.
Cette boucle de contrôle garantit que l'état IPVS correspond à l'état souhaité.
Lors de l'accès à un service, IPVS dirige le trafic vers l'un des pods backend.
Le mode proxy IPVS est basé sur des fonctions hooks de netfilter qui est similaire au mode iptables, mais utilise la table de hachage comme structure de données sous-jacente et fonctionne dans l'espace du noyau. Cela signifie que kube-proxy en mode IPVS redirige le trafic avec une latence plus faible que kube-proxy en mode iptables, avec de bien meilleures performances lors de la synchronisation des règles de proxy. Par rapport aux autres modes proxy, le mode IPVS prend également en charge un débit plus élevé de trafic réseau.
IPVS offre plus d'options pour équilibrer le trafic vers les pods d'arrière-plan; ceux-ci sont:
rr
: round-robinlc
: least connection (plus petit nombre de connexions ouvertes)dh
: destination hashingsh
: source hashingsed
: shortest expected delaynq
: never queue
Pour exécuter kube-proxy en mode IPVS, vous devez rendre IPVS Linux disponible sur le nœud avant de démarrer kube-proxy.
Lorsque kube-proxy démarre en mode proxy IPVS, il vérifie si les modules du noyau IPVS sont disponibles. Si les modules du noyau IPVS ne sont pas détectés, alors kube-proxy revient à fonctionner en mode proxy iptables.
Dans ces modèles de proxy, le trafic lié à l'IP: Port du service est dirigé vers un backend approprié sans que les clients ne sachent quoi que ce soit sur Kubernetes, les services ou les pods.
Si vous souhaitez vous assurer que les connexions d'un client particulier sont transmises à chaque fois au même pod, vous pouvez sélectionner l'affinité de session en fonction des adresses IP du client en définissant service.spec.sessionAffinity
sur" ClientIP "(la valeur par défaut est" None").
Vous pouvez également définir la durée maximale de session persistante en définissant service.spec.sessionAffinityConfig.clientIP.timeoutSeconds
de manière appropriée (la valeur par défaut est 10800, ce qui correspond à 3 heures).
Services multi-ports
Pour certains services, vous devez exposer plusieurs ports. Kubernetes vous permet de configurer plusieurs définitions de port sur un objet Service. Lorsque vous utilisez plusieurs ports pour un service, vous devez donner tous vos noms de ports afin qu'ils ne soient pas ambigus. Par exemple:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
- name: https
protocol: TCP
port: 443
targetPort: 9377
Comme pour tous les names Kubernetes en général, les noms de ports ne doivent contenir que des caractères alphanumériques en minuscules et -
.
Les noms de port doivent également commencer et se terminer par un caractère alphanumérique.
Par exemple, les noms 123-abc
et web
sont valides, mais 123_abc
et -web
ne le sont pas.
Choisir sa propre adresse IP
Vous pouvez spécifier votre propre adresse IP de cluster dans le cadre d'une demande de création de Service.
Pour ce faire, définissez le champ .spec.clusterIP
.
Par exemple, si vous avez déjà une entrée DNS existante que vous souhaitez réutiliser, ou des systèmes existants qui sont configurés pour une adresse IP spécifique et difficiles à reconfigurer.
L'adresse IP que vous choisissez doit être une adresse IPv4 ou IPv6 valide dans la plage CIDR service-cluster-ip-range
configurée pour le serveur API.
Si vous essayez de créer un service avec une valeur d'adresse de clusterIP non valide, le serveur API retournera un code d'état HTTP 422 pour indiquer qu'il y a un problème.
Découvrir les services
Kubernetes prend en charge 2 modes principaux de recherche d'un service: les variables d'environnement et DNS.
Variables d'environnement
Lorsqu'un pod est exécuté sur un nœud, le kubelet ajoute un ensemble de variables d'environnement pour chaque service actif.
Il prend en charge à la fois les variables Docker links (voir makeLinkVariables) et plus simplement les variables {SVCNAME}_SERVICE_HOST
et {SVCNAME}_SERVICE_PORT
, où le nom du service est en majuscules et les tirets sont convertis en underscore.
Par exemple, le service redis-master
qui expose le port TCP 6379 et a reçu l'adresse IP de cluster 10.0.0.11, produit les variables d'environnement suivantes:
REDIS_MASTER_SERVICE_HOST=10.0.0.11
REDIS_MASTER_SERVICE_PORT=6379
REDIS_MASTER_PORT=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
REDIS_MASTER_PORT_6379_TCP_PORT=6379
REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11
Lorsque vous avez un pod qui doit accéder à un service et que vous utilisez la méthode des variables d'environnement pour publier le port et l'IP du cluster sur les pods clients, vous devez créer le service avant que les pods clients n'existent. Sinon, ces pods clients n'auront pas leurs variables d'environnement remplies.
Si vous utilisez uniquement DNS pour découvrir l'IP du cluster pour un service, vous n'avez pas à vous soucier de ce problème de commande.
DNS
Vous pouvez (et devriez presque toujours) configurer un service DNS pour votre cluster Kubernetes à l'aide d'un add-on.
Un serveur DNS prenant en charge les clusters, tel que CoreDNS, surveille l'API Kubernetes pour les nouveaux services et crée un ensemble d'enregistrements DNS pour chacun. Si le DNS a été activé dans votre cluster, tous les pods devraient automatiquement être en mesure de résoudre les services par leur nom DNS.
Par exemple, si vous avez un service appelé "my-service"
dans un namespace Kubernetes "my-ns"
, le plan de contrôle et le service DNS agissant ensemble et créent un enregistrement DNS pour "my-service.my-ns"
.
Les Pods dans le Namespace "my-ns"
devrait être en mesure de le trouver en faisant simplement une recherche de nom pour my-service
("my-service.my-ns"
fonctionnerait également).
Les pods dans d'autres namespaces doivent utiliser le nom de my-service.my-ns
.
Ces noms seront résolus en IP de cluster attribuée pour le service.
Kubernetes prend également en charge les enregistrements DNS SRV (Service) pour les ports nommés.
Si le service "my-service.my-ns"
a un port nommé http
avec un protocole défini sur TCP
, vous pouvez effectuer une requête DNS SRV pour _http._tcp.my-service.my-ns
pour découvrir le numéro de port de http
, ainsi que l'adresse IP.
Le serveur DNS Kubernetes est le seul moyen d'accéder aux services ExternalName
.
Vous pouvez trouver plus d'informations sur la résolution de ExternalName
dans DNS Pods et Services.
Headless Services
Parfois, vous n'avez pas besoin de load-balancing et d'une seule IP de Service.
Dans ce cas, vous pouvez créer ce que l'on appelle des services "headless", en spécifiant explicitement "None" pour l'IP du cluster (.spec.clusterIP
).
Vous pouvez utiliser un service headless pour interfacer avec d'autres mécanismes de découverte de service, sans être lié à l'implémentation de Kubernetes.
Pour les services headless, une IP de cluster n'est pas allouée, kube-proxy ne gère pas ces services et aucun load-balancing ou proxy n'est effectué par la plateforme pour eux. La configuration automatique de DNS dépend de la définition ou non de sélecteurs par le service:
Avec sélecteurs
Pour les services headless qui définissent des sélecteurs, le controlleur des Endpoints crée des enregistrements Endpoints
dans l'API, et modifie la configuration DNS pour renvoyer des enregistrements (adresses) qui pointent directement vers les Pods
visés par le Service
.
Sans sélecteurs
Pour les services headless qui ne définissent pas de sélecteurs, le contrôleur des Endpoints ne crée pas d'enregistrements Endpoints
.
Cependant, le système DNS recherche et configure soit:
- Enregistrements CNAME pour les services de type
ExternalName
. - Un enregistrement pour tous les «Endpoints» qui partagent un nom avec le Service, pour tous les autres types.
Services de publication (ServiceTypes)
Pour certaines parties de votre application (par exemple, les frontaux), vous souhaiterez peut-être exposer un service sur une adresse IP externe, qui est en dehors de votre cluster.
Les «ServiceTypes» de Kubernetes vous permettent de spécifier le type de service que vous souhaitez. La valeur par défaut est «ClusterIP».
Les valeurs de Type
et leurs comportements sont:
ClusterIP
: Expose le service sur une IP interne au cluster. Le choix de cette valeur rend le service uniquement accessible à partir du cluster. Il s'agit duServiceType
par défaut.NodePort
: Expose le service sur l'IP de chaque nœud sur un port statique (leNodePort
). Un serviceClusterIP
, vers lequel le serviceNodePort
est automatiquement créé. Vous pourrez contacter le serviceNodePort
, depuis l'extérieur du cluster, en demandant<NodeIP>: <NodePort>
.LoadBalancer
: Expose le service en externe à l'aide de l'équilibreur de charge d'un fournisseur de cloud. Les servicesNodePort
etClusterIP
, vers lesquels les itinéraires de l'équilibreur de charge externe, sont automatiquement créés.ExternalName
: Mappe le service au contenu du champexternalName
(par exemplefoo.bar.example.com
), en renvoyant un enregistrementCNAME
avec sa valeur. Aucun proxy d'aucune sorte n'est mis en place.Note: Vous avez besoin de CoreDNS version 1.7 ou supérieure pour utiliser le typeExternalName
.
Vous pouvez également utiliser Ingress pour exposer votre service. Ingress n'est pas un type de service, mais il sert de point d'entrée pour votre cluster. Il vous permet de consolider vos règles de routage en une seule ressource car il peut exposer plusieurs services sous la même adresse IP.
Type NodePort
Si vous définissez le champ type
sur NodePort
, le plan de contrôle Kubernetes alloue un port à partir d'une plage spécifiée par l'indicateur --service-node-port-range
(par défaut: 30000-32767).
Chaque nœud assure le proxy de ce port (le même numéro de port sur chaque nœud) vers votre service.
Votre service signale le port alloué dans son champ .spec.ports[*].nodePort
.
Si vous souhaitez spécifier une ou des adresses IP particulières pour proxyfier le port, vous pouvez définir l'indicateur --nodeport-addresses
dans kube-proxy sur des blocs IP particuliers; cela est pris en charge depuis Kubernetes v1.10.
Cet indicateur prend une liste délimitée par des virgules de blocs IP (par exemple 10.0.0.0/8, 192.0.2.0/25) pour spécifier les plages d'adresses IP que kube-proxy doit considérer comme locales pour ce nœud.
Par exemple, si vous démarrez kube-proxy avec l'indicateur --nodeport-addresses=127.0.0.0/8
, kube-proxy sélectionne uniquement l'interface de boucle locale pour les services NodePort.
La valeur par défaut pour --nodeport-addresses
est une liste vide.
Cela signifie que kube-proxy doit prendre en compte toutes les interfaces réseau disponibles pour NodePort (qui est également compatible avec les versions antérieures de Kubernetes).
Si vous voulez un numéro de port spécifique, vous pouvez spécifier une valeur dans le champ nodePort
.
Le plan de contrôle vous attribuera ce port ou signalera l'échec de la transaction API.
Cela signifie que vous devez vous occuper vous-même des éventuelles collisions de ports.
Vous devez également utiliser un numéro de port valide, celui qui se trouve dans la plage configurée pour l'utilisation de NodePort.
L'utilisation d'un NodePort vous donne la liberté de configurer votre propre solution d'équilibrage de charge, de configurer des environnements qui ne sont pas entièrement pris en charge par Kubernetes, ou même d'exposer directement les adresses IP d'un ou plusieurs nœuds.
Notez que ce service est visible en tant que <NodeIP>: spec.ports[*].nodePort
et .spec.clusterIP: spec.ports[*].Port
.
(Si l'indicateur --nodeport-addresses
dans kube-proxy est défini,
Type LoadBalancer
Sur les fournisseurs de cloud qui prennent en charge les load balancers externes, la définition du champ type
sur LoadBalancer
provisionne un load balancer pour votre service.
La création réelle du load balancer se produit de manière asynchrone et les informations sur le load balancer provisionné sont publiées dans le champ .status.loadBalancer
.
Par exemple:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
clusterIP: 10.0.171.239
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 192.0.2.127
Le trafic provenant du load balancer externe est dirigé vers les Pods backend. Le fournisseur de cloud décide de la répartition de la charge.
Certains fournisseurs de cloud vous permettent de spécifier le loadBalancerIP
.
Dans ces cas, le load balancer est créé avec le loadBalancerIP
spécifié par l'utilisateur.
Si le champ loadBalancerIP
n'est pas spécifié, le loadBalancer est configuré avec une adresse IP éphémère.
Si vous spécifiez un loadBalancerIP
mais que votre fournisseur de cloud ne prend pas en charge la fonctionnalité, le champ loadBalancerIP
que vous définissez est ignoré.
LoadBalancer
.
Sur Azure, si vous souhaitez utiliser un type public spécifié par l'utilisateur loadBalancerIP
, vous devez d'abord créer une ressource d'adresse IP publique de type statique.
Cette ressource d'adresse IP publique doit se trouver dans le même groupe de ressources que les autres ressources créées automatiquement du cluster.
Par exemple, MC_myResourceGroup_myAKSCluster_eastus
.
Spécifiez l'adresse IP attribuée en tant que loadBalancerIP.
Assurez-vous d'avoir mis à jour le securityGroupName dans le fichier de configuration du fournisseur de cloud.
Pour plus d'informations sur le dépannage CreatingLoadBalancerFailed
relatif aux permissions consultez: Use a static IP address with the Azure Kubernetes Service (AKS) load balancer ou CreatingLoadBalancerFailed on AKS cluster with advanced networking.
Load Balancer interne
Dans un environnement mixte, il est parfois nécessaire d'acheminer le trafic des services à l'intérieur du même bloc d'adresse réseau (virtuel).
Dans un environnement DNS à horizon divisé, vous auriez besoin de deux services pour pouvoir acheminer le trafic externe et interne vers vos endpoints.
Vous pouvez y parvenir en ajoutant une des annotations suivantes à un service. L'annotation à ajouter dépend du fournisseur de services cloud que vous utilisez.
Sélectionnez l'un des onglets.
[...]
metadata:
name: my-service
annotations:
cloud.google.com/load-balancer-type: "Internal"
[...]
[...]
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-internal: "true"
[...]
[...]
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
[...]
[...]
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/openstack-internal-load-balancer: "true"
[...]
[...]
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/cce-load-balancer-internal-vpc: "true"
[...]
[...]
metadata:
annotations:
service.kubernetes.io/qcloud-loadbalancer-internal-subnetid: subnet-xxxxx
[...]
Prise en charge TLS sur AWS
Pour une prise en charge partielle de TLS / SSL sur des clusters exécutés sur AWS, vous pouvez ajouter trois annotations à un service LoadBalancer
:
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012
Le premier spécifie l'ARN du certificat à utiliser. Il peut s'agir soit d'un certificat d'un émetteur tiers qui a été téléchargé sur IAM, soit d'un certificat créé dans AWS Certificate Manager.
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: (https|http|ssl|tcp)
La deuxième annotation spécifie le protocole utilisé par un pod. Pour HTTPS et SSL, l'ELB s'attend à ce que le pod s'authentifie sur la connexion chiffrée, à l'aide d'un certificat.
HTTP et HTTPS sélectionnent le proxy de couche 7: l'ELB met fin à la connexion avec l'utilisateur, analyse les en-têtes et injecte l'en-tête X-Forwarded-For
avec l'adresse IP de l'utilisateur (les pods ne voient que l'adresse IP de l'ELB à l'autre extrémité de sa connexion) lors du transfert des demandes.
TCP et SSL sélectionnent le proxy de couche 4: l'ELB transfère le trafic sans modifier les en-têtes.
Dans un environnement à usage mixte où certains ports sont sécurisés et d'autres non chiffrés, vous pouvez utiliser les annotations suivantes:
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443,8443"
Dans l'exemple ci-dessus, si le service contenait trois ports, «80», «443» et «8443», alors «443» et «8443» utiliseraient le certificat SSL, mais «80» serait simplement un proxy HTTP.
A partir de Kubernetes v1.9, vous pouvez utiliser des stratégies SSL AWS prédéfinies avec des écouteurs HTTPS ou SSL pour vos services.
Pour voir quelles politiques sont disponibles, vous pouvez utiliser l'outil de ligne de commande aws
:
aws elb describe-load-balancer-policies --query 'PolicyDescriptions[].PolicyName'
Vous pouvez ensuite spécifier l'une de ces stratégies à l'aide de l'annotation "service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy
"; par exemple:
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy: "ELBSecurityPolicy-TLS-1-2-2017-01"
Prise en charge du protocole PROXY sur AWS
Pour activer protocole PROXY prise en charge des clusters exécutés sur AWS, vous pouvez utiliser l'annotation de service suivante:
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
Depuis la version 1.3.0, l'utilisation de cette annotation s'applique à tous les ports mandatés par l'ELB et ne peut pas être configurée autrement.
Journaux d'accès ELB sur AWS
Il existe plusieurs annotations pour gérer les journaux d'accès aux services ELB sur AWS.
L'annotation service.beta.kubernetes.io/aws-load-balancer-access-log-enabled
contrôle si les journaux d'accès sont activés.
L'annotation service.beta.kubernetes.io/aws-load-balancer-access-log-emit-interval
contrôle l'intervalle en minutes pour la publication des journaux d'accès.
Vous pouvez spécifier un intervalle de 5 ou 60 minutes.
L'annotation service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-name
contrôle le nom du bucket Amazon S3 où les journaux d'accès au load balancer sont stockés.
L'annotation service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix
spécifie la hiérarchie logique que vous avez créée pour votre bucket Amazon S3.
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-access-log-enabled: "true"
# Spécifie si les journaux d'accès sont activés pour le load balancer
service.beta.kubernetes.io/aws-load-balancer-access-log-emit-interval: "60"
# L'intervalle de publication des journaux d'accès.
# Vous pouvez spécifier un intervalle de 5 ou 60 (minutes).
service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-name: "my-bucket"
# Le nom du bucket Amazon S3 où les journaux d'accès sont stockés
service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix: "my-bucket-prefix/prod"
# La hiérarchie logique que vous avez créée pour votre bucket Amazon S3, par exemple `my-bucket-prefix/prod`
Drainage de connexion sur AWS
Le drainage des connexions pour les ELB classiques peut être géré avec l'annotation service.beta.kubernetes.io / aws-load-balancer-connection-draining-enabled
définie sur la valeur true
.
L'annotation service.beta.kubernetes.io / aws-load-balancer-connection-draining-timeout
peut également être utilisée pour définir la durée maximale, en secondes, pour garder les connexions existantes ouvertes avant de désenregistrer les instances.
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled: "true"
service.beta.kubernetes.io/aws-load-balancer-connection-draining-timeout: "60"
Autres annotations ELB
Il existe d'autres annotations pour gérer les Elastic Load Balancers décrits ci-dessous.
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "60"
# Délai, en secondes, pendant lequel la connexion peut être inactive (aucune donnée n'a été envoyée via la connexion) avant d'être fermée par le load balancer
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
# Spécifie si le load balancing inter-zones est activé pour le load balancer
service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: "environment=prod,owner=devops"
# Une liste de paires clé-valeur séparées par des virgules qui seront enregistrées en tant que balises supplémentaires dans l'ELB.
service.beta.kubernetes.io/aws-load-balancer-healthcheck-healthy-threshold: ""
# Nombre de contrôles de santé successifs réussis requis pour qu'un backend soit considéré comme sain pour le trafic.
# La valeur par défaut est 2, doit être comprise entre 2 et 10
service.beta.kubernetes.io/aws-load-balancer-healthcheck-unhealthy-threshold: "3"
# Nombre de contrôles de santé infructueux requis pour qu'un backend soit considéré comme inapte pour le trafic.
# La valeur par défaut est 6, doit être comprise entre 2 et 10
service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval: "20"
# Intervalle approximatif, en secondes, entre les contrôles d'intégrité d'une instance individuelle.
# La valeur par défaut est 10, doit être comprise entre 5 et 300
service.beta.kubernetes.io/aws-load-balancer-healthcheck-timeout: "5"
# Durée, en secondes, pendant laquelle aucune réponse ne signifie l'échec d'un contrôle de santé.
# Cette valeur doit être inférieure à la valeur service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval.
# La valeur par défaut est 5, doit être comprise entre 2 et 60
service.beta.kubernetes.io/aws-load-balancer-extra-security-groups: "sg-53fae93f,sg-42efd82e"
# Une liste de groupes de sécurité supplémentaires à ajouter à l'ELB
Prise en charge du load balancer réseau sur AWS
Kubernetes v1.15 [beta]
Pour utiliser un load balancer réseau sur AWS, utilisez l'annotation service.beta.kubernetes.io/aws-load-balancer-type
avec la valeur définie sur nlb
.
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
Contrairement aux équilibreurs de charge élastiques classiques, les équilibreurs de charge réseau (NLB) transfèrent l'adresse IP du client jusqu'au nœud.
Si un service est .spec.externalTrafficPolicy
est réglé sur Cluster
, l'adresse IP du client n'est pas propagée aux pods finaux.
En définissant .spec.externalTrafficPolicy
à Local
, les adresses IP des clients sont propagées aux pods finaux, mais cela peut entraîner une répartition inégale du trafic.
Les nœuds sans pods pour un service LoadBalancer particulier échoueront au contrôle de santé du groupe cible NLB sur le .spec.healthCheckNodePort
attribué automatiquement et ne recevront aucun trafic.
Pour obtenir un trafic uniforme, utilisez un DaemonSet ou spécifiez un pod anti-affinity pour ne pas localiser sur le même noeud.
Vous pouvez également utiliser les services NLB avec l'annotation load balancer internal.
Pour que le trafic client atteigne des instances derrière un NLB, les groupes de sécurité du nœud sont modifiés avec les règles IP suivantes:
Rule | Protocol | Port(s) | IpRange(s) | IpRange Description |
---|---|---|---|---|
Health Check | TCP | NodePort(s) (.spec.healthCheckNodePort for .spec.externalTrafficPolicy = Local ) |
VPC CIDR | kubernetes.io/rule/nlb/health=<loadBalancerName> |
Client Traffic | TCP | NodePort(s) | .spec.loadBalancerSourceRanges (defaults to 0.0.0.0/0 ) |
kubernetes.io/rule/nlb/client=<loadBalancerName> |
MTU Discovery | ICMP | 3,4 | .spec.loadBalancerSourceRanges (defaults to 0.0.0.0/0 ) |
kubernetes.io/rule/nlb/mtu=<loadBalancerName> |
Afin de limiter les IP clientes pouvant accéder à l'équilibreur de charge réseau, spécifiez loadBalancerSourceRanges
.
spec:
loadBalancerSourceRanges:
- "143.231.0.0/16"
.spec.loadBalancerSourceRanges
n'est pas défini, Kubernetes autorise le trafic de 0.0.0.0/0
vers les groupes de sécurité des nœuds.
Si les nœuds ont des adresses IP publiques, sachez que le trafic non NLB peut également atteindre toutes les instances de ces groupes de sécurité modifiés.
Autres annotations CLB sur Tencent Kubernetes Engine (TKE)
Il existe d'autres annotations pour la gestion des équilibreurs de charge cloud sur TKE, comme indiqué ci-dessous.
metadata:
name: my-service
annotations:
# Lier des load balancers avec des nœuds spécifiques
service.kubernetes.io/qcloud-loadbalancer-backends-label: key in (value1, value2)
# ID d'un load balancer existant
service.kubernetes.io/tke-existed-lbid:lb-6swtxxxx
# Paramètres personnalisés pour le load balancer (LB), ne prend pas encore en charge la modification du type LB
service.kubernetes.io/service.extensiveParameters: ""
# Paramètres personnalisés pour le listener LB
service.kubernetes.io/service.listenerParameters: ""
# Spécifie le type de Load balancer;
# valeurs valides: classic (Classic Cloud Load Balancer) ou application (Application Cloud Load Balancer)
service.kubernetes.io/loadbalance-type: xxxxx
# Spécifie la méthode de facturation de la bande passante du réseau public;
# valid values: TRAFFIC_POSTPAID_BY_HOUR(bill-by-traffic) and BANDWIDTH_POSTPAID_BY_HOUR (bill-by-bandwidth).
service.kubernetes.io/qcloud-loadbalancer-internet-charge-type: xxxxxx
# Spécifie la valeur de bande passante (plage de valeurs: [1,2000] Mbps).
service.kubernetes.io/qcloud-loadbalancer-internet-max-bandwidth-out: "10"
# Lorsque cette annotation est définie, les équilibreurs de charge n'enregistrent que les nœuds sur lesquels le pod s'exécute, sinon tous les nœuds seront enregistrés.
service.kubernetes.io/local-svc-only-bind-node-with-pod: true
Type ExternalName
Les services de type ExternalName mappent un service à un nom DNS, et non à un sélecteur standard tel que my-service
ou cassandra
.
Vous spécifiez ces services avec le paramètre spec.externalName
.
Cette définition de service, par exemple, mappe le service my-service
dans l'espace de noms prod
à my.database.example.com
:
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
Lors de la recherche de l'hôte my-service.prod.svc.cluster.local
, le service DNS du cluster renvoie un enregistrement CNAME
avec la valeur my.database.example.com
.
L'accès à «mon-service» fonctionne de la même manière que les autres services, mais avec la différence cruciale que la redirection se produit au niveau DNS plutôt que via un proxy ou un transfert.
Si vous décidez ultérieurement de déplacer votre base de données dans votre cluster, vous pouvez démarrer ses pods, ajouter des sélecteurs ou des Endpoints appropriés et modifier le type
du service.
Vous pouvez rencontrer des difficultés à utiliser ExternalName pour certains protocoles courants, notamment HTTP et HTTPS. Si vous utilisez ExternalName, le nom d'hôte utilisé par les clients à l'intérieur de votre cluster est différent du nom référencé par ExternalName.
Pour les protocoles qui utilisent des noms d'hôtes, cette différence peut entraîner des erreurs ou des réponses inattendues.
Les requêtes HTTP auront un en-tête Host:
que le serveur d'origine ne reconnaît pas; Les serveurs TLS ne pourront pas fournir de certificat correspondant au nom d'hôte auquel le client s'est connecté.
IP externes
S'il existe des adresses IP externes qui acheminent vers un ou plusieurs nœuds de cluster, les services Kubernetes peuvent être exposés sur ces "IP externes".
Le trafic qui pénètre dans le cluster avec l'IP externe (en tant qu'IP de destination), sur le port de service, sera routé vers l'un des Endpoints de service.
Les externalIPs
ne sont pas gérées par Kubernetes et relèvent de la responsabilité de l'administrateur du cluster.
Dans la spécification de service, «externalIPs» peut être spécifié avec n'importe lequel des «ServiceTypes».
Dans l'exemple ci-dessous, "my-service
" peut être consulté par les clients sur "80.11.12.10:80
" (externalIP:port
)
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
externalIPs:
- 80.11.12.10
Lacunes
Le proxy fonctionnant dans l'espace utilisateur pour les VIP peut fonctionner à petite ou moyenne échelle, mais montrera ses limites dans de très grands clusters avec des milliers de services. La proposition de conception originale pour les portails a plus de détails à ce sujet.
L'utilisation du proxy de l'espace utilisateur masque l'adresse IP source d'un paquet accédant à un service.
Cela rend certains types de filtrage réseau (pare-feu) impossibles.
Le mode proxy iptables n'obscurcit pas les adresses IP source dans le cluster, mais il affecte toujours les clients passant par un LoadBalancer
ou un NodePort
.
Le champ Type
est conçu comme une fonctionnalité imbriquée - chaque niveau s'ajoute au précédent.
Cela n'est pas strictement requis sur tous les fournisseurs de cloud (par exemple, Google Compute Engine n'a pas besoin d'allouer un NodePort
pour faire fonctionner LoadBalancer
, mais AWS le fait) mais l'API actuelle le requiert.
Implémentation IP virtuelle
Les informations précédentes devraient être suffisantes pour de nombreuses personnes qui souhaitent simplement utiliser les Services. Cependant, il se passe beaucoup de choses dans les coulisses qui méritent d'être comprises.
Éviter les collisions
L'une des principales philosophies de Kubernetes est que vous ne devez pas être exposé à des situations qui pourraient entraîner l'échec de vos actions sans aucune faute de votre part. Pour la conception de la ressource Service, cela signifie de ne pas vous faire choisir votre propre numéro de port si ce choix pourrait entrer en collision avec le choix de quelqu'un d'autre. C'est un échec d'isolement.
Afin de vous permettre de choisir un numéro de port pour vos Services, nous devons nous assurer qu'aucun deux Services ne peuvent entrer en collision. Kubernetes le fait en attribuant à chaque service sa propre adresse IP.
Pour garantir que chaque service reçoit une adresse IP unique, un allocateur interne met à jour atomiquement une carte d'allocation globale dans etcd avant de créer chaque service. L'objet de mappage doit exister dans le registre pour que les services obtiennent des affectations d'adresse IP, sinon les créations échoueront avec un message indiquant qu'une adresse IP n'a pas pu être allouée.
Dans le plan de contrôle, un contrôleur d'arrière-plan est responsable de la création de cette carte (nécessaire pour prendre en charge la migration à partir d'anciennes versions de Kubernetes qui utilisaient le verrouillage en mémoire). Kubernetes utilise également des contrôleurs pour vérifier les affectations non valides (par exemple en raison d'une intervention de l'administrateur) et pour nettoyer les adresses IP allouées qui ne sont plus utilisées par aucun service.
Service IP addresses
Contrairement aux adresses IP des pods, qui acheminent réellement vers une destination fixe, les adresses IP des services ne sont pas réellement répondues par un seul hôte. Au lieu de cela, kube-proxy utilise iptables (logique de traitement des paquets sous Linux) pour définir les adresses IP virtual qui sont redirigées de manière transparente selon les besoins. Lorsque les clients se connectent au VIP, leur trafic est automatiquement transporté vers un Endpoint approprié. Les variables d'environnement et DNS pour les services sont en fait remplis en termes d'adresse IP virtuelle (et de port) du service.
kube-proxy prend en charge trois modes proxy — espace utilisateur, iptables et IPVS — qui fonctionnent chacun légèrement différemment.
Userspace
À titre d'exemple, considérons l'application de traitement d'image décrite ci-dessus. Lorsque le service backend est créé, le maître Kubernetes attribue une adresse IP virtuelle, par exemple 10.0.0.1. En supposant que le port de service est 1234, le service est observé par toutes les instances kube-proxy dans le cluster. Lorsqu'un proxy voit un nouveau service, il ouvre un nouveau port aléatoire, établit une redirection iptables de l'adresse IP virtuelle vers ce nouveau port et commence à accepter les connexions sur celui-ci.
Lorsqu'un client se connecte à l'adresse IP virtuelle du service, la règle iptables entre en jeu et redirige les paquets vers le propre port du proxy. Le “Service proxy” choisit un backend, et commence le proxy du trafic du client vers le backend.
Cela signifie que les propriétaires de services peuvent choisir le port de leur choix sans risque de collision. Les clients peuvent simplement se connecter à une adresse IP et à un port, sans savoir à quels pods ils accèdent réellement.
iptables
Considérons à nouveau l'application de traitement d'image décrite ci-dessus. Lorsque le service backend est créé, le plan de contrôle Kubernetes attribue une adresse IP virtuelle, par exemple 10.0.0.1. En supposant que le port de service est 1234, le service est observé par toutes les instances de kube-proxy dans le cluster. Lorsqu'un proxy voit un nouveau service, il installe une série de règles iptables qui redirigent de l'adresse IP virtuelle vers des règles par service. Les règles par service sont liées aux règles des Endpoints qui redirigent le trafic (à l'aide du NAT de destination) vers les backends.
Lorsqu'un client se connecte à l'adresse IP virtuelle du service, la règle iptables entre en jeu. Un backend est choisi (soit en fonction de l'affinité de la session, soit au hasard) et les paquets sont redirigés vers le backend. Contrairement au proxy de l'espace utilisateur, les paquets ne sont jamais copiés dans l'espace utilisateur, le proxy de kube n'a pas besoin d'être exécuté pour que l'adresse IP virtuelle fonctionne et les nœuds voient le trafic provenant de l'adresse IP du client non modifiée.
Ce même flux de base s'exécute lorsque le trafic arrive via un port de nœud ou via un load balancer, bien que dans ces cas, l'adresse IP du client soit modifiée.
IPVS
Les opérations iptables ralentissent considérablement dans un cluster à grande échelle, par exemple 10000 services. IPVS est conçu pour l'équilibrage de charge et basé sur des tables de hachage dans le noyau. Ainsi, vous pouvez obtenir une cohérence des performances dans un grand nombre de services à partir d'un kube-proxy basé sur IPVS. De plus, kube-proxy basé sur IPVS a des algorithmes d'équilibrage de charge plus sophistiqués (le moins de connexions, localité, pondéré, persistance).
Objet API
Le service est une ressource de niveau supérieur dans l'API REST Kubernetes. Vous pouvez trouver plus de détails sur l'objet API sur: Service API object.
Protocoles pris en charge
TCP
Kubernetes v1.0 [stable]
Vous pouvez utiliser TCP pour tout type de service, et c'est le protocole réseau par défaut.
UDP
Kubernetes v1.0 [stable]
Vous pouvez utiliser UDP pour la plupart des services. Pour Services de type LoadBalancer, la prise en charge UDP dépend du fournisseur de cloud offrant cette fonctionnalité.
HTTP
Kubernetes v1.1 [stable]
Si votre fournisseur de cloud le prend en charge, vous pouvez utiliser un service dans le mode LoadBalancer pour configurer le proxy inverse HTTP / HTTPS externe, transmis au Endpoints du Service.
Protocole PROXY
Kubernetes v1.1 [stable]
Si votre fournisseur de cloud le prend en charge(eg, AWS), vous pouvez utiliser un service en mode LoadBalancer pour configurer un load balancer en dehors de Kubernetes lui-même, qui transmettra les connexions préfixées par PROXY protocol.
Le load balancer enverra une première série d'octets décrivant la connexion entrante, similaire à cet exemple
PROXY TCP4 192.0.2.202 10.0.42.7 12345 7\r\n
suivi des données du client.
SCTP
Kubernetes v1.12 [alpha]
Kubernetes prend en charge SCTP en tant que valeur de «protocole» dans les définitions de Service, Endpoint, NetworkPolicy et Pod en tant que fonctionnalité alpha.
Pour activer cette fonction, l'administrateur du cluster doit activer le flag SCTPSupport
sur l'apiserver, par exemple, --feature-gates=SCTPSupport=true,…
.
When the feature gate is enabled, you can set the protocol
field of a Service, Endpoint, NetworkPolicy or Pod to SCTP
.
Kubernetes sets up the network accordingly for the SCTP associations, just like it does for TCP connections.
Avertissements
Prise en charge des associations SCTP multi-hôtes
La prise en charge des associations SCTP multi-hôtes nécessite que le plug-in CNI puisse prendre en charge l'attribution de plusieurs interfaces et adresses IP à un pod.
Le NAT pour les associations SCTP multi-hôtes nécessite une logique spéciale dans les modules de noyau correspondants.
Service avec type=LoadBalancer
Windows
Userspace kube-proxy
Futurs développements
À l'avenir, la stratégie de proxy pour les services peut devenir plus nuancée que le simple équilibrage alterné, par exemple master-elected ou sharded. Nous prévoyons également que certains services auront des load balancer «réels», auquel cas l'adresse IP virtuelle y transportera simplement les paquets.
Le projet Kubernetes vise à améliorer la prise en charge des services L7 (HTTP).
Le projet Kubernetes prévoit d'avoir des modes d'entrée plus flexibles pour les services, qui englobent les modes ClusterIP, NodePort et LoadBalancer actuels et plus encore.
A suivre
- Voir Connecting Applications with Services
- Voir Ingress
- Voir Endpoint Slices
3.5.3 - DNS pour les services et les pods
Cette page fournit une vue d'ensemble du support DNS par Kubernetes.
Introduction
Kubernetes planifie un pod et un service DNS sur le cluster et configure les kubelets pour indiquer à chaque conteneur d'utiliser l'adresse IP du service DNS pour résoudre les noms DNS.
Quels composants obtiennent des noms DNS?
Chaque service défini dans le cluster (y compris le serveur DNS lui-même) a un nom DNS. Par défaut, la liste de recherche DNS du client d'un pod inclura le namespace (espace de nommage) du pod et le domaine par défaut du cluster. C'est mieux illustré par un exemple :
Supposons un service nommé foo
dans le namespace Kubernetes bar
. Un pod en cours d'exécution dans le namespace bar
peut rechercher ce service en faisant simplement une requête DNS "foo". Un pod qui tourne dans le namespace quux
peut rechercher ce service en effectuant une requête DNS foo.bar
.
Les sections suivantes détaillent les types d’enregistrement et la structure supportée par Kubernetes. Toute autre structure ou noms ou requêtes qui fonctionnent sont considérés comme des détails d'implémentation et peuvent changer sans préavis. Pour une spécification plus à jour, voir Découverte des services basée sur le DNS Kubernetes.
Services
Enregistrement A
Les services "normaux" (pas sans en-tête) se voient attribuer un enregistrement DNS A, et ont un nom sous la forme : mon-service.mon-namespace.svc.cluster.local
. La résolution de ce nom donne l'adresse ClusterIP
du service.
Les Services "Headless" (ou sans en-tête, c'est à dire sans ClusterIP) auront également un enregistrement type A, donc un nom sous la forme : mon-service.mon-namespace.svc.cluster.local
. Contrairement aux Services Normaux, cela résout l'ensemble des adresses IP des pods sélectionnés par le Service.
On s'attend à ce que les clients consomment l'ensemble ou utilisent le standard de sélection round-robin de l'ensemble.
Enregistrement SRV
Les enregistrements SRV sont créés pour les ports nommés faisant partie des services normaux ou Headless (sans en-tête).
Pour chaque port nommé, l'enregistrement SRV aurait la forme
_mon-nom-de-port._mon-protocole-de-port.mon-service.mon-namespace.svc.cluster.local
.
Pour un service régulier, cela se traduit par le numéro de port et le nom de domaine :
mon-service.mon-namespace.svc.cluster.local
.
Pour un service sans en-tête, cela pourrait être résolu en plusieurs réponses, une réponse pour chaque pod lié à ce service et qui contient le numéro de port, ainsi le nom de domaine du pod est sous la forme nom-auto-genere.mon-service.mon-namespace.svc.cluster.local
.
Pods
Enregistrement A
Lorsque cette option est activée, un enregistrement DNS A est attribué aux pods sous la forme adresse-ip-du-pod.mon-namespace.pod.cluster.local
.
Par exemple, un pod avec l’IP 1.2.3.4
dans le namespace (espace de nommage) default
avec un nom DNS de cluster.local
aurait une entrée : 1-2-3-4.default.pod.cluster.local
.
Nom d'hôte et sous-domaine d'un pod
Actuellement, lorsqu'un pod est créé, son nom d'hôte a la valeur metadata.name
du pod.
La spécification du pod a un champ optionnel hostname
, qui peut être utilisé pour spécifier la valeur du nom d'hôte du pod. Quand c'est spécifié, ce dernier a la priorité sur le nom du pod. Par exemple, si un pod a un hostname
ayant la valeur "mon-hote
", son nom d'hôte sera "mon-hote
".
La spécification du pod a également un champ optionnel subdomain
qui peut être utilisé pour spécifier son sous-domaine. Par exemple, un pod avec une valeur "foo
" du champ hostname
et une valeur "bar
" du champ subdomain
, dans le namespace "mon-namespace
", aura un nom de domaine (FQDN) "foo.bar.mon-namespace.svc.cluster.local
".
Exemple :
apiVersion: v1
kind: Service
metadata:
name: sous-domaine-par-default
spec:
selector:
name: busybox
clusterIP: None
ports:
- name: foo # En vrai, cette définition de port est à titre d'exemple, nous n'avons pas vraiment besoin de ports pour cette application.
port: 1234
targetPort: 1234
---
apiVersion: v1
kind: Pod
metadata:
name: busybox1
labels:
name: busybox
spec:
hostname: busybox-1
subdomain: sous-domaine-par-default
containers:
- image: busybox:1.28
command:
- sleep
- "3600"
name: busybox
---
apiVersion: v1
kind: Pod
metadata:
name: busybox2
labels:
name: busybox
spec:
hostname: busybox-2
subdomain: sous-domaine-par-default
containers:
- image: busybox:1.28
command:
- sleep
- "3600"
name: busybox
Si un service sans en-tête (headless) est dans le même namespace que son pod et avec le même nom que le sous-domaine, le serveur KubeDNS du cluster renvoie également un enregistrement A pour le nom d’hôte (hostname) du pod.
Par exemple, si un pod dont le nom d’hôte est " busybox-1
" et le sous-domaine est "sous-domaine-par-default
", et un service sans en-tête nommé "sous-domaine-par-default
" dans le même namespace, le pod verra son propre nom de domaine complet "busybox-1.sous-domaine-par-default.mon-namespace.svc.cluster.local
". Le DNS sert un enregistrement A portant ce nom, et pointant vers l'adresse IP du pod. Les deux Pods "busybox1
" et " busybox2
" peuvent avoir leurs enregistrements A distincts.
L’objet Endpoints peut spécifier le hostname
pour n’importe quelle adresse d'endpoint (noeud final), avec son adresse IP.
hostname
est requis pour la création de l'enregistrement A du pod. Un pod sans hostname
mais avec subdomain
(sous domaine) ne créera que l'enregistrement A pour le service sans en-tête (sous-domaine-par-default.mon-namespace.svc.cluster.local
), pointant vers l'adresse IP du pod.
Politique DNS du Pod
Les stratégies DNS peuvent être définies par pod. Actuellement, Kubernetes supporte des stratégies DNS qui sont spécifiques au pod. Ces politiques sont spécifiées dans le
Champ dnsPolicy
de la spécification du pod.
- "
Default
" : le pod hérite de la configuration de résolution des noms du node (noeud) sur lequel ce même pod est en train de tourner. Voir discussion liée pour plus de détails. - "
ClusterFirst
" : toute requête DNS ne correspondant pas au suffixe du domaine configuré dans le cluster, tel que "www.kubernetes.io
", sera transmise au serveur en amont hérité du node (noeud). Les administrateurs du cluster peuvent configurer des serveurs DNS supplémentaires que ce soit des serveurs secondaires (locaux) ou des vrais serveurs récursifs en amont pour faire la résolution. Voir discussion liée pour plus de détails sur la manière dont les requêtes DNS sont traitées dans ces cas. - "
ClusterFirstWithHostNet
" : pour les pods exécutés avechostNetwork
, vous devez explicitement définir sa politique DNS "ClusterFirstWithHostNet
". - "
None
" : une nouvelle valeur optionnelle introduite dans Kubernetes v1.9 (Beta dans v1.10). Elle permet à un pod d’ignorer les configurations DNS de l’environnement Kubernetes. Ainsi, toutes les configurations DNS sont supposées être fournies dans le champdnsConfig
de la spécification du pod. Voir la sous-section Config DNS ci-dessous.
dnsPolicy
n'est pas explicitement spécifié, ClusterFirst
sera utilisé.
L’exemple ci-dessous montre un pod avec une stratégie DNS "ClusterFirstWithHostNet
" car il a le champ hostNetwork
défini à true
.
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- image: busybox:1.28
command:
- sleep
- "3600"
imagePullPolicy: IfNotPresent
name: busybox
restartPolicy: Always
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
Configuration DNS du pod
Kubernetes v1.9 introduit une fonctionnalité Alpha (version beta de v1.10) qui permet aux utilisateurs d'avoir plus de contrôle sur les paramètres DNS d'un pod. Cette fonctionnalité est activée par défaut dans la version 1.10.
Pour activer cette fonctionnalité dans la version 1.9, l'administrateur du cluster doit activer la feature gate (porte de fonctionnalité) CustomPodDNS
sur les serveurs apiserver et kubelet, par exemple, "--feature-gates=CustomPodDNS=true,...
".
Lorsque la fonction est activée, les utilisateurs peuvent mettre le champ dnsPolicy
d’un pod à "None
" et ils peuvent rajouter un nouveau champ dnsConfig
à la spécification du pod.
Le champ dnsConfig
est facultatif et peut fonctionner avec toute configuration dnsPolicy
.
Cependant, quand dnsPolicy
du pod est réglé sur "None
", le champ dnsConfig
doit être explicitement spécifié.
Vous trouverez ci-dessous les propriétés qu'un utilisateur peut spécifier dans le champ dnsConfig
:
nameservers
: liste d'adresses IP qui seront utilisées comme serveurs DNS pour le Pod. Il peut y avoir au plus 3 adresses IP spécifiées. Quand le champdnsPolicy
du Pod est mis à "None
", la liste doit contenir au moins une adresse IP, sinon cette propriété est facultative. Les serveurs listés seront combinés avec les nameservers (serveurs de noms) de base générés à partir de la stratégie DNS spécifiée, tout en supprimant les adresses en double.searches
: liste des domaines de recherche DNS pour la recherche du nom d'hôte dans le pod. Cette propriété est facultative. Si elle est spécifiée, la liste fournie sera fusionnée avec les noms de domaine de recherche de base générés à partir de la stratégie DNS choisie. Les noms de domaine en double sont supprimés. Kubernetes permet au plus 6 domaines de recherche.options
: une liste optionnelle d'objets où chaque objet peut avoir une propriéténame
(obligatoire) et une propriétévalue
(facultatif). Le contenu de cette propriété sera fusionné avec les options générées à partir de la stratégie DNS spécifiée. Les entrées en double sont supprimées.
Voici un exemple de Pod avec des configurations DNS personnalisées :
apiVersion: v1
kind: Pod
metadata:
namespace: default
name: exemple-dns
spec:
containers:
- name: test
image: nginx
dnsPolicy: "None"
dnsConfig:
nameservers:
- 1.2.3.4
searches:
- ns1.svc.cluster.local
- mon.dns.search.suffix
options:
- name: ndots
value: "2"
- name: edns0
Lorsque le Pod ci-dessus est créé, le conteneur test
obtient le contenu suivant dans son fichier /etc/resolv.conf
:
nameserver 1.2.3.4
search ns1.svc.cluster.local mon.dns.search.suffix
options ndots:2 edns0
Pour la configuration IPv6, le chemin de recherche et le serveur de noms doivent être configurés comme suit :
$ kubectl exec -it exemple-dns -- cat /etc/resolv.conf
nameserver fd00:79:30::a
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
A suivre
Pour obtenir des recommendations sur l’administration des configurations DNS, consultez Configurer le service DNS
3.5.4 - Ingress
Un Ingress est un objet Kubernetes qui gère l'accès externe aux services dans un cluster, généralement du trafic HTTP.
Un Ingress peut fournir un équilibrage de charge, une terminaison TLS et un hébergement virtuel basé sur un nom.
Terminologie
Par souci de clarté, ce guide définit les termes suivants :
- Nœud (Node) : une seule machine virtuelle ou physique dans un cluster Kubernetes.
- Cluster : groupe de nœuds protégés par un pare-feu du trafic provenant d'Internet et constituant les principales ressources de calcul gérées par Kubernetes.
- Routeur Edge : routeur appliquant la stratégie de pare-feu pour votre cluster. Il peut s’agir d’une passerelle gérée par un fournisseur de cloud ou d’un matériel physique.
- Réseau de cluster : ensemble de liens, logiques ou physiques, facilitant la communication au sein d'un cluster selon le modèle de réseau Kubernetes.
- Service : un Kubernetes Service identifiant un ensemble de pods à l'aide de sélecteurs d'étiquettes. Sauf indication contraire, les services sont supposés avoir des adresses IP virtuelles routables uniquement dans le réseau du cluster.
Qu'est-ce qu'un Ingress ?
Ingress (ou une entrée réseau), ajouté à Kubernetes v1.1, expose les routes HTTP et HTTPS de l'extérieur du cluster à des services au sein du cluster. Le routage du trafic est contrôlé par des règles définies sur la ressource Ingress.
internet
|
[ Ingress ]
--|-----|--
[ Services ]
Un Ingress peut être configuré pour donner aux services des URLs accessibles de l'extérieur, un équilibrage du trafic de charge externe, la terminaison SSL/TLS et un hébergement virtuel basé sur le nom. Un contrôleur d'Ingress est responsable de l'exécution de l'Ingress, généralement avec un load-balancer (équilibreur de charge), bien qu'il puisse également configurer votre routeur périphérique ou des interfaces supplémentaires pour aider à gérer le trafic.
Un Ingress n'expose pas de ports ni de protocoles arbitraires. Exposer des services autres que HTTP et HTTPS à Internet généralement utilise un service de type Service.Type=NodePort ou Service.Type=LoadBalancer.
Conditions préalables
Kubernetes v1.1 [beta]
Avant de commencer à utiliser un Ingress, vous devez comprendre certaines choses. Un Ingress est une ressource en "version Beta".
GCE/GKE (Google Cloud Engine / Google Kubernetes Engine) déploie un contrôleur d’Ingress sur le master (le maître de kubernetes). Revoir les limitations beta de ce contrôleur si vous utilisez GCE/GKE.
Dans les environnements autres que GCE/GKE, vous devrez peut-être déployer un contrôleur d'Ingress. Il y a un certain nombre de contrôleurs d'Ingress parmi lesquels vous pouvez choisir.
Avant de commencer
Dans l’idéal, tous les contrôleurs d’Ingress devraient correspondre à cette spécification. Cependant le fonctionnement est légèrement différent d'un contrôleur à un autre (en fonction de son implémentation).
La ressource Ingress
Exemple de ressource Ingress minimale :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /testpath
pathType: Prefix
backend:
service:
name: test
port:
number: 80
Comme pour toutes les autres ressources Kubernetes, un Ingress (une entrée) a besoin des champs apiVersion
, kind
et metadata
.
Pour des informations générales sur l'utilisation des fichiers de configuration, voir déployer des applications, configurer des conteneurs, gestion des ressources.
Ingress utilise fréquemment des annotations pour configurer certaines options en fonction du contrôleur Ingress, dont un exemple
est l'annotation rewrite-target.
Différents Ingress controller prennent en charge différentes annotations. Consultez la documentation du contrôleur Ingress de votre choix pour savoir quelles annotations sont prises en charge.
La spécification de la ressource Ingress dispose de toutes les informations nécessaires pour configurer un loadbalancer ou un serveur proxy. Plus important encore, il contient une liste de règles d'appariement de toutes les demandes entrantes. La ressource Ingress ne supporte que les règles pour diriger le trafic HTTP.
Ingress rules
Chaque règle http contient les informations suivantes :
- Un hôte optionnel. Dans cet exemple, aucun hôte n'est spécifié. La règle s'applique donc à tous les appels entrants. Le trafic HTTP via l'adresse IP est spécifié. Si un hôte est fourni (par exemple, foo.bar.com), les règles s’appliquent à cet hôte.
- une liste de chemins (par exemple, /testpath), chacun étant associé à un backend associé défini par un
serviceName
etservicePort
. L’hôte et le chemin doivent correspondre au contenu d’une demande entrante avant que le load-balancer ne dirige le trafic vers le service référencé. - Un backend est une combinaison de noms de services et de ports, comme décrit dans services doc. Les requêtes HTTP (et HTTPS) envoyées à l'Ingress correspondant à l'hôte et au chemin de la règle seront envoyées au backend indiqué.
Un backend par défaut est souvent configuré dans un contrôleur d’Ingress qui traite toutes les demandes qui ne correspondent à aucun chemin dans la spécification.
Backend par défaut
Un Ingress sans règles envoie tout le trafic à un seul backend par défaut. Le backend par défaut est généralement une option de configuration du Contrôleur d'ingress et n'est pas spécifié dans vos ressources Ingress.
Si aucun des hôtes ou chemins ne correspond à la demande HTTP dans les objets Ingress, le trafic est routé vers votre backend par défaut.
Types d'Ingress
Ingress pour service unique
Il existe des concepts Kubernetes qui vous permettent d’exposer un seul service. (voir alternatives). Vous pouvez également le faire avec un Ingress en spécifiant un backend par défaut sans règles.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
spec:
defaultBackend:
service:
name: testsvc
port:
number: 80
Si vous le créez en utilisant kubectl create -f
, vous devriez voir :
kubectl get ingress test-ingress
NAME HOSTS ADDRESS PORTS AGE
test-ingress * 107.178.254.228 80 59s
Où 107.178.254.228
est l’adresse IP allouée par le contrôleur d’Ingress pour satisfaire cette entrée.
<pending>
(en attente).
Fanout simple
Une configuration de type fanout achemine le trafic d'une adresse IP unique vers plusieurs services, en se basant sur l'URI HTTP demandée. Une entrée vous permet de garder le nombre de loadbalancers au minimum. Par exemple, une configuration comme :
foo.bar.com -> 178.91.123.132 -> / foo service1:4200
/ bar service2:8080
ceci nécessitera un Ingress défini comme suit :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: simple-fanout-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
pathType: Prefix
backend:
service:
name: service1
port:
number: 4200
- path: /bar
pathType: Prefix
backend:
service:
name: service2
port:
number: 8080
Lorsque vous créez l'ingress avec kubectl create -f
:
kubectl describe ingress simple-fanout-example
Name: simple-fanout-example
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo service1:4200 (10.8.0.90:4200)
/bar service2:8080 (10.8.0.91:8080)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 22s loadbalancer-controller default/test
Le contrôleur d’Ingress fournit une implémentation spécifique aux load-balancers qui satisfait l'Ingress, tant que les services (s1
, s2
) existent.
Lorsque cela est fait, vous pouvez voir l’adresse du load-balancer sur le champ d'adresse.
Hébergement virtuel basé sur le nom
Les hôtes virtuels basés sur des noms prennent en charge le routage du trafic HTTP vers plusieurs noms d'hôte basés sur la même adresse IP.
foo.bar.com --| |-> foo.bar.com s1:80
| 178.91.123.132 |
bar.foo.com --| |-> bar.foo.com s2:80
L’Ingress suivant indique au load-balancer de router les requêtes en fonction de En-tête du hôte.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
- host: bar.foo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service2
port:
number: 80
Si vous créez une ressource Ingress sans aucun hôte défini dans les règles, tout trafic Web à destination de l'adresse IP de votre contrôleur d'Ingress peut être mis en correspondance sans qu'un hôte virtuel basé sur le nom ne soit requis. Par exemple, la ressource Ingress suivante acheminera le trafic demandé pour first.bar.com
au service1
second.foo.com
au service2
, et à tout trafic à l'adresse IP sans nom d'hôte défini dans la demande (c'est-à-dire sans en-tête de requête présenté) au service3
.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: first.bar.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
- host: second.foo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service2
port:
number: 80
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service3
port:
number: 80
TLS
Vous pouvez sécuriser un Ingress en définissant un secret qui contient une clé privée et un certificat TLS. Actuellement, l'Ingress prend seulement en charge l'unique port TLS, 443, et suppose une terminaison TLS. Si la section de configuration TLS dans un Ingress spécifie différents hôtes, ils seront multiplexés sur le même port en fonction du nom d’hôte spécifié via l'extension SNI TLS (à condition que le contrôleur d’Ingress prenne en charge SNI). Le secret de TLS doit contenir les clés tls.crt
et tls.key
contenant le certificat et clé privée à utiliser pour TLS, par exemple :
apiVersion: v1
data:
tls.crt: base64 encoded cert
tls.key: base64 encoded key
kind: Secret
metadata:
name: testsecret-tls
namespace: default
type: kubernetes.io/tls
Référencer ce secret dans un Ingress indiquera au contrôleur d'Ingress de sécuriser le canal du client au load-balancer à l'aide de TLS. Vous devez vous assurer que le secret TLS que vous avez créé provenait d'un certificat contenant un Common Name (CN), aussi appelé nom de domaine pleinement qualifié (FQDN), pour https-example.foo.com
.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-example-ingress
spec:
tls:
- hosts:
- https-example.foo.com
secretName: testsecret-tls
rules:
- host: https-example.foo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
L'équilibrage de charge
Un contrôleur d’Ingress est démarré avec certains paramètres de politique d’équilibrage de charge qui s'appliquent à toutes les entrées, tels que l'algorithme d'équilibrage de la charge, le régime de pondérations des backends, et d'autres. Les concepts un peu plus avancés d'équilibrage de charge (p. ex. sessions persistantes, pondérations dynamiques) ne sont pas encore exposés pour l'Ingress. Vous pouvez toujours obtenir ces fonctionnalités via le service loadbalancer.
Il est également intéressant de noter que même si les health checks (contrôles de santé) ne sont pas exposés directement via l'Ingress, il existe des concepts parallèles dans Kubernetes, tels que readiness probes qui vous permettent d'obtenir le même résultat final. Veuillez consulter les documents spécifiques au contrôleur pour voir comment il gère les health checks. (nginx,GCE).
Mise à jour d'un Ingress
Pour mettre à jour un Ingress existant afin d'ajouter un nouvel hôte, vous pouvez le mettre à jour en modifiant la ressource :
kubectl describe ingress test
Name: test
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo s1:80 (10.8.0.90:80)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 35s loadbalancer-controller default/test
kubectl edit ingress test
Cela devrait faire apparaître un éditeur avec le yaml existant, modifiez-le pour inclure le nouvel hôte :
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
service:
name: s1
port:
number: 80
path: /foo
pathType: Prefix
- host: bar.baz.com
http:
paths:
- backend:
service:
name: s2
port:
number: 80
path: /foo
pathType: Prefix
..
L'enregistrement du yaml mettra à jour la ressource dans le serveur d'API, ce qui devrait indiquer au contrôleur d'Ingress de reconfigurer le load-balancer.
kubectl describe ingress test
Name: test
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo s1:80 (10.8.0.90:80)
bar.baz.com
/foo s2:80 (10.8.0.91:80)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 45s loadbalancer-controller default/test
Vous pouvez obtenir le même résultat en appelant kubectl replace -f
sur un fichier Ingress yaml modifié.
Échec dans les zones de disponibilité
Les techniques permettant de répartir le trafic sur plusieurs domaines de défaillance diffèrent d'un fournisseur de cloud à l'autre. Veuillez consulter la documentation du Contrôleur d'ingress pour plus de détails. Vous pouvez également vous référer à la documentation de la fédération pour plus d'informations sur le déploiement d'Ingress dans un cluster fédéré.
Travail futur
Suivez SIG network (groupe d'intérêt spécial Réseau) pour plus de détails sur l'évolution de l'Ingress et des ressources associées. Vous pouvez également suivre le Dépôt Ingress pour plus de détails sur l'évolution des différents contrôleurs d’Ingress.
Alternatives
Vous pouvez exposer un service de plusieurs manières sans impliquer directement la ressource Ingress :
- Utilisez Service.Type=LoadBalancer
- Utilisez Service.Type=NodePort
- Utilisez un Proxy du port
A suivre
3.6 - Stockage
3.6.1 - Volumes
Les fichiers sur disque dans un conteneur sont éphémères, ce qui présente des problèmes pour
des applications non-triviales lorsqu'elles s'exécutent dans des conteneurs. Premièrement, lorsqu'un
conteneur plante, kubelet va le redémarrer mais les fichiers seront perdus - le conteneur démarre
avec un état propre. Deuxièmement, lorsque plusieurs conteneurs s'exécutent ensemble dans un Pod
,
il est souvent nécessaire de partager des fichiers entre ces conteneurs. L'abstraction Kubernetes
Volume
résout ces deux problèmes.
Une connaissance des Pods est suggérée.
Contexte
Docker a également un concept de volumes, bien qu'il soit, dans une certaine mesure, plus relâché et moins géré. Avec Docker, un volume est simplement un dossier sur le disque ou dans un autre conteneur. Les durées de vie ne sont pas gérées et, jusqu'à très récemment, seuls les volumes supportés par un disque local l'étaient. Docker fournit maintenant des pilotes de volume, mais la fonctionnalité est très limitée pour le moment (par exemple, à partir de Docker 1.7, seulement un pilote de volume est autorisé par conteneur et il n'est pas possible de passer des paramètres aux volumes).
Un volume Kubernetes, en revanche, a une durée de vie explicite - la même que le Pod qui l'inclut. Par conséquent, un volume survit aux conteneurs qui s'exécutent à l'intérieur du Pod et les données sont préservées lorsque le conteneur redémarre. Bien sûr, lorsqu'un Pod cesse d'exister, le volume va également cesser d'exister. Peut-être plus important encore, Kubernetes supporte de nombreux types de volumes et un Pod peut en utiliser plusieurs simultanément.
À la base, un volume est juste un dossier, contenant possiblement des données, qui est accessible aux conteneurs dans un Pod. La manière dont ce dossier est créé, le support qui le sauvegarde et son contenu sont déterminés par le type de volume utilisé.
Pour utiliser un volume, un Pod spécifie les volumes à fournir au Pod (le champ .spec.volumes
)
et où les monter dans les conteneurs (le champ .spec.containers.volumeMounts
).
Un processus dans un conteneur a une vue système de fichiers composée de son image et de ses volumes Docker. L'image Docker est à la racine de la hiérarchie du système de fichiers et tous les volumes sont montés sur les chemins spécifiés dans l'image. Les volumes ne peuvent pas être montés sur d'autres volumes ou avoir des liens physiques vers d'autres volumes. Chaque conteneur dans le Pod doit spécifier indépendamment où monter chaque volume.
Types de Volumes
Kubernetes supporte plusieurs types de Volumes:
- awsElasticBlockStore
- azureDisk
- azureFile
- cephfs
- cinder
- configMap
- csi
- downwardAPI
- emptyDir
- fc (fibre channel)
- flexVolume
- flocker
- gcePersistentDisk
- gitRepo (deprecated)
- glusterfs
- hostPath
- iscsi
- local
- nfs
- persistentVolumeClaim
- projected
- portworxVolume
- quobyte
- rbd
- scaleIO
- secret
- storageos
- vsphereVolume
Toute contribution supplémentaire est la bienvenue.
awsElasticBlockStore
Un type de volume awsElasticBlockStore
monte un Volume EBS d'Amazon Web Services (AWS) dans un Pod.
À la différence de emptyDir
, qui est écrasé lorsqu'un Pod est supprimé, le contenu d'un volume EBS
est préservé et le volume est seulement démonté. Cela signifie qu'un volume EBS peut être prérempli avec des données et que les données peuvent être transmises entre les Pods.
aws ec2 create-volume
ou l'API AWS avant de pouvoir l'utiliser.
Des restrictions existent lorsque l'on utilise un volume awsElasticBlockStore
:
- les nœuds dans lesquels les Pods s'exécutent doivent être des instances AWS EC2
- ces instances doivent être dans la même région et la même zone de disponibilité que le volume EBS
- EBS supporte uniquement le montage d'un volume par une seule instance EC2
Création d'un volume EBS
Avant que vous puissiez utiliser un volume EBS dans un Pod, vous devez le créer.
aws ec2 create-volume --availability-zone=eu-west-1a --size=10 --volume-type=gp2
Assurez-vous que la zone correspond à la zone de votre grappe de serveurs (cluster). (Et vérifiez aussi que la taille et le type du volume EBS conviennent à votre utilisation!)
Exemple de configuration AWS EBS
apiVersion: v1
kind: Pod
metadata:
name: test-ebs
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-ebs
name: test-volume
volumes:
- name: test-volume
# Ce volume AWS EBS doit déjà exister.
awsElasticBlockStore:
volumeID: <volume-id>
fsType: ext4
Migration CSI
Kubernetes v1.14 [alpha]
La fonctionnalité de migration CSI pour awsElasticBlockStore, lorsque activée, fixe toutes les opérations de plugin depuis le plugin "in-tree" vers le pilote de l'interface CSI (Container Storage Interface) ebs.csi.aws.com
.
Afin d'utiliser cette fonctionnalité, le Pilote AWS EBS CSI doit être installé dans le cluster et les fonctionnalités Alpha CSIMigration
et CSIMigrationAWS
doivent être activées.
azureDisk
Un type de volume azureDisk
est utilisé pour monter un disque de données (Data Disk) dans un Pod.
Plus de détails sont disponibles ici.
Migration CSI
Kubernetes v1.15 [alpha]
La fonctionnalité de migration CSI pour azureDisk, lorsque activée, fixe toutes les opérations de plugin depuis le plugin "in-tree" vers le pilote de l'interface CSI (Container Storage Interface) disk.csi.azure.com
.
Afin d'utiliser cette fonctionnalité, le Pilote Azure Disk CSI doit être installé dans le cluster et les fonctionnalités Alpha CSIMigration
et CSIMigrationAzureDisk
doivent être activées.
azureFile
Un type de volume azureFile
est utilisé pour monter un volume de fichier Microsoft Azure (SMB 2.1 et 3.0) dans un Pod.
Plus de détails sont disponibles ici.
Migration CSI
Kubernetes v1.15 [alpha]
La fonctionnalité de migration CSI pour azureFile, lorsque activée, fixe toutes les opérations de plugin depuis le plugin "in-tree" vers le pilote de l'interface CSI (Container Storage Interface) file.csi.azure.com
.
Afin d'utiliser cette fonctionnalité, le Pilote Azure File CSI doit être installé dans le cluster et les fonctionnalités Alpha CSIMigration
et CSIMigrationAzureFile
doivent être activées.
cephfs
Un volume cephfs
permet de monter un volume CephFS existant dans un Pod.
Contrairement à emptyDir
, qui est écrasé quand un Pod est supprimé, le contenu d'un volume cephfs
est préservé et le volume est simplement démonté.
Cela signifie qu'un volume CephFS peut être prérempli avec des données et ces données peuvent être transmises entre les Pods.
CephFS peut être monté plusieurs fois en écriture simultanément.
Voir l'exemple CephFS pour plus de détails.
cinder
cinder
est utilisé pour monter un volume Cinder OpenStack dans un Pod.
Exemple de configuration d'un volume Cinder
apiVersion: v1
kind: Pod
metadata:
name: test-cinder
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-cinder-container
volumeMounts:
- mountPath: /test-cinder
name: test-volume
volumes:
- name: test-volume
# Ce volume OpenStack doit déjà exister.
cinder:
volumeID: <volume-id>
fsType: ext4
Migration CSI
Kubernetes v1.14 [alpha]
La fonctionnalité de migration CSI pour Cinder, lorsque activée, fixe toutes les opérations de plugin depuis le plugin "in-tree" vers le pilote de l'interface CSI (Container Storage Interface) cinder.csi.openstack.org
.
Afin d'utiliser cette fonctionnalité, le Pilote Cinder CSI doit être installé dans le cluster et les fonctionnalités Alpha CSIMigration
et CSIMigrationOpenStack
doivent être activées.
configMap
La ressource configMap
fournit un moyen d'injecter des données de configuration dans les Pods.
Les données stockées dans un objet ConfigMap
peuvent être référencées dans un volume de type configMap
et être ensuite consommées par des applications conteneurisées s'exécutant dans un Pod.
Lorsque l'on référence un objet configMap
, on peut simplement fournir son nom dans le volume
pour le référencer. On peut également personnaliser le chemin pour utiliser une entrée spécifique dans
la ConfigMap. Par exemple, pour monter la ConfigMap log-config
sur un Pod appelé configmap-pod
,
vous pourriez utiliser le YAML suivant :
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: test
image: busybox
volumeMounts:
- name: config-vol
mountPath: /etc/config
volumes:
- name: config-vol
configMap:
name: log-config
items:
- key: log_level
path: log_level
La ConfigMap log-config
est montée comme un volume et tout le contenu stocké dans son entrée log_level
est monté dans le Pod au chemin "/etc/config/log_level
".
À noter que ce chemin est dérivé du mountPath
du volume et le path
est étiqueté avec la clef log_level
.
downwardAPI
Un volume downwardAPI
est utilisé pour rendre disponibles aux applications les données de l'API Downward.
Il monte un dossier et écrit les données demandées dans des fichiers de texte brut.
Voir l'exemple de volume downwardAPI
pour plus de détails.
emptyDir
Un volume emptyDir
est d'abord créé lorsqu'un Pod est assigné à un nœud et existe aussi longtemps que le Pod s'exécute sur ce nœud.
Comme le nom l'indique, le volume est initialement vide. Les conteneurs dans le Pod peuvent tous lire et écrire les mêmes fichiers dans le volume emptyDir
, bien que ce volume puisse être monté sur le même ou différents chemins dans chaque conteneur.
Lorsqu'un Pod est supprimé d'un nœud pour une raison quelconque, les données dans le emptyDir
sont supprimées à jamais.
emptyDir
sont protégées en cas de plantage du conteneur.
Des cas d'utilisation pour un emptyDir
peuvent être :
- un espace de travail, par exemple pour un tri fusion sur disque.
- l'établissement d'un point de reprise d'un long calcul à des fins de récupération des données après un crash.
- le stockage de fichiers qu'un conteneur de gestion de contenu va chercher pendant qu'un conteneur serveur web expose les données.
Par défaut, les volumes emptyDir
sont stockés sur tout médium supporté par le nœud - que ce soit un disque dur, un disque SSD ou un stockage réseau, dépendamment de l'environnement.
Cependant, vous pouvez définir le champ emptyDir.medium
à "Memory"
pour indiquer à Kubernetes de monter un tmpfs (système de fichiers supporté par la RAM) pour vous à la place.
Tandis que tmpfs est très rapide, soyez conscient qu'au contraire des disques, un tmpfs est effacé au redémarrage du nœud et tous les fichiers que vous écrivez seront comptabilisés dans la limite de mémoire de votre conteneur.
Exemple de Pod
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
fc (fibre channel)
Un volume fc
permet à un volume Fibre Channel existant d'être monté dans un Pod.
Vous pouvez spécifier une ou plusieurs cibles World Wide Names en utilisant le paramètre
targetWWNs
dans votre configuration de volume.
Si plusieurs WWNs sont spécifiés, targetWWNs s'attend à ce que ces WWNs proviennent de connexions multi-path.
Voir l'exemple FC pour plus de détails.
flocker
Flocker est un gestionnaire de volumes de données en cluster open-source. Il assure la gestion et l'orchestration de volumes de données supportés par divers serveurs de stockage.
Un volume flocker
permet de monter un ensemble de données Flocker dans un Pod.
Si l'ensemble de données n'existe pas déjà dans Flocker, il doit d'abord être créé avec la CLI Flocker ou en utilisant l'API Flocker.
Si l'ensemble de données existe déjà, il sera réattaché par Flocker au nœud sur lequel le Pod est planifié.
Cela signifie que les données peuvent être transmises entre les Pods selon les besoins.
Voir l'exemple Flocker pour plus de détails.
gcePersistentDisk
Un volume gcePersistentDisk
monte un Disque Persistant Google Compute Engine (GCE) dans un Pod.
À la différence d'un emptyDir
, qui est écrasé lorsqu'un Pod est supprimé, le contenu d'un disque persistant est préservé et le volume est simplement démonté. Cela signifie qu'un disque persistant peut être prérempli avec des données et que ces données peuvent être transmises entre les Pods.
gcloud
, l'API GCE ou l'interface utilisateur avant de pouvoir utiliser ce disque.
Des restrictions existent lors de l'utilisation d'un gcePersistentDisk
:
- les nœuds sur lesquels les Pods s'exécutent doivent être des machines virtuelles (VMs) GCE.
- ces VMs doivent se trouver dans le même projet et la même zone GCE que le disque persistant
Une fonctionnalité des disques persistants est qu'ils peuvent être montés en lecture seule par plusieurs consommateurs simultanément. Cela signifie que vous pouvez préremplir un disque persistant avec votre jeu de données et l'exposer en parallèle à partir d'autant de Pods que nécessaire. Malheureusement, les disques persistants peuvent seulement être montés par un seul consommateur en mode lecture-écriture - les écritures simultanées ne sont pas autorisées.
Utiliser un disque persistant dans un Pod contrôlé par un ReplicationController échouera à moins que le disque persistant soit en lecture seule ou que le nombre de répliques soit de 0 ou 1.
Création d'un disque persistant
Avant de pouvoir utiliser un disque persistant GCE avec un Pod, vous devez le créer.
gcloud compute disks create --size=500GB --zone=us-central1-a my-data-disk
Exemple de Pod
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
# Ce disque persistant GCE doit déjà exister.
gcePersistentDisk:
pdName: my-data-disk
fsType: ext4
Disques persistants régionaux
Kubernetes v1.10 [beta]
La fonctionnalité de disques persistants régionaux (Regional Persistent Disks) permet la création de disques persistants disponibles dans deux zones à l'intérieur d'une même région. Afin d'utiliser cette fonctionnalité, le volume doit être provisionné en tant que PersistentVolume; le référencement du volume directement depuis un Pod n'est pas supporté.
Provisionnement manuel d'un disque persistant régional en tant que PersistentVolume
Le provisionnement dynamique est possible en utilisant une StorageClass pour un disque persistant GCE. Avant de créer un PersistentVolume, vous devez créer le disque persistant :
gcloud beta compute disks create --size=500GB my-data-disk
--region us-central1
--replica-zones us-central1-a,us-central1-b
Exemple de spec PersistentVolume :
apiVersion: v1
kind: PersistentVolume
metadata:
name: test-volume
labels:
failure-domain.beta.kubernetes.io/zone: us-central1-a__us-central1-b
spec:
capacity:
storage: 400Gi
accessModes:
- ReadWriteOnce
gcePersistentDisk:
pdName: my-data-disk
fsType: ext4
Migration CSI
Kubernetes v1.14 [alpha]
La fonctionnalité de migration CSI pour un disque persistant GCE, lorsque activée, fixe toutes les opérations de plugin depuis le plugin "in-tree" vers le pilote de l'interface CSI (Container Storage Interface) pd.csi.storage.gke.io
.
Afin d'utiliser cette fonctionnalité, le Pilote CSI de disque persistant GCE doit être installé dans le cluster et les fonctionnalités Alpha CSIMigration
et CSIMigrationGCE
doivent être activées.
gitRepo (obsolète)
Un volume gitRepo
est un exemple de ce qui peut être réalisé en tant que plugin de volume.
Cela monte un dossier vide et clone un dépôt git à l'intérieur, à la disposition d'un Pod.
Dans le futur, de tels volumes pourraient être déplacé vers un modèle encore plus découplé plutôt qu'étendre l'API Kubernetes pour chaque cas d'utilisation.
Voici un exemple d'un volume gitRepo :
apiVersion: v1
kind: Pod
metadata:
name: server
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- mountPath: /mypath
name: git-volume
volumes:
- name: git-volume
gitRepo:
repository: "git@somewhere:me/my-git-repository.git"
revision: "22f1d8406d464b0c0874075539c1f2e96c253775"
glusterfs
Un volume glusterfs
permet à un volume Glusterfs (un système de fichiers en réseau open
source) d'être monté dans un Pod. À la différence d'un emptyDir
, qui est écrasé lorsqu'un Pod est supprimé. le contenu d'un volume glusterfs
est préservé et le volume est simplement démonté.
Cela signifie qu'un volume glusterfs peut être prérempli avec des données et que ces données peuvent être transmises entre les Pods.
GlusterFS peut être monté plusieurs fois en écriture simultanément.
Voir l'exemple GlusterFS pour plus de détails.
hostPath
Un volume hostPath
monte un fichier ou un dossier depuis le système de fichiers du nœud hôte à l'intérieur d'un Pod.
Ce ne sera pas requis pour la plupart des Pods, mais cela offre une puissante solution de secours pour certaines applications.
Par exemple, des utilisations du hostPath
peuvent être :
- exécuter un conteneur qui nécessite l'accès aux éléments internes de Docker; utiliser un
hostPath
de/var/lib/docker
- exécuter cAdvisor dans un conteneur; utiliser un
hostPath
de/sys
- autoriser un Pod à spécifier si un
hostPath
donné devrait exister avant la mise en exécution du Pod, s'il devrait être créé et en tant que quoi il devrait exister.
En plus de la propriété requise path
, un utilisateur peut optionnellement spécifier un type
pour un volume hostPath
.
Les valeurs supportées pour le champ type
sont les suivantes :
Valeur | Comportement |
---|---|
Une chaîne de caractères vide (par défaut) sert à la rétrocompatibilité, ce qui signifie qu'aucune vérification ne sera effectuée avant de monter le volume hostPath. | |
DirectoryOrCreate |
Si rien n'existe au chemin fourni, un dossier vide y sera créé au besoin avec les permissions définies à 0755, avec le même groupe et la même possession que Kubelet. |
Directory |
Un dossier doit exister au chemin fourni |
FileOrCreate |
Si rien n'existe au chemin fourni, un fichier vide y sera créé au besoin avec les permissions définies à 0644, avec le même groupe et la même possession que Kubelet. |
File |
Un fichier doit exister au chemin fourni |
Socket |
Un socket UNIX doit exister au chemin fourni |
CharDevice |
Un périphérique en mode caractère doit exister au chemin fourni |
BlockDevice |
Un périphérique en mode bloc doit exister au chemin fourni |
Une attention particulière doit être portée lors de l'utilisation de ce type de volume car :
- les Pods avec une configuration identique (tels que ceux créés depuis un podTemplate) peuvent se comporter différemment sur des nœuds différents à cause de fichiers différents sur les nœuds.
- lorsque Kubernetes ajoute une planification tenant compte des ressources, comme prévu, il ne pourra pas prendre en compte les ressources utilisées par un
hostPath
. - les fichiers ou dossiers créés sur les hôtes sous-jacents ne sont accessibles en écriture que par root. Vous devez soit exécuter votre programme en tant que root dans un conteneur privilégié ou modifier les permissions du fichier sur l'hôte pour pouvoir écrire dans un volume
hostPath
.
Exemple de Pod
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
# chemin du dossier sur l'hôte
path: /data
# ce champ est optionnel
type: Directory
iscsi
Un volume iscsi
permet à un volume existant iSCSI (SCSI over IP) d'être monté dans un Pod.
À la différence d'un emptyDir
, qui est écrasé lorsqu'un Pod est supprimé, le contenu d'un volume iscsi
est préservé et le volume est simplement démonté.
Cela signifie qu'un volume iscsi peut être prérempli avec des données que ces données peuvent être transmises entre les Pods.
Une fonctionnalité de iSCSI est qu'il peut être monté en lecture seule par plusieurs consommateurs simultanément. Cela signifie que vous pouvez préremplir un volume avec votre jeu de données et l'exposer en parallèle à partir d'autant de Pods que nécessaire. Malheureusement, les volumes iSCSI peuvent seulement être montés par un seul consommateur en mode lecture-écriture - les écritures simultanées ne sont pas autorisées.
Voir l'exemple iSCSI pour plus de détails.
local
Kubernetes v1.14 [stable]
Un volume local
représente un périphérique de stockage local monté tels qu'un disque, une partition ou un dossier.
Les volumes locaux peuvent seulement être utilisés comme un PersistentVolume créé statiquement. Le provisionnement dynamique n'est pas encore supporté.
Comparés aux volumes hostPath
, les volumes locaux peuvent être utilisés de manière durable et portable sans planifier manuellement des Pods sur les nœuds, puisque le système est conscient des contraintes de nœud du volume en examinant l'affinité de nœud sur le PersistentVolume.
Toutefois, les volumes locaux sont encore sujets à la disponibilité du nœud sous-jacent et ne conviennent pas à toutes les applications. Si un nœud devient "en mauvaise santé" (unhealthy), alors le volume local deviendra également inaccessible et un Pod qui l'utilise ne sera pas en mesure de s'exécuter. Les applications qui utilisent des volumes locaux doivent être en mesure de tolérer cette disponibilité réduite, ainsi que de potentielles pertes de données, dépendamment des caractéristiques de durabilité du disque sous-jacent.
L'exemple suivant traite d'une spec d'un PersistentVolume utilisant un volume local
et une nodeAffinity
:
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 100Gi
# le champ volumeMode requiert l'activation de la "feature gate" Alpha BlockVolume
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/disks/ssd1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- example-node
La nodeAffinity
d'un PersistentVolume est requise lors de l'utilisation de volumes locaux.
Cela permet au planificateur (scheduler) Kubernetes de planifier correctement des Pods utilisant des volumes locaux aux bons nœuds.
Le volumeMode
d'un PersistentVolume peut maintenant être configuré à "Block" (au lieu de la valeur par défaut "Filesystem") pour exposer le volume local en tant que périphérique bloc brut (raw block device).
Le champ volumeMode
requiert l'activation de la "feature gate" Alpha BlockVolume
.
Lors de l'utilisation des volumes locaux, il est recommandé de créer une StorageClass avec volumeBindingMode
configuré à WaitForFirstConsumer
. Voir l'exemple. Retarder la liaison (binding) du volume garantit que la décision de liaison du PersistentVolumeClaim sera également évaluée avec toutes les autres contraintes de nœud que le Pod peut avoir, tels que les exigences en ressources du nœud, les sélecteurs de nœud, leur affinité et leur anti-affinité.
Un provisionneur statique externe peut être exécuté séparément pour une gestion améliorée du cycle de vie du volume local. Noter que ce provisionneur ne supporte pas encore le provisionnement dynamique. Pour un exemple sur la façon d'exécuter un provisionneur externe local, voir le guide utilisateur de provisionneur de volume local.
nfs
Un volume nfs
permet à un partage NFS (Network File System) existant d'être monté dans un Pod.
À la différence d'un emptyDir
, qui est écrasé lorsqu'un Pod est supprimé, le contenu d'un volume nfs
est préservé et le volume est simplement démonté.
Cela signifie qu'un volume NFS peut être prérempli avec des données et que les données peuvent être transmises entre les Pods. NFS peut être monté plusieurs fois en écriture simultanément.
Voir l'exemple NFS pour plus de détails.
persistentVolumeClaim
Un volume persistentVolumeClaim
est utilisé pour monter un PersistentVolume dans un Pod. Les PersistentVolumes sont une manière pour les utilisateurs de "revendiquer" un stockage durable (comme un PersistentDisk GCE ou un volume iSCSI) sans savoir les détails d'un environnement cloud particulier.
Voir l'exemple PersistentVolumes pour plus de détails.
projected
Un volume projected
mappe plusieurs sources de volume existantes dans le même dossier.
Actuellement, les types de sources de volume suivantes peuvent être projetés :
secret
downwardAPI
configMap
serviceAccountToken
Toutes les sources doivent se trouver dans le même namespace que celui du Pod. Pour plus de détails, voir le document de conception tout-en-un .
La projection des jetons de compte de service (service account) est une fonctionnalité introduite dans Kubernetes 1.11 et promue en Beta dans la version 1.12.
Pour activer cette fonctionnalité dans la version 1.11, il faut configurer explicitement la "feature gate" TokenRequestProjection
à "True".
Exemple d'un Pod avec un secret, une API downward et une configmap.
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
containers:
- name: container-test
image: busybox
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: all-in-one
projected:
sources:
- secret:
name: mysecret
items:
- key: username
path: my-group/my-username
- downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "cpu_limit"
resourceFieldRef:
containerName: container-test
resource: limits.cpu
- configMap:
name: myconfigmap
items:
- key: config
path: my-group/my-config
Exemple d'un Pod avec plusieurs secrets avec une configuration de mode de permission autre que celle par défaut.
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
containers:
- name: container-test
image: busybox
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: all-in-one
projected:
sources:
- secret:
name: mysecret
items:
- key: username
path: my-group/my-username
- secret:
name: mysecret2
items:
- key: password
path: my-group/my-password
mode: 511
Chaque source de volume projeté est listée dans la spec, sous sources
. Les paramètres sont à peu près les mêmes avec deux exceptions :
- Pour les secrets, le champ
secretName
a été changé parname
pour être consistant avec le nommage des ConfigMap. - Le
defaultMode
peut seulement être spécifié au niveau projeté et non pour chaque source de volume. Cependant, tel qu'illustré au-dessus, il est possible de configurer explicitement lemode
pour chaque projection individuelle.
Lorsque la fonctionnalité TokenRequestProjection
est activée, vous pouvez injecter le jeton pour le service account courant dans un Pod au chemin spécifié. Ci-dessous, un exemple :
apiVersion: v1
kind: Pod
metadata:
name: sa-token-test
spec:
containers:
- name: container-test
image: busybox
volumeMounts:
- name: token-vol
mountPath: "/service-account"
readOnly: true
volumes:
- name: token-vol
projected:
sources:
- serviceAccountToken:
audience: api
expirationSeconds: 3600
path: token
Le pod d'exemple possède un volume projeté contenant le jeton injecté du service account.
Ce jeton peut être utilisé par des conteneurs de Pod pour accéder au service d'API Kubernetes API, par exemple.
Le champ audience
contient l'audience-cible du jeton.
Un destinataire du jeton doit s'identifier avec un identificateur spécifié dans l'audience du jeton, sinon il doit rejeter le jeton. Ce champ est facultatif et sa valeur par défaut est l'identifiant du serveur API.
Le champ expirationSeconds
est la durée de validité attendue du jeton de service account.
Sa valeur par défaut est de 1 heure et doit être au moins de 10 minutes (600 secondes). Un administrateur peut aussi limiter sa valeur maximum en spécifiant l'option --service-account-max-token-expiration
pour le serveur API.
Le champ path
spécifie un chemin relatif au point de montage du volume projeté.
portworxVolume
Un portworxVolume
est une couche de stockage bloc élastique qui s'exécute de manière hyperconvergée avec Kubernetes.
Portworx donne l'empreinte digitale d'un stockage dans un serveur, tiers basés sur les capacités et agrège la capacité sur plusieurs serveurs. Portworx s'exécute en invité sur des machines virtuelles ou sur des nœuds Linux bare metal.
Un portworxVolume
peut être créé dynamiquement à travers Kubernetes ou il peut également être pré-provisionné et référencé à l'intérieur d'un Pod Kubernetes.
Voici un exemple de Pod référençant un PortworxVolume pré-provisionné :
apiVersion: v1
kind: Pod
metadata:
name: test-portworx-volume-pod
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /mnt
name: pxvol
volumes:
- name: pxvol
# Ce volume Portworx doit déjà exister.
portworxVolume:
volumeID: "pxvol"
fsType: "<fs-type>"
pxvol
avant de l'utiliser dans le Pod.
Plus de détails et d'exemples peuvent être trouvé ici.
quobyte
Un volume quobyte
permet à un volume existant Quobyte d'être monté dans un Pod.
Quobyte supporte le Container Storage Interface. CSI est le plugin recommandé pour utiliser les volumes Quobyte volumes dans Kubernetes. Le projet GitHub Quobyte dispose d'instructions pour déployer Quobyte en utilisant CSI, avec des exemples.
rbd
Un volume rbd
permet à un volume périphérique bloc Rados (Rados Block
Device) d'être monté dans un Pod.
À la différence d'un emptyDir
, qui est écrasé lorsqu'un Pod est supprimé, le contenu d'un volume rbd
est préservé et le volume est simplement démonté.
Cela signifie qu'un volume RBD peut être prérempli avec des données et que ces données peuvent être transmises entre les Pods.
Une fonctionnalité de RBD est qu'il peut être monté en lecture seule par plusieurs consommateurs simultanément. Cela signifie que vous pouvez préremplir un volume avec votre jeu de données et l'exposer en parallèle à partir d'autant de Pods que nécessaire. Malheureusement, les volumes RBD peuvent seulement être montés par un seul consommateur en mode lecture-écriture - les écritures simultanées ne sont pas autorisées.
Voir l'exemple RBD pour plus de détails.
scaleIO
ScaleIO est une plateforme de stockage logicielle qui peut utiliser du matériel physique existant pour créer des clusters de stockage bloc partagé en réseau évolutif.
Le plugin de volume scaleIO
permet aux Pods déployés d'accéder à des volumes ScaleIO existants (ou il peut provisionner dynamiquement de nouveaux volumes pour des revendications de volumes persistants, voir ScaleIO Persistent Volumes).
L'exemple suivant montre une configuration de Pod avec ScaleIO :
apiVersion: v1
kind: Pod
metadata:
name: pod-0
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: pod-0
volumeMounts:
- mountPath: /test-pd
name: vol-0
volumes:
- name: vol-0
scaleIO:
gateway: https://localhost:443/api
system: scaleio
protectionDomain: sd0
storagePool: sp1
volumeName: vol-0
secretRef:
name: sio-secret
fsType: xfs
Pour plus de détails, consulter les exemples ScaleIO.
secret
Un volume secret
est utilisé pour fournir des informations sensibles, comme des mots de passe, aux Pods.
Vous pouvez stocker des secrets dans l'API Kubernetes et les monter en tant que fichiers pour être utilisés par les Pods sans les coupler directement avec Kubernetes. Les volumes secret
sont supportés par tmpfs (un système de fichiers en RAM) pour qu'ils ne soient jamais écrits sur du stockage non volatil.
Les secrets sont décrits plus en détails ici.
storageOS
Un volume storageos
permet à un volume StorageOS existant d'être monté dans un Pod.
StorageOS s'exécute en tant que conteneur dans l'environnement Kubernetes en rendant le stockage local ou attaché accessible depuis n'importe quel nœud dans le cluster Kubernetes. Les données peuvent être répliquées pour se protéger des défaillances de nœuds. Les techniques d'allocation fine et dynamique et de compression peuvent améliorer l'utilisation et réduire les coûts.
À la base, StorageOS fournit un stockage bloc aux conteneurs accessible via un système de fichiers.
Le conteneur StorageOS requiert Linux 64-bit et n'a pas besoin de dépendances supplémentaires. Une licence développeur libre est disponible.
apiVersion: v1
kind: Pod
metadata:
labels:
name: redis
role: master
name: test-storageos-redis
spec:
containers:
- name: master
image: kubernetes/redis:v1
env:
- name: MASTER
value: "true"
ports:
- containerPort: 6379
volumeMounts:
- mountPath: /redis-master-data
name: redis-data
volumes:
- name: redis-data
storageos:
# Le volume `redis-vol01` doit déjà exister dans StorageOS, dans le namespace `default`.
volumeName: redis-vol01
fsType: ext4
Pour plus d'informations incluant le provisionnement dynamique (Dynamic Provisioning) et les réclamations de volume persistant (Persistent Volume Claims), consulter les exemples StorageOS.
vsphereVolume
Un volume vsphereVolume
est utilisé pour monter un volume vSphere VMDK dans un Pod. Le contenu d'un volume est préservé lorsqu'il est démonté. Il supporte les banques de données (datastore) VMFS and VSAN.
Création d'un volume VMDK
Choisir une des méthodes suivantes pour créer un VMDK.
Premièrement, se connecter en ssh dans l'ESX, ensuite, utiliser la commande suivante pour créer un VMDK :
vmkfstools -c 2G /vmfs/volumes/DatastoreName/volumes/myDisk.vmdk
Utiliser la commande suivante pour créer un VMDK:
vmware-vdiskmanager -c -t 0 -s 40GB -a lsilogic myDisk.vmdk
Exemple de configuration vSphere VMDK
apiVersion: v1
kind: Pod
metadata:
name: test-vmdk
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-vmdk
name: test-volume
volumes:
- name: test-volume
# Ce volume VMDK doit déjà exister.
vsphereVolume:
volumePath: "[DatastoreName] volumes/myDisk"
fsType: ext4
Plus d'exemples sont disponibles ici.
Utilisation de subPath
Parfois, il est utile de partager un volume pour plusieurs utilisations dans un même Pod.
La propriété volumeMounts.subPath
peut être utilisée pour spécifier un sous-chemin à l'intérieur du volume référencé au lieu de sa racine.
Voici un exemple d'un Pod avec une stack LAMP (Linux Apache Mysql PHP) utilisant un unique volume partagé.
Le contenu HTML est mappé à son dossier html
et les bases de données seront stockées dans son dossier mysql
:
apiVersion: v1
kind: Pod
metadata:
name: my-lamp-site
spec:
containers:
- name: mysql
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "rootpasswd"
volumeMounts:
- mountPath: /var/lib/mysql
name: site-data
subPath: mysql
- name: php
image: php:7.0-apache
volumeMounts:
- mountPath: /var/www/html
name: site-data
subPath: html
volumes:
- name: site-data
persistentVolumeClaim:
claimName: my-lamp-site-data
Utilisation d'un subPath avec des variables d'environnement étendues
Kubernetes v1.15 [beta]
Utiliser le champ subPathExpr
pour construire des noms de dossier subPath
depuis les variables d'environnement de l'API Downward.
Avant d'utiliser cette fonctionnalité, vous devez activer la "feature gate" VolumeSubpathEnvExpansion
.
Les propriétés subPath
et subPathExpr
sont mutuellement exclusives.
Dans cet exemple, un Pod utilise subPathExpr
pour créer un dossier pod1
à l'intérieur du volume hostPath /var/log/pods
, en utilisant le nom du pod depuis l'API Downward.
Le dossier hôte /var/log/pods/pod1
est monté sur /logs
dans le conteneur.
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: container1
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
image: busybox
command: [ "sh", "-c", "while [ true ]; do echo 'Hello'; sleep 10; done | tee -a /logs/hello.txt" ]
volumeMounts:
- name: workdir1
mountPath: /logs
subPathExpr: $(POD_NAME)
restartPolicy: Never
volumes:
- name: workdir1
hostPath:
path: /var/log/pods
Ressources
Le support de stockage (Disk, SSD, etc.) d'un volume emptyDir
est déterminé par le support du système de fichiers
contenant le dossier racine de kubelet (typiquement /var/lib/kubelet
).
Il n'y a pas de limite sur l'espace qu'un volume emptyDir
ou hostPath
peut consommer
et pas d'isolation entre les conteneurs ou entre les Pods.
Dans le futur, il est prévu que les volumes emptyDir
et hostPath
soient en mesure de demander une certaine quantité d'espace en utilisant une spécification de ressource et de sélectionner un type de support à utiliser, pour les clusters qui ont plusieurs types de support.
Plugins de volume Out-of-Tree
Les plugins de volume Out-of-tree incluent l'interface CSI (Container Storage Interface) et FlexVolume. Ils permettent aux fournisseurs de stockage de créer des plugins de stockage personnalisés sans les ajouter au dépôt Kubernetes.
Avant l'introduction de l'interface CSI et FlexVolume, tous les plugins de volume (tels que les types de volume listés plus haut) étaient "in-tree", ce qui signifie qu'ils étaient construits, liés, compilés et livrés avec les binaires de base Kubernetes et étendent l'API Kubernetes de base. Cela signifiait que l'ajout d'un nouveau système de stockage à Kubernetes (un plugin de volume) requérait de vérifier le code dans le dépôt de base de Kubernetes.
CSI et FlexVolume permettent à des plugins de volume d'être développés indépendamment de la base de code Kubernetes et déployés (installés) sur des clusters Kubernetes en tant qu'extensions.
Pour les fournisseurs de stockage qui cherchent à créer un plugin de volume "out-of-tree", se référer à cette FAQ.
CSI
L'interface Container Storage Interface (CSI) définit une interface standard pour les systèmes d'orchestration de conteneurs (comme Kubernetes) pour exposer des systèmes de stockage arbitraires aux charges de travail de leurs conteneurs.
Pour plus d'informations, lire la proposition de conception CSI.
Le support CSI a été introduit en alpha à partir de Kubernetes v1.9, a évolué en beta dans Kubernetes v1.10 et est en disponibilité générale (GA) depuis Kubernetes v1.13.
Une fois qu'un pilote de volume CSI compatible est déployé dans un cluster Kubernetes, les utilisateurs peuvent
utiliser le type de volume csi
pour attacher, monter, etc.., les volumes exposés par le pilote CSI.
Le type de volume csi
ne supporte pas de référence directe depuis un Pod et ne peut être référencé seulement dans un Pod que par un objet PersistentVolumeClaim
.
Les champs suivants sont disponibles aux administrateurs de stockage pour configurer un volume persistant CSI :
driver
: Une valeur texte qui spécifie le nom du pilote de volume à utiliser. Cette valeur doit correspondre à la valeur retournée dans leGetPluginInfoResponse
par le pilote CSI tel que défini dans la spec CSI. Elle est utilisée par Kubernetes pour identifier le pilote CSI à appeler et par les composants du pilote CSI pour identifier quels objets PV appartiennent au pilote CSI.volumeHandle
: Une valeur texte qui identifie le volume de manière unique. Cette valeur doit correspondre à la valeur retournée dans le champvolume.id
deCreateVolumeResponse
par le pilote CSI tel que défini dans la spec CSI. La valeur est passée en tant quevolume_id
sur tous les appels au pilote de volume CSI lorsque le volume est référencé.readOnly
: Une valeur booléenne optionnelle indiquant si le volume doit être "ControllerPublished" (attaché) en lecture seule. La valeur par défaut est "false". Cette valeur est passées au pilote CSI via le champreadonly
dans leControllerPublishVolumeRequest
.fsType
: Si leVolumeMode
du PV estFilesystem
, alors ce champ peut être utilisé pour spécifier le système de fichiers qui devrait être utilisé pour monter le volume. Si le volume n'a pas été formaté et que le formatage est supporté, cette valeur sera utilisée pour formater le volume. Cette valeur est passée au pilote CSI driver via le champVolumeCapability
deControllerPublishVolumeRequest
,NodeStageVolumeRequest
, etNodePublishVolumeRequest
.volumeAttributes
: Un tableau associatif (map) string vers string qui spécifie les propriétés statiques d'un volume. Ce tableau associatif doit correspondre à celui retourné dans le champvolume.attributes
duCreateVolumeResponse
par le pilote CSI tel que défini dans la spec CSI. Le tableau associatif est passé au pilote CSI via le champvolume_attributes
dans laControllerPublishVolumeRequest
,NodeStageV olumeRequest
, etNodePublishVolumeRequest
.controllerPublishSecretRef
: Une référence de l'objet de type secret contenant des informations sensibles à passer au driver CSI pour compléter les appels CSIControllerPublishVolume
etControllerUnpublishVolume
. Ce champ est optionnel et peut être vide si aucun secret n'est requis. Si l'objet secret contient plus qu'un secret, tous les secrets sont passés.nodeStageSecretRef
: Une référence à l'objet de type secret contenant des informations sensibles à passer au pilote CSI pour compléter l'appel CSINodeStageVolume
. Ce champ est optionnel et peut être vide si aucun secret n'est requis. Si l'objet secret contient plus qu'un secret, tous les secrets sont passés.nodePublishSecretRef
: Une référence vers l'objet de type secret contenant des informations sensibles à passer au pilote CSI pour compléter l'appel CSINodePublishVolume
. Ce champ est optionnel et peut être vide si aucun secret n'est requis. Si l'objet secret contient plus qu'un secret, tous les secrets sont passés.
Support de volume bloc brut CSI
Kubernetes v1.14 [beta]
À partir de la version 1.11, CSI a introduit le support des volumes bloc bruts, qui s'appuient sur la fonctionnalité de volume bloc brut introduite dans une version précédente de Kubernetes. Cette fonctionnalité va permettre aux fournisseurs avec des pilotes CSI externes d'implémenter le support pour les volumes bloc bruts dans les charges de travail Kubernetes.
Le support volume bloc CSI est une "feature-gate", mais est activée par défaut. Les deux
"feature gates" qui doivent être activées pour cette fonctionnalité sont BlockVolume
et CSIBlockVolume
.
Apprenez comment configurer votre PV/PVC avec le support de volume bloc brut.
Volumes CSI éphémères
Kubernetes v1.15 [alpha]
Cette fonctionnalité permet aux volumes CSI d'être embarqués directement dans la spécification du Pod au lieu de celle d'un PersistentVolume. Les Volumes spécifiés de cette manière sont éphémères et ne persistent pas lorsque le Pod redémarre.
Exemple :
kind: Pod
apiVersion: v1
metadata:
name: my-csi-app
spec:
containers:
- name: my-frontend
image: busybox
volumeMounts:
- mountPath: "/data"
name: my-csi-inline-vol
command: [ "sleep", "1000000" ]
volumes:
- name: my-csi-inline-vol
csi:
driver: inline.storage.kubernetes.io
volumeAttributes:
foo: bar
Cette fonctionnalité requiert l'activation de la "feature gate" CSIInlineVolume :
--feature-gates=CSIInlineVolume=true
Les volumes éphémères CSI sont seulement supportés par un sous-ensemble des pilotes CSI. La liste des pilotes CSI est disponible ici.
Ressources pour développeur
Pour plus d'informations sur la manière de développer un pilote CSI, se référer à la documentation kubernetes-csi
Migration de pilotes CSI depuis des plugins "in-tree"
Kubernetes v1.14 [alpha]
La fonctionnalité de migration CSI, lorsque activée, dirige les opérations sur les plugins "in-tree" existants vers les plugins CSI correspondants (qui sont sensés être installés et configurés). Cette fonctionnalité implémente la logique de translation nécessaire et les fixations nécessaires pour rerouter les opérations de manière transparente. En conséquence, les opérateurs n'ont pas à effectuer de changements de configuration aux classes de stockage (Storage Classes) existantes, PV ou PVC (référençant aux plugins "in-tree") lors de la transition vers un pilote CSI qui remplace un plugin "in-tree".
Dans l'état alpha, les opérations et fonctionnalités qui sont supportées incluent provisionnement/suppression, attachement/détachement, montage/démontage et le redimensionnement des volumes.
Les plugins "in-tree" qui supportent la migration CSI et qui ont un pilote CSI correspondant implémenté sont listés dans la section "Types de volumes" au-dessus.
FlexVolume
FlexVolume est une interface de plugin "out-of-tree" qui existe dans Kubernetes depuis la version 1.2 (avant CSI). Elle utilise un modèle basé sur exec pour s'interfacer avec les pilotes. Les binaires de pilote FlexVolume doivent être installés dans un chemin de volume de plugin prédéfini sur chaque nœud (et dans certains cas le nœud maître).
Les Pods interagissent avec les pilotes FlexVolume à travers le plugin "in-tree" flexvolume
Plus de détails sont disponibles ici.
Propagation de montage
La propagation de montage permet à des volumes partagés montés par un conteneur à d'autres conteneurs dans un même Pod, ou même à d'autres Pods dans le même nœud.
La propagation de montage d'un volume est contrôlée par le champ mountPropagation
dans Container.volumeMounts.
Ses valeurs sont :
-
None
- Ce montage de volume ne recevra aucun montage subséquent qui est monté à ce volume ou n'importe lequel de ses sous-dossiers par l'hôte. De la même manière, aucun montage créé par le conteneur ne sera visible sur l'hôte. C'est le mode par défaut.Ce mode équivaut à une propagation de montage
private
tel que décrit dans la documentation du noyau Linux -
HostToContainer
- Ce montage de volume recevra les montages subséquents qui sont montés sur ce volume ou n'importe lequel de ses sous-dossiers.En d'autres termes, si l'hôte monte quoi que ce soit dans le montage de volume, le conteneur va le voir monté à cet endroit.
De manière similaire, si un Pod avec la propagation de montage
Bidirectional
vers le même volume y monte quoi que ce soit, le conteneur avec la propagation de montageHostToContainer
le verra.Ce mode est équivalent à la propagation de montage
rslave
tel que décrit dans la documentation du noyau Linux -
Bidirectional
- Ce montage de volume se comporte de la même manière que le montageHostToContainer
. De plus, tous les montages de volume créés par le conteneur seront propagés à l'hôte et à tous les conteneurs des autres Pods qui utilisent le même volume.Un cas d'utilisation typique pour ce mode est un Pod avec un FlexVolume ou un pilote CSI, ou un Pod qui nécessite de monter quelque chose sur l'hôte en utilisant un volume
hostPath
.Ce mode est équivalent à une propagation de montage
rshared
tel que décrit dans la documentation du noyau Linux
Bidirectional
peut être dangereuse. Elle peut endommager le système d'exploitation hôte
et est donc autorisée seulement dans des conteneurs privilégiés.
Il est fortement recommandé d'être familier avec le comportement du noyau Linux.
De plus, tous les montages de volume créés par des conteneurs dans des Pods doivent être détruits (démontés) par les conteneurs lors de la terminaison.
Configuration
Avant que la propagation de montage puisse fonctionner correctement sur certains déploiements (CoreOS, RedHat/Centos, Ubuntu) le partage de montage doit être correctement configuré dans Docker tel qu'illustré ci-dessous :
Modifiez le fichier de service systemd
de votre Docker. Configurez votre MountFlags
comme suit :
MountFlags=shared
Ou bien retirez MountFlags=slave
si présent. Redémarrez ensuite le démon Docker :
sudo systemctl daemon-reload
sudo systemctl restart docker
A suivre
- Suivez un exemple de déploiement de WordPress et MySQL avec des volumes persistants.
3.6.2 - Volumes persistants
Ce document décrit l'état actuel de PersistentVolumes
dans Kubernetes.
Une connaissance des volumes est suggérée.
Introduction
La gestion du stockage est un problème distinct de la gestion des instances de calcul.
Le sous-système PersistentVolume
fournit une API pour les utilisateurs et les administrateurs qui abstrait les détails de la façon dont le stockage est fourni et de la façon dont il est utilisé.
Pour ce faire, nous introduisons deux nouvelles ressources API: PersistentVolume
et PersistentVolumeClaim
.
Un PersistentVolume
(PV) est un élément de stockage dans le cluster qui a été provisionné par un administrateur ou provisionné dynamiquement à l'aide de Storage Classes.
Il s'agit d'une ressource dans le cluster, tout comme un nœud est une ressource de cluster.
Les PV sont des plugins de volume comme Volumes, mais ont un cycle de vie indépendant de tout pod individuel qui utilise le PV.
Cet objet API capture les détails de l'implémentation du stockage, que ce soit NFS, iSCSI ou un système de stockage spécifique au fournisseur de cloud.
Un PersistentVolumeClaim
(PVC) est une demande de stockage par un utilisateur.
Il est similaire à un Pod.
Les pods consomment des ressources de noeud et les PVC consomment des ressources PV.
Les pods peuvent demander des niveaux spécifiques de ressources (CPU et mémoire).
Les PVC peuvent demander une taille et des modes d'accès spécifiques (par exemple, ils peuvent être montés une fois en lecture/écriture ou plusieurs fois en lecture seule).
Alors que les PersistentVolumeClaims
permettent à un utilisateur de consommer des ressources de stockage abstraites, il est courant que les utilisateurs aient besoin de PersistentVolumes
avec des propriétés et des performances variables pour différents problèmes.
Les administrateurs de cluster doivent être en mesure d'offrir une variété de PersistentVolumes
qui diffèrent de bien des façons plus que la taille et les modes d'accès, sans exposer les utilisateurs aux détails de la façon dont ces volumes sont mis en œuvre.
Pour ces besoins, il existe la ressource StorageClass
.
Voir la procédure détaillée avec des exemples.
Cycle de vie d'un PV et d'un PVC
Les PV sont des ressources du cluster. Les PVC sont des demandes pour ces ressources et agissent également comme des contrôles de réclamation pour la ressource. L'interaction entre les PV et les PVC suit ce cycle de vie:
Provisionnement
Les PV peuvent être provisionnés de deux manières: statiquement ou dynamiquement.
Provisionnement statique
Un administrateur de cluster crée un certain nombre de PV. Ils contiennent les détails du stockage réel, qui est disponible pour une utilisation par les utilisateurs du cluster. Ils existent dans l'API Kubernetes et sont disponibles pour la consommation.
Provisionnement dynamique
Lorsqu'aucun des PV statiques créés par l'administrateur ne correspond au PersistentVolumeClaim
d'un utilisateur, le cluster peut essayer de provisionner dynamiquement un volume spécialement pour le PVC.
Ce provisionnement est basé sur les StorageClasses
: le PVC doit demander une storage class et l'administrateur doit avoir créé et configuré cette classe pour que l'approvisionnement dynamique se produise.
Les PVC qui demandent la classe ""
désactive le provisionnement dynamique pour eux-mêmes.
Pour activer le provisionnement de stockage dynamique basé sur la classe de stockage, l'administrateur de cluster doit activer le DefaultStorageClass
dans l'contrôleur d'admission sur le serveur API.
Cela peut être fait, par exemple, en veillant à ce que DefaultStorageClass
figure parmi la liste de valeurs séparées par des virgules pour l'option --enable-admission-plugins
du composant serveur API.
Pour plus d'informations sur les options de ligne de commande du serveur API, consultez la documentation kube-apiserver.
Liaison
Un utilisateur crée, ou dans le cas d'un provisionnement dynamique, a déjà créé, un PersistentVolumeClaim
avec une quantité spécifique de stockage demandée et avec certains modes d'accès.
Une boucle de contrôle dans le maître surveille les nouveaux PVC, trouve un PV correspondant (si possible) et les lie ensemble.
Si un PV a été dynamiquement provisionné pour un nouveau PVC, la boucle liera toujours ce PV au PVC.
Sinon, l'utilisateur obtiendra toujours au moins ce qu'il a demandé, mais le volume peut être supérieur à ce qui a été demandé.
Une fois liées, les liaisons PersistentVolumeClaim
sont exclusives, quelle que soit la façon dont elles ont été liées.
Une liaison PVC-PV est une relation 1-à-1.
Les PVC resteront non liés indéfiniment s'il n'existe pas de volume correspondant. Le PVC sera lié à mesure que les volumes correspondants deviendront disponibles. Par exemple, un cluster provisionné avec de nombreux PV 50Gi ne correspondrait pas à un PVC demandant 100Gi. Le PVC peut être lié lorsqu'un PV 100Gi est ajouté au cluster.
Utilisation
Les Pods utilisent les PVC comme des volumes. Le cluster inspecte le PVC pour trouver le volume lié et monte ce volume pour un Pod. Pour les volumes qui prennent en charge plusieurs modes d'accès, l'utilisateur spécifie le mode souhaité lors de l'utilisation de leur PVC comme volume dans un Pod.
Une fois qu'un utilisateur a un PVC et que ce PVC est lié, le PV lié appartient à l'utilisateur aussi longtemps qu'il en a besoin.
Les utilisateurs planifient des pods et accèdent à leurs PV revendiqués en incluant un persistentVolumeClaim
dans le bloc de volumes de leur Pod Voir ci-dessous pour les détails de la syntaxe.
Protection de l'objet de stockage en cours d'utilisation
Le but de la fonction de protection des objets de stockage utilisés est de garantir que les revendications de volume persistantes (PVC) en cours d'utilisation par un Pod et les volumes persistants (PV) liés aux PVC ne sont pas supprimées du système, car cela peut entraîner des pertes de données.
Si un utilisateur supprime un PVC en cours d'utilisation par un pod, le PVC n'est pas supprimé immédiatement. L'élimination du PVC est différée jusqu'à ce que le PVC ne soit plus activement utilisé par les pods. De plus, si un administrateur supprime un PV lié à un PVC, le PV n'est pas supprimé immédiatement. L'élimination du PV est différée jusqu'à ce que le PV ne soit plus lié à un PVC.
Vous pouvez voir qu'un PVC est protégé lorsque son état est Terminating
et la liste Finalizers
inclus kubernetes.io/pvc-protection
:
kubectl describe pvc hostpath
Name: hostpath
Namespace: default
StorageClass: example-hostpath
Status: Terminating
Volume:
Labels: <none>
Annotations: volume.beta.kubernetes.io/storage-class=example-hostpath
volume.beta.kubernetes.io/storage-provisioner=example.com/hostpath
Finalizers: [kubernetes.io/pvc-protection]
...
Vous pouvez voir qu'un PV est protégé lorsque son état est Terminating
et la liste Finalizers
inclus kubernetes.io/pv-protection
aussi:
kubectl describe pv task-pv-volume
Name: task-pv-volume
Labels: type=local
Annotations: <none>
Finalizers: [kubernetes.io/pv-protection]
StorageClass: standard
Status: Available
Claim:
Reclaim Policy: Delete
Access Modes: RWO
Capacity: 1Gi
Message:
Source:
Type: HostPath (bare host directory volume)
Path: /tmp/data
HostPathType:
Events: <none>
Récupération des volumes
Lorsqu'un utilisateur a terminé avec son volume, il peut supprimer les objets PVC de l'API qui permet la récupération de la ressource.
La politique de récupération pour un PersistentVolume
indique au cluster ce qu'il doit faire du volume une fois qu'il a été libéré de son PVC.
Actuellement, les volumes peuvent être conservés, recyclés ou supprimés.
Volumes conservés
La politique de récupération Retain
permet la récupération manuelle de la ressource.
Lorsque le PersistentVolumeClaim
est supprimé, le PersistentVolume
existe toujours et le volume est considéré comme «libéré».
Mais il n'est pas encore disponible pour une autre demande car les données du demandeur précédent restent sur le volume.
Un administrateur peut récupérer manuellement le volume en procédant comme suit.
- Supprimer le
PersistentVolume
. L'actif de stockage associé dans une infrastructure externe (comme un volume AWS EBS, GCE PD, Azure Disk ou Cinder) existe toujours après la suppression du PV. - Nettoyez manuellement les données sur l'actif de stockage associé en conséquence.
- Supprimez manuellement l'actif de stockage associé ou, si vous souhaitez réutiliser le même actif de stockage, créez un nouveau
PersistentVolume
avec la définition de l'actif de stockage.
Volumes supprimés
Pour les plug-ins de volume qui prennent en charge la stratégie de récupération Delete
, la suppression supprime à la fois l'objet PersistentVolume
de Kubernetes, ainsi que l'actif de stockage associé dans l'infrastructure externe, tel qu'un volume AWS EBS, GCE PD, Azure Disk ou Cinder.
Les volumes qui ont été dynamiquement provisionnés héritent de la politique de récupération de leur StorageClass
, qui par défaut est Delete
.
L'administrateur doit configurer la StorageClass
selon les attentes des utilisateurs; sinon, le PV doit être édité ou corrigé après sa création.
Voir Modifier la politique de récupération d'un PersistentVolume.
Volumes recyclés
Recycle
est obsolète.
Au lieu de cela, l'approche recommandée consiste à utiliser l'approvisionnement dynamique.
Si elle est prise en charge par le plug-in de volume sous-jacent, la stratégie de récupération Recycle
effectue un nettoyage de base (rm -rf /thevolume/*
) sur le volume et le rend à nouveau disponible pour une nouvelle demande.
Cependant, un administrateur peut configurer un modèle de module de recyclage personnalisé à l'aide des arguments de ligne de commande du gestionnaire de contrôleur Kubernetes, comme décrit ici.
Le modèle de pod de recycleur personnalisé doit contenir une définition de volumes
, comme le montre l'exemple ci-dessous:
apiVersion: v1
kind: Pod
metadata:
name: pv-recycler
namespace: default
spec:
restartPolicy: Never
volumes:
- name: vol
hostPath:
path: /any/path/it/will/be/replaced
containers:
- name: pv-recycler
image: "k8s.gcr.io/busybox"
command: ["/bin/sh", "-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z \"$(ls -A /scrub)\" || exit 1"]
volumeMounts:
- name: vol
mountPath: /scrub
Cependant, le chemin particulier spécifié dans la partie volumes
du template personnalisé de Pod est remplacée par le chemin particulier du volume qui est recyclé.
Redimensionnement des PVC
Kubernetes v1.11 [beta]
La prise en charge du redimensionnement des PersistentVolumeClaims (PVCs) est désormais activée par défaut. Vous pouvez redimensionner les types de volumes suivants:
- gcePersistentDisk
- awsElasticBlockStore
- Cinder
- glusterfs
- rbd
- Azure File
- Azure Disk
- Portworx
- FlexVolumes
- CSI
Vous ne pouvez redimensionner un PVC que si le champ allowVolumeExpansion
de sa classe de stockage est défini sur true.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gluster-vol-default
provisioner: kubernetes.io/glusterfs
parameters:
resturl: "http://192.168.10.100:8080"
restuser: ""
secretNamespace: ""
secretName: ""
allowVolumeExpansion: true
Pour demander un volume plus important pour un PVC, modifiez l'objet PVC et spécifiez une taille plus grande.
Cela déclenche l'expansion du volume qui soutient le PersistentVolume
sous-jacent.
Un nouveau PersistentVolume
n'est jamais créé pour satisfaire la demande.
Au lieu de cela, un volume existant est redimensionné.
Redimensionnement de volume CSI
Kubernetes v1.16 [beta]
La prise en charge du redimensionnement des volumes CSI est activée par défaut, mais elle nécessite également un pilote CSI spécifique pour prendre en charge le redimensionnement des volumes. Reportez-vous à la documentation du pilote CSI spécifique pour plus d'informations.
Redimensionner un volume contenant un système de fichiers
Vous ne pouvez redimensionner des volumes contenant un système de fichiers que si le système de fichiers est XFS, Ext3 ou Ext4.
Lorsqu'un volume contient un système de fichiers, le système de fichiers n'est redimensionné que lorsqu'un nouveau pod utilise le PersistentVolumeClaim
en mode ReadWrite.
L'extension du système de fichiers est effectuée au démarrage d'un pod ou lorsqu'un pod est en cours d'exécution et que le système de fichiers sous-jacent prend en charge le redimensionnement en ligne.
FlexVolumes autorise le redimensionnement si le pilote est défini avec la capacité requiresFSResize
sur true
.
Le FlexVolume peut être redimensionné au redémarrage du pod.
Redimensionnement d'un PersistentVolumeClaim en cours d'utilisation
Kubernetes v1.15 [beta]
ExpandInUsePersistentVolumes
doit être activée, ce qui est le cas automatiquement pour de nombreux clusters de fonctionnalités bêta.
Se référer à la documentation de la feature gate pour plus d'informations.
Dans ce cas, vous n'avez pas besoin de supprimer et de recréer un pod ou un déploiement qui utilise un PVC existant. Tout PVC en cours d'utilisation devient automatiquement disponible pour son pod dès que son système de fichiers a été étendu. Cette fonctionnalité n'a aucun effet sur les PVC qui ne sont pas utilisés par un pod ou un déploiement. Vous devez créer un pod qui utilise le PVC avant que l'extension puisse se terminer.
Semblable à d'autres types de volume - les volumes FlexVolume peuvent également être étendus lorsqu'ils sont utilisés par un pod.
Types de volumes persistants
Les types PersistentVolume
sont implémentés en tant que plugins.
Kubernetes prend actuellement en charge les plugins suivants:
- GCEPersistentDisk
- AWSElasticBlockStore
- AzureFile
- AzureDisk
- CSI
- FC (Fibre Channel)
- FlexVolume
- Flocker
- NFS
- iSCSI
- RBD (Ceph Block Device)
- CephFS
- Cinder (OpenStack block storage)
- Glusterfs
- VsphereVolume
- Quobyte Volumes
- HostPath (Test de nœud unique uniquement -- le stockage local n'est en aucun cas pris en charge et NE FONCTIONNERA PAS dans un cluster à plusieurs nœuds)
- Portworx Volumes
- ScaleIO Volumes
- StorageOS
Volumes persistants
Chaque PV contient une spécification et un état, qui sont les spécifications et l'état du volume.
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
/sbin/mount.nfs
est requis pour permettre de monter des systèmes de fichiers de type NFS.
Capacité
Généralement, un PV aura une capacité de stockage spécifique.
Ceci est réglé en utilisant l'attribut capacity
des PV.
Voir le Kubernetes modèle de ressource pour comprendre les unités attendues par capacity
.
Actuellement, la taille du stockage est la seule ressource qui peut être définie ou demandée. Les futurs attributs peuvent inclure les IOPS, le débit, etc.
Mode volume
Kubernetes v1.13 [beta]
Avant Kubernetes 1.9, tous les plug-ins de volume créaient un système de fichiers sur le volume persistant.
Maintenant, vous pouvez définir la valeur de volumeMode
sur block
pour utiliser un périphérique de bloc brut, ou filesystem
pour utiliser un système de fichiers.
filesystem
est la valeur par défaut si la valeur est omise.
Il s'agit d'un paramètre API facultatif.
Modes d'accès
Un PersistentVolume
peut être monté sur un hôte de n'importe quelle manière prise en charge par le fournisseur de ressources.
Comme indiqué dans le tableau ci-dessous, les fournisseurs auront des capacités différentes et les modes d'accès de chaque PV sont définis sur les modes spécifiques pris en charge par ce volume particulier.
Par exemple, NFS peut prendre en charge plusieurs clients en lecture/écriture, mais un PV NFS spécifique peut être exporté sur le serveur en lecture seule.
Chaque PV dispose de son propre ensemble de modes d'accès décrivant les capacités spécifiques de ce PV.
Les modes d'accès sont:
- ReadWriteOnce -- le volume peut être monté en lecture-écriture par un seul nœud
- ReadOnlyMany -- le volume peut être monté en lecture seule par plusieurs nœuds
- ReadWriteMany -- le volume peut être monté en lecture-écriture par de nombreux nœuds
Dans la CLI, les modes d'accès sont abrégés comme suit:
- RWO - ReadWriteOnce
- ROX - ReadOnlyMany
- RWX - ReadWriteMany
Important! Un volume ne peut être monté qu'en utilisant un seul mode d'accès à la fois, même s'il prend en charge plusieurs. Par exemple, un GCEPersistentDisk peut être monté en tant que ReadWriteOnce par un seul nœud ou ReadOnlyMany par plusieurs nœuds, mais pas en même temps.
Volume Plugin | ReadWriteOnce | ReadOnlyMany | ReadWriteMany |
---|---|---|---|
AWSElasticBlockStore | ✓ | - | - |
AzureFile | ✓ | ✓ | ✓ |
AzureDisk | ✓ | - | - |
CephFS | ✓ | ✓ | ✓ |
Cinder | ✓ | - | - |
CSI | dépend du pilote | dépend du pilote | dépend du pilote |
FC | ✓ | ✓ | - |
FlexVolume | ✓ | ✓ | dépend du pilote |
Flocker | ✓ | - | - |
GCEPersistentDisk | ✓ | ✓ | - |
Glusterfs | ✓ | ✓ | ✓ |
HostPath | ✓ | - | - |
iSCSI | ✓ | ✓ | - |
Quobyte | ✓ | ✓ | ✓ |
NFS | ✓ | ✓ | ✓ |
RBD | ✓ | ✓ | - |
VsphereVolume | ✓ | - | - (fonctionne lorsque les pods sont colocalisés) |
PortworxVolume | ✓ | - | ✓ |
ScaleIO | ✓ | ✓ | - |
StorageOS | ✓ | - | - |
Classe
Un PV peut avoir une classe, qui est spécifiée en définissant l'attribut storageClassName
sur le nom d'une StorageClass.
Un PV d'une classe particulière ne peut être lié qu'à des PVC demandant cette classe.
Un PV sans storageClassName
n'a pas de classe et ne peut être lié qu'à des PVC qui ne demandent aucune classe particulière.
Dans le passé, l'annotation volume.beta.kubernetes.io/storage-class
a été utilisé à la place de l'attribut storageClassName
.
Cette annotation fonctionne toujours; cependant, il deviendra complètement obsolète dans une future version de Kubernetes.
Politique de récupération
Les politiques de récupération actuelles sont:
- Retain -- remise en état manuelle
- Recycle -- effacement de base (
rm -rf /thevolume/*
) - Delete -- l'élément de stockage associé tel qu'AWS EBS, GCE PD, Azure Disk ou le volume OpenStack Cinder est supprimé
Actuellement, seuls NFS et HostPath prennent en charge le recyclage. Les volumes AWS EBS, GCE PD, Azure Disk et Cinder prennent en charge la suppression.
Options de montage
Un administrateur Kubernetes peut spécifier des options de montage supplémentaires pour quand un PersistentVolume
est monté sur un nœud.
Les types de volume suivants prennent en charge les options de montage:
- AWSElasticBlockStore
- AzureDisk
- AzureFile
- CephFS
- Cinder (OpenStack block storage)
- GCEPersistentDisk
- Glusterfs
- NFS
- Quobyte Volumes
- RBD (Ceph Block Device)
- StorageOS
- VsphereVolume
- iSCSI
Les options de montage ne sont pas validées, donc le montage échouera simplement si l'une n'est pas valide.
Dans le passé, l'annotation volume.beta.kubernetes.io/mount-options
était utilisée à la place de l'attribut mountOptions
.
Cette annotation fonctionne toujours; cependant, elle deviendra complètement obsolète dans une future version de Kubernetes.
Affinité des nœuds
Un PV peut spécifier une affinité de nœud pour définir les contraintes qui limitent les nœuds à partir desquels ce volume est accessible. Les pods qui utilisent un PV seront uniquement planifiés sur les nœuds sélectionnés par l'affinité de nœud.
Phase
Un volume sera dans l'une des phases suivantes:
- Available -- une ressource libre qui n'est pas encore liée à une demande
- Bound -- le volume est lié à une demande
- Released -- la demande a été supprimée, mais la ressource n'est pas encore récupérée par le cluster
- Failed -- le volume n'a pas réussi sa récupération automatique
Le CLI affichera le nom du PVC lié au PV.
PersistentVolumeClaims
Chaque PVC contient une spécification et un état, qui sont les spécifications et l'état de la réclamation.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
storageClassName: slow
selector:
matchLabels:
release: "stable"
matchExpressions:
- {key: environment, operator: In, values: [dev]}
Modes d'accès
Les PVC utilisent les mêmes conventions que les volumes lorsque vous demandez un stockage avec des modes d'accès spécifiques.
Modes de volume
Les PVC utilisent la même convention que les volumes pour indiquer la consommation du volume en tant que système de fichiers ou périphérique de bloc.
Ressources
Les PVC, comme les pods, peuvent demander des quantités spécifiques d'une ressource. Dans ce cas, la demande concerne le stockage. Le même modèle de ressource s'applique aux volumes et aux PVC.
Sélecteur
Les PVC peuvent spécifier un sélecteur de labels pour filtrer davantage l'ensemble des volumes. Seuls les volumes dont les étiquettes correspondent au sélecteur peuvent être liés au PVC. Le sélecteur peut comprendre deux champs:
matchLabels
- le volume doit avoir un label avec cette valeurmatchExpressions
- une liste des exigences définies en spécifiant la clé, la liste des valeurs et l'opérateur qui relie la clé et les valeurs. Les opérateurs valides incluent In, NotIn, Exists et DoesNotExist.
Toutes les exigences, à la fois de matchLabels
et de matchExpressions
doivent toutes être satisfaites pour correspondre (application d'un opérateur booléen ET).
Classe
Un PVC peut demander une classe particulière en spécifiant le nom d'une StorageClass en utilisant l'attribut storageClassName
.
Seuls les PV de la classe demandée, ceux ayant le même storageClassName
que le PVC, peuvent être liés au PVC.
Les PVC n'ont pas nécessairement à demander une classe.
Un PVC avec son attribut storageClassName
égal à ""
est toujours interprété comme demandant un PV sans classe, il ne peut donc être lié qu'à des PV sans classe (pas d'annotation ou une annotation égal à ""
).
Un PVC sans storageClassName
n'est pas tout à fait la même et est traité différemment par le cluster, selon que le DefaultStorageClass
admission plugin est activé.
- Si le plug-in d'admission est activé, l'administrateur peut spécifier une valeur par défaut
StorageClass
. Tous les PVC qui n'ont pas destorageClassName
ne peuvent être liés qu'aux PV de cette valeur par défaut. La spécification d'uneStorageClass
par défaut se fait en définissant l'annotationstorageclass.kubernetes.io/is-default-class
égal àtrue
dans un objetStorageClass
. Si l'administrateur ne spécifie pas de valeur par défaut, le cluster répond à la création de PVC comme si le plug-in d'admission était désactivé. Si plusieurs valeurs par défaut sont spécifiées, le plugin d'admission interdit la création de tous les PVC. - Si le plugin d'admission est désactivé, il n'y a aucune notion de défaut
StorageClass
. Tous les PVC qui n'ont passtorageClassName
peut être lié uniquement aux PV qui n'ont pas de classe. Dans ce cas, les PVC qui n'ont passtorageClassName
sont traités de la même manière que les PVC qui ont leurstorageClassName
égal à""
.
Selon la méthode d'installation, une StorageClass
par défaut peut être déployée sur un cluster Kubernetes par le gestionnaire d'extensions pendant l'installation.
Lorsqu'un PVC spécifie un selector
en plus de demander une StorageClass
, les exigences sont ET ensemble: seul un PV de la classe demandée et avec les labels demandées peut être lié au PVC.
selector
non vide ne peut pas avoir un PV provisionné dynamiquement pour cela.
Dans le passé, l'annotation volume.beta.kubernetes.io/storage-class
a été utilisé au lieu de l'attribut storageClassName
.
Cette annotation fonctionne toujours; cependant, elle ne sera pas pris en charge dans une future version de Kubernetes.
PVC sous forme de volumes
Les pods accèdent au stockage en utilisant le PVC comme volume.
Les PVC et les pods qui les utilisent doivent exister dans le même namespace.
Le cluster trouve le PVC dans le namespace où se trouve le pod et l'utilise pour obtenir le PersistentVolume
visé par le PVC.
Le volume est ensuite monté sur l'hôte et dans le pod.
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
Remarque au sujet des namespaces
Les liaisons PersistentVolumes
sont exclusives, et comme les objets PersistentVolumeClaims
sont des objets vivant dans un namespace donné, le montage de PVC avec les modes "Many" (ROX
, RWX
) n'est possible qu'au sein d'un même namespace.
Prise en charge du volume de bloc brut
Kubernetes v1.13 [beta]
Les plug-ins de volume suivants prennent en charge les volumes de blocs bruts, y compris l'approvisionnement dynamique, le cas échéant:
- AWSElasticBlockStore
- AzureDisk
- FC (Fibre Channel)
- GCEPersistentDisk
- iSCSI
- Local volume
- RBD (Ceph Block Device)
- VsphereVolume (alpha)
Volumes persistants utilisant un volume de bloc brut
apiVersion: v1
kind: PersistentVolume
metadata:
name: block-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
volumeMode: Block
persistentVolumeReclaimPolicy: Retain
fc:
targetWWNs: ["50060e801049cfd1"]
lun: 0
readOnly: false
Revendication de volume persistant demandant un volume de bloc brut
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: block-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Block
resources:
requests:
storage: 10Gi
Spécification de pod ajoutant le chemin du périphérique de bloc brut dans le conteneur
apiVersion: v1
kind: Pod
metadata:
name: pod-with-block-volume
spec:
containers:
- name: fc-container
image: fedora:26
command: ["/bin/sh", "-c"]
args: [ "tail -f /dev/null" ]
volumeDevices:
- name: data
devicePath: /dev/xvda
volumes:
- name: data
persistentVolumeClaim:
claimName: block-pvc
Lier des volumes bloc bruts
Si un utilisateur demande un volume de bloc brut en l'indiquant à l'aide du champ volumeMode
dans la spécification PersistentVolumeClaim
, les règles de liaison diffèrent légèrement des versions précédentes qui ne considéraient pas ce mode comme faisant partie de la spécification.
Voici un tableau des combinaisons possibles que l'utilisateur et l'administrateur peuvent spécifier pour demander un périphérique de bloc brut.
Le tableau indique si le volume sera lié ou non compte tenu des combinaisons:
Matrice de liaison de volume pour les volumes provisionnés statiquement:
| PV volumeMode | PVC volumeMode | Result | |---------------|-:-:------------|--:------| | unspecified | unspecified | BIND | | unspecified | Block | NO BIND | | unspecified | Filesystem | BIND | | Block | unspecified | NO BIND | | Block | Block | BIND | | Block | Filesystem | NO BIND | | Filesystem | Filesystem | BIND | | Filesystem | Block | NO BIND | | Filesystem | unspecified | BIND |
Snapshot et restauration de volumes
Kubernetes v1.12 [alpha]
La fonction de snapshot de volume a été ajoutée pour prendre en charge uniquement les plug-ins de volume CSI. Pour plus de détails, voir volume snapshots.
Pour activer la prise en charge de la restauration d'un volume à partir d'un snapshot de volume, activez la fonctionnalité VolumeSnapshotDataSource
sur l'apiserver et le controller-manager.
Créer du PVC à partir d'un snapshot de volume
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: restore-pvc
spec:
storageClassName: csi-hostpath-sc
dataSource:
name: new-snapshot-test
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Clonage de volume
Kubernetes v1.16 [beta]
La fonctionnalité de clonage de volume a été ajoutée pour prendre en charge uniquement les plug-ins de volume CSI. Pour plus de détails, voir clonage de volume.
Pour activer la prise en charge du clonage d'un volume à partir d'une source de données PVC, activez la propriété VolumePVCDataSource
sur l'apiserver et le controller-manager.
Créer un PVC à partir d'un PVC existant
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cloned-pvc
spec:
storageClassName: my-csi-plugin
dataSource:
name: existing-src-pvc-name
kind: PersistentVolumeClaim
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Écriture d'une configuration portable
Si vous écrivez des templates de configuration ou des exemples qui s'exécutent sur une large gamme de clusters et nécessitent un stockage persistant, il est recommandé d'utiliser le modèle suivant:
- Incluez des objets
PersistentVolumeClaim
dans votre ensemble de config (aux côtés deDeployments
,ConfigMaps
, etc.). - N'incluez pas d'objets
PersistentVolume
dans la configuration, car l'utilisateur qui instancie la configuration peut ne pas être autorisé à créer desPersistentVolumes
. - Donnez à l'utilisateur la possibilité de fournir un nom de classe de stockage lors de l'instanciation du template.
- Si l'utilisateur fournit un nom de classe de stockage, mettez cette valeur dans le champ
persistentVolumeClaim.storageClassName
. Cela entraînera le PVC pour utiliser la bonne classe de stockage si le cluster a cetteStorageClasses
activé par l'administrateur. - Si l'utilisateur ne fournit pas de nom de classe de stockage, laissez le champ
persistentVolumeClaim.storageClassName
à zéro. Cela entraînera un PV à être automatiquement provisionné pour l'utilisateur avec laStorageClass
par défaut dans le cluster. De nombreux environnements de cluster ont uneStorageClass
par défaut installée, où les administrateurs peuvent créer leur propreStorageClass
par défaut.
- Si l'utilisateur fournit un nom de classe de stockage, mettez cette valeur dans le champ
- Dans votre outillage, surveillez les PVCs qui ne sont pas liés après un certain temps et signalez-le à l'utilisateur, car cela peut indiquer que le cluster n'a pas de support de stockage dynamique (auquel cas l'utilisateur doit créer un PV correspondant) ou que le cluster n'a aucun système de stockage (auquel cas l'utilisateur ne peut pas déployer de configuration nécessitant des PVCs).
3.7 - Configuration
3.7.1 - Secrets
Les objets secret
de Kubernetes vous permettent de stocker et de gérer des informations sensibles, telles que les mots de passe, les jetons OAuth et les clés ssh.
Mettre ces informations dans un secret
est plus sûr et plus flexible que de le mettre en dur dans la définition d'un Pod ou dans une container image.
Voir Document de conception des secrets pour plus d'informations.
Présentation des secrets
Un secret est un objet qui contient une petite quantité de données sensibles telles qu'un mot de passe, un jeton ou une clé. De telles informations pourraient autrement être placées dans une spécification de pod ou dans une image; le placer dans un objet secret permet de mieux contrôler la façon dont il est utilisé et réduit le risque d'exposition accidentelle.
Les utilisateurs peuvent créer des secrets et le système crée également des secrets.
Pour utiliser un secret, un pod doit référencer le secret. Un secret peut être utilisé avec un pod de deux manières: sous forme de fichiers dans un volume monté sur un ou plusieurs de ses conteneurs, ou utilisé par kubelet lorsque vous récupérez des images pour le pod.
Secrets intégrés
Les comptes de service créent et attachent automatiquement des secrets avec les informations d'identification de l'API
Kubernetes crée automatiquement des secrets qui contiennent des informations d'identification pour accéder à l'API et il modifie automatiquement vos pods pour utiliser ce type de secret.
La création et l'utilisation automatiques des informations d'identification de l'API peuvent être désactivées ou remplacées si vous le souhaitez. Cependant, si tout ce que vous avez à faire est d'accéder en toute sécurité à l'apiserver, il s'agit de la méthode recommandée.
Voir la documentation des Compte de service pour plus d'informations sur le fonctionnement des comptes de service.
Créer vos propres secrets
Créer un secret avec kubectl create secret
Supposons que certains pods doivent accéder à une base de données.
Le nom d'utilisateur et le mot de passe que les pods doivent utiliser se trouvent dans les fichiers ./username.txt
et ./password.txt
sur votre machine locale.
# Create files needed for rest of example.
echo -n 'admin' > ./username.txt
echo -n '1f2d1e2e67df' > ./password.txt
La commande kubectl create secret
regroupe ces fichiers dans un secret et crée l'objet sur l'Apiserver.
kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
secret "db-user-pass" created
Les caractères spéciaux tels que $
, \
, *
, et !
seront interprétés par votre shell et nécessitent d'être échappés.
Dans les shells les plus courants, le moyen le plus simple d'échapper au mot de passe est de l'entourer de guillemets simples ('
).
Par exemple, si votre mot de passe réel est S!B\*d$zDsb
, vous devez exécuter la commande de cette façon:
kubectl create secret generic dev-db-secret --from-literal=username=devuser --from-literal=password='S!B\*d$zDsb'
Vous n'avez pas besoin d'échapper les caractères spéciaux dans les mots de passe des fichiers (--from-file
).
Vous pouvez vérifier que le secret a été créé comme ceci:
kubectl get secrets
NAME TYPE DATA AGE
db-user-pass Opaque 2 51s
kubectl describe secrets/db-user-pass
Name: db-user-pass
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password.txt: 12 bytes
username.txt: 5 bytes
kubectl get
et kubectl describe
évitent d'afficher le contenu d'un secret par défaut.
Il s'agit de protéger le secret contre une exposition accidentelle à un spectateur de l'écran ou contre son stockage dans un journal de terminal.
Voir décoder un secret pour voir le contenu d'un secret.
Création manuelle d'un secret
Vous pouvez également créer un secret dans un fichier d'abord, au format json ou yaml, puis créer cet objet.
Le secret contient deux table de hachage: data
et stringData
.
Le champ data
est utilisé pour stocker des données arbitraires, encodées en base64.
Le champ stringData
est fourni pour plus de commodité et vous permet de fournir des données secrètes sous forme de chaînes non codées.
Par exemple, pour stocker deux chaînes dans un secret à l'aide du champ data
, convertissez-les en base64 comme suit:
echo -n 'admin' | base64
YWRtaW4=
echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm
Écrivez un secret qui ressemble à ceci:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
Maintenant, créez le secret en utilisant kubectl apply
:
kubectl apply -f ./secret.yaml
secret "mysecret" created
Pour certains scénarios, vous pouvez utiliser le champ stringData
à la place.
Ce champ vous permet de mettre une chaîne non codée en base64 directement dans le secret, et la chaîne sera codée pour vous lorsque le secret sera créé ou mis à jour.
Un exemple pratique de cela pourrait être le suivant: vous déployez une application qui utilise un secret pour stocker un fichier de configuration. Vous souhaitez remplir des parties de ce fichier de configuration pendant votre processus de déploiement.
Si votre application utilise le fichier de configuration suivant:
apiUrl: "https://my.api.com/api/v1"
username: "user"
password: "password"
Vous pouvez stocker cela dans un secret en utilisant ce qui suit:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
stringData:
config.yaml: |-
apiUrl: "https://my.api.com/api/v1"
username: {{username}}
password: {{password}}
Votre outil de déploiement pourrait alors remplacer les variables de modèle {{username}}
et {{password}}
avant d'exécuter kubectl apply
.
stringData
est un champ de commodité en écriture seule.
Il n'est jamais affiché lors de la récupération des secrets.
Par exemple, si vous exécutez la commande suivante:
kubectl get secret mysecret -o yaml
La sortie sera similaire à:
apiVersion: v1
kind: Secret
metadata:
creationTimestamp: 2018-11-15T20:40:59Z
name: mysecret
namespace: default
resourceVersion: "7225"
uid: c280ad2e-e916-11e8-98f2-025000000001
type: Opaque
data:
config.yaml: YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IHt7dXNlcm5hbWV9fQpwYXNzd29yZDoge3twYXNzd29yZH19
Si un champ est spécifié à la fois dans data
et stringData
, la valeur de stringData
est utilisée.
Par exemple, la définition de secret suivante:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
stringData:
username: administrateur
Donnera le secret suivant:
apiVersion: v1
kind: Secret
metadata:
creationTimestamp: 2018-11-15T20:46:46Z
name: mysecret
namespace: default
resourceVersion: "7579"
uid: 91460ecb-e917-11e8-98f2-025000000001
type: Opaque
data:
username: YWRtaW5pc3RyYXRldXI=
Où YWRtaW5pc3RyYXRldXI=
décode en administrateur
.
Les clés de data
et stringData
doivent être composées de caractères alphanumériques, '-', '_' ou '.'.
Encoding Note: Les valeurs JSON et YAML sérialisées des données secrètes sont codées sous forme de chaînes base64.
Les sauts de ligne ne sont pas valides dans ces chaînes et doivent être omis.
Lors de l'utilisation de l'utilitaire base64
sur Darwin / macOS, les utilisateurs doivent éviter d'utiliser l'option -b
pour diviser les longues lignes.
Inversement, les utilisateurs Linux devraient ajouter l'option -w 0
aux commandes base64
ou le pipeline base64 | tr -d '\ n'
si l'option -w
n'est pas disponible.
Création d'un secret à partir du générateur
Kubectl prend en charge la gestion des objets à l'aide de Kustomize depuis 1.14.
Avec cette nouvelle fonctionnalité, vous pouvez également créer un secret à partir de générateurs, puis l'appliquer pour créer l'objet sur l'Apiserver.
Les générateurs doivent être spécifiés dans un kustomization.yaml
à l'intérieur d'un répertoire.
Par exemple, pour générer un secret à partir des fichiers ./username.txt
et ./password.txt
# Create a kustomization.yaml file with SecretGenerator
cat <<EOF >./kustomization.yaml
secretGenerator:
- name: db-user-pass
files:
- username.txt
- password.txt
EOF
Appliquez le répertoire de personnalisation pour créer l'objet secret.
$ kubectl apply -k .
secret/db-user-pass-96mffmfh4k created
Vous pouvez vérifier que le secret a été créé comme ceci:
$ kubectl get secrets
NAME TYPE DATA AGE
db-user-pass-96mffmfh4k Opaque 2 51s
$ kubectl describe secrets/db-user-pass-96mffmfh4k
Name: db-user-pass
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password.txt: 12 bytes
username.txt: 5 bytes
Par exemple, pour générer un secret à partir des littéraux username=admin
et password=secret
, vous pouvez spécifier le générateur de secret dans kustomization.yaml
comme:
# Create a kustomization.yaml file with SecretGenerator
$ cat <<EOF >./kustomization.yaml
secretGenerator:
- name: db-user-pass
literals:
- username=admin
- password=secret
EOF
Appliquer le repertoire kustomization pour créer l'objet secret.
$ kubectl apply -k .
secret/db-user-pass-dddghtt9b5 created
Décoder un secret
Les secrets peuvent être récupérés via la command kubectl get secret
.
Par exemple, pour récupérer le secret créé dans la section précédente:
kubectl get secret mysecret -o yaml
apiVersion: v1
kind: Secret
metadata:
creationTimestamp: 2016-01-22T18:41:56Z
name: mysecret
namespace: default
resourceVersion: "164619"
uid: cfee02d6-c137-11e5-8d73-42010af00002
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
Décodez le champ du mot de passe:
echo 'MWYyZDFlMmU2N2Rm' | base64 --decode
1f2d1e2e67df
Modification d'un secret
Un secret existant peut être modifié avec la commande suivante:
kubectl edit secrets mysecret
Cela ouvrira l'éditeur configuré par défaut et permettra de mettre à jour les valeurs secrètes codées en base64 dans le champ data
:
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: { ... }
creationTimestamp: 2016-01-22T18:41:56Z
name: mysecret
namespace: default
resourceVersion: "164619"
uid: cfee02d6-c137-11e5-8d73-42010af00002
type: Opaque
Utiliser les secrets
Les secrets peuvent être montés en tant que volumes de données ou être exposés en tant que variables d'environnement à utiliser par un conteneur dans un Pod. Ils peuvent également être utilisés par d'autres parties du système, sans être directement exposés aux Pods. Par exemple, ils peuvent détenir des informations d'identification que d'autres parties du système doivent utiliser pour interagir avec des systèmes externes en votre nom.
Utilisation de secrets comme fichiers d'un pod
Pour consommer un secret dans un volume dans un pod:
- Créez un secret ou utilisez-en un déjà existant. Plusieurs Pods peuvent référencer le même secret.
- Modifiez la définition de votre Pod pour ajouter un volume sous
.spec.volumes[]
. Nommez le volume et ayez un champ.spec.volumes[].secret.secretName
égal au nom de l'objet secret. - Ajouter un
.spec.containers[].volumeMounts[]
à chaque conteneur qui a besoin du secret. Spécifier.spec.containers[].volumeMounts[].readOnly = true
et.spec.containers[].volumeMounts[].mountPath
à un nom de répertoire inutilisé où vous souhaitez que les secrets apparaissent. - Modifiez votre image et/ou votre ligne de commande pour que le programme recherche les fichiers dans ce répertoire.
Chaque clé de la carte secrète
data
devient le nom de fichier sousmountPath
.
Voici un exemple de pod qui monte un secret dans un volume:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
Chaque secret que vous souhaitez utiliser doit être mentionné dans .spec.volumes
.
S'il y a plusieurs conteneurs dans le pod, alors chaque conteneur a besoin de son propre bloc volumeMounts
, mais un seul .spec.volumes
est nécessaire par secret.
Vous pouvez regrouper de nombreux fichiers en un seul secret ou utiliser de nombreux secrets, selon le cas.
Projection de clés secrètes vers des chemins spécifiques
Nous pouvons également contrôler les chemins dans le volume où les clés secrètes sont projetées.
Vous pouvez utiliser le champ .spec.volumes []. Secret.items
pour changer le chemin cible de chaque clé:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
Que se passera-t-il:
username
est stocké dans le fichier/etc/foo/my-group/my-username
au lieu de/etc/foo/username
.password
n'est pas projeté
Si .spec.volumes[].secret.items
est utilisé, seules les clés spécifiées dans items
sont projetées.
Pour consommer toutes les clés du secret, toutes doivent être répertoriées dans le champ items
.
Toutes les clés répertoriées doivent exister dans le secret correspondant.
Sinon, le volume n'est pas créé.
Autorisations de fichiers secrets
Vous pouvez également spécifier les bits de mode d'autorisation des fichiers contenant les parties d'un secret.
Si vous n'en spécifiez pas, 0644
est utilisé par défaut.
Vous pouvez spécifier un mode par défaut pour tout le volume secret et remplacer par clé si nécessaire.
Par exemple, vous pouvez spécifier un mode par défaut comme celui-ci:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
volumes:
- name: foo
secret:
secretName: mysecret
defaultMode: 256
Ensuite, le secret sera monté sur /etc/foo
et tous les fichiers créés par le montage de volume secret auront la permission 0400
.
Notez que la spécification JSON ne prend pas en charge la notation octale, utilisez donc la valeur 256 pour les autorisations 0400. Si vous utilisez yaml au lieu de json pour le pod, vous pouvez utiliser la notation octale pour spécifier les autorisations de manière plus naturelle.
Vous pouvez aussi utiliser un mapping, comme dans l'exemple précédent, et spécifier des autorisations différentes pour différents fichiers comme celui-ci:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
mode: 511
Dans ce cas, le fichier résultant /etc/foo/my-group/my-username
aura la valeur d'autorisation de 0777
.
En raison des limitations JSON, vous devez spécifier le mode en notation décimale.
Notez que cette valeur d'autorisation peut être affichée en notation décimale si vous la lisez plus tard.
Consommer des valeurs secrètes à partir de volumes
À l'intérieur du conteneur qui monte un volume secret, les clés secrètes apparaissent sous forme de fichiers et les valeurs secrètes sont décodées en base 64 et stockées à l'intérieur de ces fichiers. C'est le résultat des commandes exécutées à l'intérieur du conteneur de l'exemple ci-dessus:
ls /etc/foo/
username
password
cat /etc/foo/username
admin
cat /etc/foo/password
1f2d1e2e67df
Le programme dans un conteneur est responsable de la lecture des secrets des fichiers.
Les secrets montés sont mis à jour automatiquement
Lorsqu'un secret déjà consommé dans un volume est mis à jour, les clés projetées sont finalement mises à jour également.
Kubelet vérifie si le secret monté est récent à chaque synchronisation périodique.
Cependant, il utilise son cache local pour obtenir la valeur actuelle du Secret.
Le type de cache est configurable à l'aide de le champ ConfigMapAndSecretChangeDetectionStrategy
dans la structure KubeletConfiguration.
Il peut être soit propagé via watch (par défaut), basé sur ttl, ou simplement redirigé toutes les requêtes vers directement kube-apiserver.
Par conséquent, le délai total entre le moment où le secret est mis à jour et le moment où de nouvelles clés sont projetées sur le pod peut être aussi long que la période de synchronisation du kubelet + le délai de propagation du cache, où le délai de propagation du cache dépend du type de cache choisi (cela équivaut au delai de propagation du watch, ttl du cache, ou bien zéro).
Utilisation de secrets comme variables d'environnement
Pour utiliser un secret dans une variable d'environnement dans un pod:
- Créez un secret ou utilisez-en un déjà existant. Plusieurs pods peuvent référencer le même secret.
- Modifiez la définition de votre pod dans chaque conteneur où vous souhaitez utiliser la valeur d'une clé secrète pour ajouter une variable d'environnement pour chaque clé secrète que vous souhaitez consommer.
La variable d'environnement qui consomme la clé secrète doit remplir le nom et la clé du secret dans
env[].valueFrom.secretKeyRef
. - Modifiez votre image et/ou votre ligne de commande pour que le programme recherche des valeurs dans les variables d'environnement spécifiées
Voici un exemple de pod qui utilise des secrets de variables d'environnement:
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
restartPolicy: Never
Consommation de valeurs secrètes à partir de variables d'environnement
À l'intérieur d'un conteneur qui consomme un secret dans des variables d'environnement, les clés secrètes apparaissent comme des variables d'environnement normales contenant les valeurs décodées en base64 des données secrètes. C'est le résultat des commandes exécutées à l'intérieur du conteneur de l'exemple ci-dessus:
echo $SECRET_USERNAME
admin
echo $SECRET_PASSWORD
1f2d1e2e67df
Utilisation des imagePullSecrets
Un imagePullSecret
est un moyen de transmettre un secret qui contient un mot de passe de registre d'images Docker (ou autre) au Kubelet afin qu'il puisse extraire une image privée au nom de votre Pod.
Spécification manuelle d'une imagePullSecret
L'utilisation de imagePullSecrets
est décrite dans la documentation des images
Arranging for imagePullSecrets to be Automatically Attached
Vous pouvez créer manuellement un imagePullSecret
et le référencer à partir d'un serviceAccount
.
Tous les pods créés avec ce serviceAccount
ou cette valeur par défaut pour utiliser ce serviceAccount
, verront leur champ imagePullSecret
défini sur celui du compte de service.
Voir Ajouter ImagePullSecrets à un compte de service pour une explication détaillée de ce processus.
Montage automatique de secrets créés manuellement
Les secrets créés manuellement (par exemple, un contenant un jeton pour accéder à un compte github) peuvent être automatiquement associés aux pods en fonction de leur compte de service. Voir Injection d'informations dans des pods à l'aide d'un PodPreset pour une explication détaillée de ce processus.
Details
Restrictions
Les sources de volume secrètes sont validées pour garantir que la référence d'objet spécifiée pointe réellement vers un objet de type Secret. Par conséquent, un secret doit être créé avant tous les pods qui en dépendent.
Les objets API secrets résident dans un namespace. Ils ne peuvent être référencés que par des pods dans le même espace de noms.
Les secrets individuels sont limités à 1 Mo de taille. C'est pour décourager la création de très grands secrets qui épuiseraient la mémoire de l'apiserver et du kubelet. Cependant, la création de nombreux petits secrets pourrait également épuiser la mémoire. Des limites plus complètes sur l'utilisation de la mémoire en raison de secrets sont une fonctionnalité prévue.
Kubelet prend uniquement en charge l'utilisation des secrets pour les pods qu'il obtient du serveur API.
Cela inclut tous les pods créés à l'aide de kubectl, ou indirectement via un contrôleur de réplication.
Il n'inclut pas les pods créés via les drapeaux kubelet --manifest-url
, ou --config
, ou son API REST (ce ne sont pas des moyens courants de créer des Pods).
Les secrets doivent être créés avant d'être consommés dans les pods en tant que variables d'environnement, sauf s'ils sont marqués comme facultatifs. Les références à des secrets qui n'existent pas empêcheront le pod de démarrer.
Les références via secretKeyRef
à des clés qui n'existent pas dans un Secret nommé empêcheront le pod de démarrer.
Les secrets utilisés pour remplir les variables d'environnement via envFrom
qui ont des clés considérées comme des noms de variables d'environnement non valides verront ces clés ignorées.
Le pod sera autorisé à démarrer.
Il y aura un événement dont la raison est InvalidVariableNames
et le message contiendra la liste des clés invalides qui ont été ignorées.
L'exemple montre un pod qui fait référence au / mysecret par défaut qui contient 2 clés invalides, 1badkey et 2alsobad.
kubectl get events
LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON
0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames kubelet, 127.0.0.1 Keys [1badkey, 2alsobad] from the EnvFrom secret default/mysecret were skipped since they are considered invalid environment variable names.
Cycle de vie de l'intéraction Secret et Pod
Lorsqu'un pod est créé via l'API, il n'est pas vérifié s'il existe un secret référencé. Une fois qu'un pod est programmé, le kubelet tentera de récupérer la valeur secrète. Si le secret ne peut pas être récupéré parce qu'il n'existe pas ou en raison d'un manque temporaire de connexion au serveur API, kubelet réessayera périodiquement. Il rapportera un événement sur le pod expliquant la raison pour laquelle il n'a pas encore démarré. Une fois le secret récupéré, le kubelet créera et montera un volume le contenant. Aucun des conteneurs du pod ne démarre tant que tous les volumes du pod ne sont pas montés.
Cas d'utilisation
Cas d'utilisation: pod avec clés SSH
Créez un kustomization.yaml avec un SecretGenerator
contenant quelques clés SSH:
kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/path/to/.ssh/id_rsa --from-file=ssh-publickey=/path/to/.ssh/id_rsa.pub
secret "ssh-key-secret" created
Nous pouvons maintenant créer un pod qui référence le secret avec la clé SSH et le consomme dans un volume:
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
labels:
name: secret-test
spec:
volumes:
- name: secret-volume
secret:
secretName: ssh-key-secret
containers:
- name: ssh-test-container
image: mySshImage
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
Lorsque la commande du conteneur s'exécute, les morceaux de la clé seront disponibles dans:
/etc/secret-volume/ssh-publickey
/etc/secret-volume/ssh-privatekey
Le conteneur est alors libre d'utiliser les données secrètes pour établir une connexion SSH.
Cas d'utilisation: pods avec informations d'identification de prod/test
Faites un fichier kustomization.yaml avec un SecretGenerator.
Cet exemple illustre un Pod qui consomme un secret contenant des informations d'identification de prod et un autre Pod qui consomme un secret avec des informations d'identification d'environnement de test.
kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11
secret "prod-db-secret" created
kubectl create secret generic test-db-secret --from-literal=username=testuser --from-literal=password=iluvtests
secret "test-db-secret" created
Caractères spéciaux tels que $
, \
, *
, et !
seront interprétés par votre shell et nécessitent d'être échappés.
Dans les shells les plus courants, le moyen le plus simple d'échapper au mot de passe est de l'entourer de guillemets simples ('
).
Par exemple, si votre mot de passe réel est S!B\*d$zDsb
, vous devez exécuter la commande de cette façon:
kubectl create secret generic dev-db-secret --from-literal=username=devuser --from-literal=password='S!B\*d$zDsb'
Vous n'avez pas besoin d'échapper les caractères spéciaux dans les mots de passe des fichiers (--from-file
).
Maintenant, faites les pods:
$ cat <<EOF > pod.yaml
apiVersion: v1
kind: List
items:
- kind: Pod
apiVersion: v1
metadata:
name: prod-db-client-pod
labels:
name: prod-db-client
spec:
volumes:
- name: secret-volume
secret:
secretName: prod-db-secret
containers:
- name: db-client-container
image: myClientImage
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
- kind: Pod
apiVersion: v1
metadata:
name: test-db-client-pod
labels:
name: test-db-client
spec:
volumes:
- name: secret-volume
secret:
secretName: test-db-secret
containers:
- name: db-client-container
image: myClientImage
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
EOF
Ajoutez les pods à la même kustomization.yaml
$ cat <<EOF >> kustomization.yaml
resources:
- pod.yaml
EOF
Appliquez tous ces objets sur l'Apiserver avec
kubectl apply -k .
Les deux conteneurs auront les fichiers suivants présents sur leurs systèmes de fichiers avec les valeurs pour l'environnement de chaque conteneur:
/etc/secret-volume/username
/etc/secret-volume/password
Notez comment les spécifications pour les deux pods ne diffèrent que dans un champ; cela facilite la création de pods avec différentes capacités à partir d'un template de pod commun.
Vous pouvez encore simplifier la spécification du pod de base en utilisant deux comptes de service: un appelé, disons, prod-user
avec le secret prod-db-secret
, et un appelé, test-user
avec le secret test-db-secret
.
Ensuite, la spécification du pod peut être raccourcie, par exemple:
apiVersion: v1
kind: Pod
metadata:
name: prod-db-client-pod
labels:
name: prod-db-client
spec:
serviceAccount: prod-db-client
containers:
- name: db-client-container
image: myClientImage
Cas d'utilisation: Dotfiles dans un volume secret
Afin de masquer des données (c'est-à-dire dans un fichier dont le nom commence par un point), il suffit de faire commencer cette clé par un point. Par exemple, lorsque le secret suivant est monté dans un volume:
apiVersion: v1
kind: Secret
metadata:
name: dotfile-secret
data:
.secret-file: dmFsdWUtMg0KDQo=
---
apiVersion: v1
kind: Pod
metadata:
name: secret-dotfiles-pod
spec:
volumes:
- name: secret-volume
secret:
secretName: dotfile-secret
containers:
- name: dotfile-test-container
image: k8s.gcr.io/busybox
command:
- ls
- "-l"
- "/etc/secret-volume"
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
Le secret-volume
contiendra un seul fichier, appelé .secret-file
, et le dotfile-test-container
aura ce fichier présent au chemin /etc/secret-volume/.secret-file
.
ls -l
; vous devez utiliser ls -la
pour les voir lors de la liste du contenu du répertoire.
Cas d'utilisation: secret visible pour un conteneur dans un pod
Envisagez un programme qui doit gérer les requêtes HTTP, effectuer une logique métier complexe, puis signer certains messages avec un HMAC. Parce qu'il a une logique d'application complexe, il pourrait y avoir un exploit de lecture de fichier à distance inaperçu dans le serveur, qui pourrait exposer la clé privée à un attaquant.
Cela pourrait être divisé en deux processus dans deux conteneurs: un conteneur frontal qui gère l'interaction utilisateur et la logique métier, mais qui ne peut pas voir la clé privée; et un conteneur de signataire qui peut voir la clé privée, et répond aux demandes de signature simples du frontend (par exemple sur le réseau localhost).
Avec cette approche partitionnée, un attaquant doit maintenant inciter le serveur d'applications à faire quelque chose d'assez arbitraire, ce qui peut être plus difficile que de lui faire lire un fichier.
Les meilleures pratiques
Clients qui utilisent l'API secrets
Lors du déploiement d'applications qui interagissent avec l'API secrets, l'accès doit être limité à l'aide de politiques d'autorisation telles que RBAC.
Les secrets contiennent souvent des valeurs qui couvrent un spectre d'importance, dont beaucoup peuvent provoquer des escalades au sein de Kubernetes (par exemple, les jetons de compte de service) et vers les systèmes externes. Même si une application individuelle peut raisonner sur la puissance des secrets avec lesquels elle s'attend à interagir, d'autres applications dans le même namespace peuvent rendre ces hypothèses invalides.
Pour ces raisons, les requêtes watch
et list
pour les secrets dans un namespace sont des capacités extrêmement puissantes et doivent être évitées, puisque la liste des secrets permet aux clients d'inspecter les valeurs de tous les secrets qui se trouvent dans ce namespace.
La capacité à effectuer un watch
ou list
des secrets dans un cluster doit être réservé uniquement aux composants les plus privilégiés au niveau du système.
Les applications qui ont besoin d'accéder à l'API secrets doivent effectuer des requêtes get
sur les secrets dont elles ont besoin.
Cela permet aux administrateurs de restreindre l'accès à tous les secrets tout en donnant accès en liste blanche aux instances individuelles dont l'application a besoin.
Pour des performances améliorées sur une boucle get
, les clients peuvent concevoir des ressources qui font référence à un secret puis watch
la ressource, demandant à nouveau le secret lorsque la ressource change.
De plus, un "bulk watch" API laisse les clients watch
des ressources individuelles ont également été proposées et seront probablement disponibles dans les prochaines versions de Kubernetes.
Propriétés de sécurité
Protections
Étant donné que les objets secrets peuvent être créés indépendamment des Pods qui les utilisent, il y a moins de risques que le secret soit exposé pendant la création, la visualisation et la modification des Pods. Le système peut également prendre des précautions supplémentaires avec les objets secrets, comme éviter de les écrire sur le disque lorsque cela est possible.
Un secret n'est envoyé à un nœud que si un module sur ce nœud l'exige.
Kubelet stocke le secret dans un tmpfs
afin que le secret ne soit pas écrit sur le stockage sur disque.
Une fois que le pod qui dépend du secret est supprimé, kubelet supprimera également sa copie locale des données secrètes.
Il peut y avoir des secrets pour plusieurs pods sur le même nœud. Cependant, seuls les secrets qu'un pod demande sont potentiellement visibles dans ses conteneurs. Par conséquent, un pod n'a pas accès aux secrets d'un autre pod.
Il peut y avoir plusieurs conteneurs dans un pod.
Cependant, chaque conteneur d'un pod doit demander le volume secret dans ses volumesMounts
pour qu'il soit visible dans le conteneur.
Cela peut être utilisé pour construire des partitions de sécurité au niveau du pod.
Sur la plupart des distributions gérées par le projet Kubernetes, la communication entre l'utilisateur vers l'apiserver et entre l'apiserver et les kubelets est protégée par SSL/TLS. Les secrets sont protégés lorsqu'ils sont transmis sur ces canaux.
Kubernetes v1.13 [beta]
Vous pouvez activer le chiffrement au repos pour les données secrètes, afin que les secrets ne soient pas stockés en clair dans etcd.
Risques
- Dans le serveur API, les données secrètes sont stockées dans etcd; par conséquent:
- Les administrateurs doivent activer le chiffrement au repos pour les données du cluster (nécessite la version 1.13 ou ultérieure)
- Les administrateurs devraient limiter l'accès à etcd aux utilisateurs administrateurs
- Les administrateurs peuvent vouloir effacer/détruire les disques utilisés par etcd lorsqu'ils ne sont plus utilisés
- Si vous exécutez etcd dans un cluster, les administrateurs doivent s'assurer d'utiliser SSL/TLS pour la communication peer-to-peer etcd.
- Si vous configurez le secret via un fichier manifeste (JSON ou YAML) qui a les données secrètes codées en base64, partager ce fichier ou l'archiver dans un dépot de source signifie que le secret est compromis. L'encodage Base64 n'est pas une méthode de chiffrement, il est considéré comme identique au texte brut.
- Les applications doivent toujours protéger la valeur du secret après l'avoir lu dans le volume, comme ne pas le mettre accidentellement dans un journal ou le transmettre à une partie non fiable.
- Un utilisateur qui peut créer un pod qui utilise un secret peut également voir la valeur de ce secret. Même si la stratégie apiserver ne permet pas à cet utilisateur de lire l'objet secret, l'utilisateur peut créer un pod qui expose le secret.
- Actuellement, toute personne disposant des droit root sur n'importe quel nœud peut lire n'importe quel secret depuis l'apiserver, en usurpant l'identité du kubelet. Il est prévu de n'envoyer des secrets qu'aux nœuds qui en ont réellement besoin, pour limiter l'impact d'un exploit root sur un seul nœud.
A suivre
3.8 - Sécurité
3.9 - Politiques
3.10 - Administration d'un cluster
3.10.1 - Vue d'ensemble de l'administration d'un cluster
La vue d'ensemble de l'administration d'un cluster est destinée à toute personne créant ou administrant un cluster Kubernetes. Il suppose une certaine familiarité avec les concepts de Kubernetes.
Planifier le déploiement d'un cluster
Voir le guide: choisir la bonne solution pour des exemples de planification, de mise en place et de configuration de clusters Kubernetes. Les solutions répertoriées dans cet article s'appellent des distributions.
Avant de choisir un guide, voici quelques considérations:
- Voulez-vous simplement essayer Kubernetes sur votre machine ou voulez-vous créer un cluster haute disponibilité à plusieurs nœuds? Choisissez les distributions les mieux adaptées à vos besoins.
- Si vous recherchez la haute disponibilité, apprenez à configurer des clusters multi zones.
- Utiliserez-vous un cluster Kubernetes hébergé, comme Google Kubernetes Engine, ou hébergerez-vous votre propre cluster?
- Votre cluster sera-t-il on-premises, ou sur un cloud (IaaS)? Kubernetes ne prend pas directement en charge les clusters hybrides. Cependant, vous pouvez configurer plusieurs clusters.
- Si vous configurez Kubernetes on-premises, choisissez le modèle réseau qui vous convient le mieux.
- Voulez-vous faire tourner Kubernetes sur du bare metal ou sur des machines virtuelles (VMs)?
- Voulez-vous simplement faire tourner un cluster, ou vous attendez-vous à faire du développement actif sur le code du projet Kubernetes? Dans ce dernier cas, choisissez une distribution activement développée. Certaines distributions n’utilisent que des versions binaires, mais offrent une plus grande variété de choix.
- Familiarisez-vous avec les composants nécessaires pour faire tourner un cluster.
A noter: Toutes les distributions ne sont pas activement maintenues. Choisissez des distributions qui ont été testées avec une version récente de Kubernetes.
Gérer un cluster
-
Gérer un cluster décrit plusieurs rubriques relatives au cycle de vie d’un cluster: création d’un nouveau cluster, mise à niveau des nœuds maître et des workers de votre cluster, maintenance des nœuds (mises à niveau du noyau, par exemple) et mise à niveau de la version de l’API Kubernetes d’un cluster en cours d’exécution.
-
Apprenez comment gérer les nœuds.
-
Apprenez à configurer et gérer les quotas de ressources pour les clusters partagés.
Sécuriser un cluster
-
La rubrique Certificats décrit les étapes à suivre pour générer des certificats à l’aide de différentes suites d'outils.
-
L' Environnement de conteneur dans Kubernetes décrit l'environnement des conteneurs gérés par Kubelet sur un nœud Kubernetes.
-
Le Contrôle de l'accès à l'API Kubernetes explique comment configurer les autorisations pour les utilisateurs et les comptes de service.
-
La rubrique Authentification explique l'authentification dans Kubernetes, y compris les différentes options d'authentification.
-
Autorisations est distinct de l'authentification et contrôle le traitement des appels HTTP.
-
Utiliser les Admission Controllers explique les plug-ins qui interceptent les requêtes adressées au serveur d'API Kubernetes après authentification et autorisation.
-
Utiliser Sysctls dans un cluster Kubernetes explique aux administrateurs comment utiliser l'outil de ligne de commande
sysctl
pour définir les paramètres du noyau. -
Auditer explique comment interagir avec les journaux d'audit de Kubernetes.
Sécuriser la Kubelet
Services de cluster optionnels
-
Integration DNS décrit comment résoudre un nom DNS directement vers un service Kubernetes.
-
Journalisation des évènements et surveillance de l'activité du cluster explique le fonctionnement de la journalisation des évènements dans Kubernetes et son implémentation.
3.10.2 - Certificats
Lorsque vous utilisez l'authentification par certificats client, vous pouvez générer des certificats
manuellement grâce à easyrsa
, openssl
ou cfssl
.
easyrsa
easyrsa peut générer manuellement des certificats pour votre cluster.
-
Téléchargez, décompressez et initialisez la version corrigée de easyrsa3.
curl -LO https://storage.googleapis.com/kubernetes-release/easy-rsa/easy-rsa.tar.gz tar xzf easy-rsa.tar.gz cd easy-rsa-master/easyrsa3 ./easyrsa init-pki
-
Générez une CA. (
--batch
pour le mode automatique.--req-cn
CN par défaut à utiliser)./easyrsa --batch "--req-cn=${MASTER_IP}@`date +%s`" build-ca nopass
-
Générer un certificat de serveur et une clé. L' argument
--subject-alt-name
définit les adresses IP et noms DNS possibles par lesquels l'API serveur peut être atteind. LaMASTER_CLUSTER_IP
est généralement la première adresse IP du CIDR des services qui est spécifié en tant qu'argument--service-cluster-ip-range
pour l'API Server et le composant controller manager. L'argument--days
est utilisé pour définir le nombre de jours après lesquels le certificat expire. L’exemple ci-dessous suppose également que vous utilisezcluster.local
par défaut comme nom de domaine DNS../easyrsa --subject-alt-name="IP:${MASTER_IP},"\ "IP:${MASTER_CLUSTER_IP},"\ "DNS:kubernetes,"\ "DNS:kubernetes.default,"\ "DNS:kubernetes.default.svc,"\ "DNS:kubernetes.default.svc.cluster,"\ "DNS:kubernetes.default.svc.cluster.local" \ --days=10000 \ build-server-full server nopass
-
Copiez
pki/ca.crt
,pki/issued/server.crt
, etpki/private/server.key
dans votre répertoire. -
Personnalisez et ajoutez les lignes suivantes aux paramètres de démarrage de l'API Server:
--client-ca-file=/yourdirectory/ca.crt --tls-cert-file=/yourdirectory/server.crt --tls-private-key-file=/yourdirectory/server.key
openssl
openssl peut générer manuellement des certificats pour votre cluster.
-
Générez ca.key en 2048bit:
openssl genrsa -out ca.key 2048
-
A partir de la clé ca.key générez ca.crt (utilisez -days pour définir la durée du certificat):
openssl req -x509 -new -nodes -key ca.key -subj "/CN=${MASTER_IP}" -days 10000 -out ca.crt
-
Générez server.key en 2048bit:
openssl genrsa -out server.key 2048
-
Créez un fichier de configuration pour générer une demande de signature de certificat (CSR). Assurez-vous de remplacer les valeurs marquées par des "< >" (par exemple,
<MASTER_IP>
) avec des valeurs réelles avant de l'enregistrer dans un fichier (par exemple,csr.conf
). Notez que la valeur deMASTER_CLUSTER_IP
est celle du service Cluster IP pour l' API Server comme décrit dans la sous-section précédente. L’exemple ci-dessous suppose également que vous utilisezcluster.local
par défaut comme nom de domaine DNS.[ req ] default_bits = 2048 prompt = no default_md = sha256 req_extensions = req_ext distinguished_name = dn [ dn ] C = <country> ST = <state> L = <city> O = <organization> OU = <organization unit> CN = <MASTER_IP> [ req_ext ] subjectAltName = @alt_names [ alt_names ] DNS.1 = kubernetes DNS.2 = kubernetes.default DNS.3 = kubernetes.default.svc DNS.4 = kubernetes.default.svc.cluster DNS.5 = kubernetes.default.svc.cluster.local IP.1 = <MASTER_IP> IP.2 = <MASTER_CLUSTER_IP> [ v3_ext ] authorityKeyIdentifier=keyid,issuer:always basicConstraints=CA:FALSE keyUsage=keyEncipherment,dataEncipherment extendedKeyUsage=serverAuth,clientAuth subjectAltName=@alt_names
-
Générez la demande de signature de certificat basée sur le fichier de configuration:
openssl req -new -key server.key -out server.csr -config csr.conf
-
Générez le certificat de serveur en utilisant ca.key, ca.crt et server.csr:
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \ -CAcreateserial -out server.crt -days 10000 \ -extensions v3_ext -extfile csr.conf
-
Vérifiez le certificat:
openssl x509 -noout -text -in ./server.crt
Enfin, ajoutez les mêmes paramètres aux paramètres de démarrage de l'API Server.
cfssl
cfssl est un autre outil pour la génération de certificat.
-
Téléchargez, décompressez et préparez les outils de ligne de commande comme indiqué ci-dessous. Notez que vous devrez peut-être adapter les exemples de commandes en fonction du matériel, de l'architecture et de la version de cfssl que vous utilisez.
curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o cfssl chmod +x cfssl curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o cfssljson chmod +x cfssljson curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o cfssl-certinfo chmod +x cfssl-certinfo
-
Créez un répertoire pour contenir les artefacts et initialiser cfssl:
mkdir cert cd cert ../cfssl print-defaults config > config.json ../cfssl print-defaults csr > csr.json
-
Créez un fichier JSON pour générer le fichier d'autorité de certification, par exemple,
ca-config.json
:{ "signing": { "default": { "expiry": "8760h" }, "profiles": { "kubernetes": { "usages": [ "signing", "key encipherment", "server auth", "client auth" ], "expiry": "8760h" } } } }
-
Créez un fichier JSON pour la demande de signature de certificat de l'autorité de certification, par exemple,
ca-csr.json
. Assurez-vous de remplacer les valeurs marquées par des "< >" par les vraies valeurs que vous voulez utiliser.{ "CN": "kubernetes", "key": { "algo": "rsa", "size": 2048 }, "names":[{ "C": "<country>", "ST": "<state>", "L": "<city>", "O": "<organization>", "OU": "<organization unit>" }] }
-
Générez la clé de CA (
ca-key.pem
) et le certificat (ca.pem
):../cfssl gencert -initca ca-csr.json | ../cfssljson -bare ca
-
Créer un fichier JSON pour générer des clés et des certificats pour l'API Server, par exemple,
server-csr.json
. Assurez-vous de remplacer les valeurs entre "< >" par les vraies valeurs que vous voulez utiliser.MASTER_CLUSTER_IP
est le service Cluster IP de l'API Server, comme décrit dans la sous-section précédente. L’exemple ci-dessous suppose également que vous utilisezcluster.local
par défaut comme nom de domaine DNS.{ "CN": "kubernetes", "hosts": [ "127.0.0.1", "<MASTER_IP>", "<MASTER_CLUSTER_IP>", "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster", "kubernetes.default.svc.cluster.local" ], "key": { "algo": "rsa", "size": 2048 }, "names": [{ "C": "<country>", "ST": "<state>", "L": "<city>", "O": "<organization>", "OU": "<organization unit>" }] }
-
Générez la clé et le certificat pour l'API Server, qui sont par défaut sauvegardés respectivement dans les fichiers
server-key.pem
etserver.pem
:../cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \ --config=ca-config.json -profile=kubernetes \ server-csr.json | ../cfssljson -bare server
Distribuer un certificat auto-signé
Un client peut refuser de reconnaître un certificat auto-signé comme valide. Pour un déploiement hors production ou pour un déploiement exécuté derrière un pare-feu d'entreprise, vous pouvez distribuer un certificat auto-signé à tous les clients et actualiser la liste locale pour les certificats valides.
Sur chaque client, effectuez les opérations suivantes:
$ sudo cp ca.crt /usr/local/share/ca-certificates/kubernetes.crt
$ sudo update-ca-certificates
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....
done.
API pour les certificats
Vous pouvez utiliser l’API certificates.k8s.io
pour faire créer des
Certificats x509 à utiliser pour l'authentification, comme documenté
ici.
3.10.3 - Architecture de Journalisation d'évènements (logging)
La journalisation des évènements systèmes et d'applications peut aider à
comprendre ce qui se passe dans un cluster. Les journaux sont particulièrement
utiles pour débogguer les problèmes et surveiller l'activité du cluster. La
plupart des applications modernes ont un mécanisme de journalisation
d'évènements, et la plupart des environnements d'exécution de conteneurs ont été
conçus pour supporter la journalisation des évènements. La méthode de
journalisation la plus facile et la plus répandue pour des applications
conteneurisées est d'écrire dans les flux de sortie standard et d'erreur
(stdout
et stderr
).
Malgré cela, la fonctionnalité de journalisation fournie nativement par l'environnement d'exécution de conteneurs n'est pas suffisante comme solution complète de journalisation. Quand un conteneur crashe, quand un Pod est expulsé ou quand un nœud disparaît, il est utile de pouvoir accéder au journal d'événements de l'application. C'est pourquoi les journaux doivent avoir leur propre espace de stockage et un cycle de vie indépendamment des nœuds, Pods ou conteneurs. Ce concept est appelé journalisation des évènements au niveau du cluster (cluster-level-logging). Un backend dédié pour stocker, analyser et faire des requêtes est alors nécessaire. Kubernetes n'offre pas nativement de solution de stockage pour les journaux mais il est possible d'intégrer de nombreuses solutions de journalisation d'évènements dans un cluster Kubernetes.
L'architecture de journalisation des évènements au niveau du cluster est décrite en considérant qu'un backend de journalisation est présent à l'intérieur ou à l'extérieur du cluster. Même sans avoir l'intention de journaliser les évènements au niveau du cluster, il est intéressant de savoir comment les journaux sont conservés et gérés au niveau d'un nœud.
Journalisation simple d'évènements dans Kubernetes
Dans cette section, on va utiliser un exemple simple de journalisation d'évènements avec le flux de sortie standard. Cette démonstration utilise un manifeste pour un Pod avec un seul conteneur qui écrit du texte sur le flux de sortie standard toutes les secondes.
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args: [/bin/sh, -c,
'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']
Pour lancer ce Pod, utilisez la commande suivante :
kubectl apply -f https://k8s.io/examples/debug/counter-pod.yaml
Le résultat est :
pod/counter created
Pour récupérer les événements du conteneur d'un pod, utilisez la commande
kubectl logs
de la manière suivante :
kubectl logs counter
Le résultat est :
0: Mon Jan 1 00:00:00 UTC 2001
1: Mon Jan 1 00:00:01 UTC 2001
2: Mon Jan 1 00:00:02 UTC 2001
...
Utilisez kubectl logs
pour récupérer les évènements de l'instanciation
précédente d'un Pod en utilisant l'option --previous
quand par exemple le
conteneur a crashé.
Si le Pod a plusieurs conteneurs, il faut spécifier le nom du conteneur dont on
veut récupérer le journal d'évènement. Dans notre exemple le conteneur s'appelle
count
donc vous pouvez utiliser kubectl logs counter count
. Plus de détails
dans la [documentation de kubectl logs
] (/docs/reference/generated/kubectl/kubectl-commands#logs)
Journalisation d'évènements au niveau du nœud
Tout ce qu'une application conteneurisée écrit sur stdout
ou stderr
est pris
en compte et redirigé par l'environnement d'exécution des conteneurs. Par exemple,
Docker redirige ces deux flux vers un driver de journalisation
(EN) qui est
configuré dans Kubernetes pour écrire dans un fichier au format json.
Par défaut quand un conteneur redémarre, le kubelet ne conserve le journal que du dernier conteneur terminé. Quand un Pod est expulsé d'un nœud, tous ses conteneurs sont aussi expulsés avec leurs journaux d'évènements.
Quand on utilise la journalisation d'évènements au niveau du nœud, il faut prendre garde à mettre en place une politique de rotation des journaux adéquate afin qu'ils n'utilisent pas tout l'espace de stockage du nœud. Kubernetes n'a pas en charge la rotation des journaux, c'est à l'outil de déploiement de le prendre en compte.
Par exemple, dans les clusters Kubernetes déployés avec le script kube-up.sh
logrotate
est configuré pour
s'exécuter toutes les heures. Il est aussi possible de configurer
l'environnement d'exécution des conteneurs pour que la rotation des journaux
s'exécute automatiquement, e.g. en utilisant le paramètre log-opt
de Docker.
Dans le script kube-up.sh
, c'est cette méthode qui est utilisée pour des
images COS sur GCP et sinon c'est la première méthode dans tous les autres cas.
Quelle que soit la méthode choisie par kube-up.sh
la rotation est configurée par
défaut quand la taille d'un journal atteint 10 Mo.
Ce script montre de manière détaillée comment kube-up.sh
met en place la journalisation d'évènements pour des images COS sur GCP.
Quand kubectl logs
s'exécute comme dans le premier exemple de journalisation simple le kubelet du
nœud gère la requête et lit directement depuis le fichier de journal et retourne
son contenu dans la réponse.
kubectl logs
. Par
exemple quand le journal atteint 10 Mo, logrotate
effectue une rotation, il y a
alors 2 fichers, un de 10 Mo et un de vide, à ce moment là kubectl logs
retournera une réponse vide.
Journalisation des évènements des composants système
Il y a deux types de composants système selon qu'ils s'exécutent dans un conteneur ou pas.
Par exemple :
- Le scheduler Kubernetes et kube-proxy s'exécutent dans un conteneur.
- Kubelet et l'environnement d'exécution de conteneurs, comme par exemple Docker, ne s'exécutent pas dans un conteneur.
Sur les systèmes avec systemd, kubelet et l'environnement d'exécution de
conteneurs écrivent dans journald. Si systemd n'est pas présent, ils écrivent
dans un fichier .log
dans le répertoire /var/log
.
Les composants système qui s'exécutent dans un conteneur écrivent toujours dans
le répertoire /var/log
, en contournant le mécanisme de journalisation par
défaut. Ils utilisent la bibliothèque de journalisation klog. Les
conventions pour la sévérité des évènements pour ces composants se trouvent dans
cette [documentation sur les conventions de journalisation des évènements dans
kubernetes]
(https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md).
De la même manière que les journaux des conteneurs, les journaux des composants
systèmes doivent avoir une politique de rotation. Dans un cluster créé avec
le script kube-up.sh
, les journaux ont une rotation journalière ou quand leur
taille atteint 100 Mo.
Architecture de journalisation des évènements au niveau du cluster
Kubernetes ne fournit pas de solution native pour la journalisation des évènements au niveau du cluster. Mais il y a différentes approches qui peuvent être considérées :
- Utiliser un agent de journalisation au niveau du nœud sur chacun des nœuds.
- Inclure un conteneur side-car pour journaliser les évènements du Pod applicatif.
- Envoyer les évènements directement a un backend depuis l'application.
Utiliser un agent de journalisation au niveau du nœud
Vous pouvez implémenter une journalisation au niveau du cluster en incluant un agent de journalisation au niveau du nœud sur chacun des nœuds. L'agent de journalisation est un outil dédié qui met à disposition ou envoie les journaux à un backend. Communément l'agent de journalisation est un conteneur qui a accès au répertoire qui contient les journaux des conteneurs applicatifs sur ce nœud.
Comme l'agent de journalisation doit s'exécuter sur chacun des nœuds, on utilise soit un DaemonSet, soit un manifeste de Pod, soit un processus dédié natif sur le nœud. Ces deux dernières options sont obsolètes et fortement découragées.
Utiliser un agent de journalisation au niveau du nœud est l'approche la plus commune et recommandée pour un cluster Kubernetes parce qu'un seul agent par nœud est créé et qu'aucune modification dans l'application n'est nécessaire. Mais cette approche ne fonctionne correctement que pour les flux standards de sortie et d'erreurs des applications.
Kubernetes ne définit pas d'agent de journalisation, mais deux agents de journalisation optionnels sont fournis avec la version de Kubernetes : Stackdriver (EN) pour utiliser sur Google Cloud Platform, et Elasticsearch (EN). Les deux utilisent fluentd avec une configuration spécifique comme agent sur le nœud. Les liens précédents fournissent plus d'informations et les instructions pour les utiliser et configurer.
Inclure un conteneur side-car pour journaliser les évènements du Pod applicatif
Vous pouvez utiliser un conteneur side-car d'une des manières suivantes :
- Le conteneur side-car diffuse les journaux de l'application sur son propre
stdout
. - Le conteneur side-car exécute un agent de journalisation qui est configuré pour récupérer les journaux du conteneur applicatif.
Conteneur side-car diffusant (Streaming sidecar container)
Comme le conteneur side-car diffuse les journaux sur ses propres flux stdout
et stderr
, on peut bénéficier du kubelet et de l'agent de journalisation qui
s'exécute déjà sur chaque nœud. Les conteneurs side-car lisent les journaux
depuis un fichier, un socket ou bien journald. Chaque conteneur side-car écrit
son journal sur son propre flux stdout
ou stderr
.
Cette méthode permet de séparer les flux de journaux de différentes
parties de votre application même si elles ne supportent pas d'écrire sur
stdout
ou stderr
. La logique de rediriger les journaux est minime et
le surcoût est non significatif. De plus comme les flux standards stdout
et
stderr
sont gérés par kubelet, les outils natifs comme kubectl logs
peuvent
être utilisés.
Regardez l'exemple qui suit.
Un Pod exécute un unique conteneur et ce conteneur écrit dans deux fichiers de journaux différents en utilisant deux format différents. Voici le manifeste du Pod :
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
emptyDir: {}
Il serait très désordonné d'avoir des évènements avec des formats différents
dans le même journal en redirigeant les évènements dans le flux de sortie
stdout
d'un seul conteneur. Il est plutôt souhaitable d'utiliser deux
conteneurs side-car, un pour chaque type de journaux. Chaque conteneur side-car
suit un des fichiers et renvoie les évènements sur son propre stdout
.
Ci-dessous se trouve le manifeste pour un Pod avec deux conteneurs side-car.
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-log-1
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/1.log']
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-log-2
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/2.log']
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
emptyDir: {}
Quand ce Pod s'exécute, chaque journal peut être diffusé séparément en utilisant les commandes suivantes :
kubectl logs counter count-log-1
0: Mon Jan 1 00:00:00 UTC 2001
1: Mon Jan 1 00:00:01 UTC 2001
2: Mon Jan 1 00:00:02 UTC 2001
...
kubectl logs counter count-log-2
Mon Jan 1 00:00:00 UTC 2001 INFO 0
Mon Jan 1 00:00:01 UTC 2001 INFO 1
Mon Jan 1 00:00:02 UTC 2001 INFO 2
...
L'agent au niveau du nœud installé dans le cluster récupère les deux flux de journaux sans aucune configuration supplémentaire. Il est possible de configurer l'agent pour qu'il analyse syntaxiquement les évènements en fonction du conteneur source.
Notez que bien que la consommation en CPU et mémoire soit faible ( de l'ordre de
quelques milicores pour la CPU et quelques mégaoctets pour la mémoire), ecrire
les évènements dans un fichier et les envoyer ensuite dans stdout
peut doubler
l'espace disque utilisé. Quand une application écrit dans un seul fichier de
journal, il est préférable de configurer /dev/stdout
comme destination plutôt
que d'implémenter un conteneur side-car diffusant.
Les conteneurs side-car peuvent être utilisés pour faire la rotation des
journaux quand l'application n'en est pas capable elle-même. Un exemple serait
un petit conteneur side-car qui effectuerait cette rotation périodiquement.
Toutefois, il est recommandé d'utiliser stdout
et stderr
directement et de
laisser la rotation et les politiques de rétentions au kubelet.
Conteneur side-car avec un agent de journalisation
Quand un agent de journalisation au niveau du nœud n'est pas assez flexible pour votre utilisation, vous pouvez créer un conteneur side-car avec un agent de journalisation séparé que vous avez configuré spécialement pour qu'il s'exécute avec votre application.
kubectl
parce qu'ils ne sont plus gérés par
kubelet.
Comme exemple, vous pouvez utiliser Stackdriver où fluentd est l'agent de journalisation. Ci-dessous se trouvent deux configurations qui implémentent cette méthode.
Le premier fichier contient un ConfigMap pour configurer fluentd.
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-config
data:
fluentd.conf: |
<source>
type tail
format none
path /var/log/1.log
pos_file /var/log/1.log.pos
tag count.format1
</source>
<source>
type tail
format none
path /var/log/2.log
pos_file /var/log/2.log.pos
tag count.format2
</source>
<match **>
type google_cloud
</match>
Le second fichier est un manifeste pour un Pod avec un conteneur side-car qui exécute fluentd. Le Pod monte un volume où fluentd peut récupérer sa configuration.
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-agent
image: k8s.gcr.io/fluentd-gcp:1.30
env:
- name: FLUENTD_ARGS
value: -c /etc/fluentd-config/fluentd.conf
volumeMounts:
- name: varlog
mountPath: /var/log
- name: config-volume
mountPath: /etc/fluentd-config
volumes:
- name: varlog
emptyDir: {}
- name: config-volume
configMap:
name: fluentd-config
Apres quelques minutes, les évènements apparaîtront dans l'interface de Stackdriver.
Ce n'est qu'un exemple et vous pouvez remplacer fluentd par n'importe quel agent de journalisation qui lit depuis n'importe quelle source de votre application.
Envoyer les évènements directement depuis l'application.
Vous pouvez implémenter la journalisation au niveau cluster en mettant à disposition ou en envoyant les journaux directement depuis chaque application; Toutefois l'implémentation de ce mécanisme de journalisation est hors du cadre de Kubernetes.
3.11 - Extensions Kubernetes
3.11.1 - Extensions de l'API Kubernetes
3.11.2 - Extensions compute, stockage et réseau
4 - Solutions indépendantes
4.1 - Serveurs physiques
5 - Tâches
Cette section de la documentation de Kubernetes contient des pages qui montrent comment effectuer des tâches individuelles. Une page montre comment effectuer une seule chose, généralement en donnant une courte séquence d'étapes.
Interface web (Dashboard)
Déployer et accéder au dashboard web de votre cluster pour vous aider à le gérer et administrer un cluster Kubernetes.
Utilisation de la ligne de commande kubectl
Installez et configurez l’outil en ligne de commande kubectl
utilisé pour gérer directement les clusters Kubernetes.
Configuration des Pods et des Conteneurs
Effectuer des tâches de configuration courantes pour les pods et les conteneurs.
Exécution d'applications
Effectuez des tâches courantes de gestion des applications, telles que les mises à jour progressives, l'injection de données dans les pods et la mise à l'échelle automatique des pods.
Executez des jobs
Exécuter des jobs en utilisant un traitement parallèle
Accéder aux applications dans un cluster
Configuration du load balancing, du port forwarding, ou mise en place d'un firewall ou la configuration DNS pour accéder aux applications dans un cluster.
Monitoring, Logging, and Debugging
Mettre en place le monitoring et le logging pour diagnostiquer un cluster ou debugguer une application conteneurisée.
Accéder à l'API Kubernetes
Apprenez diverses méthodes pour accéder directement à l'API Kubernetes.
Utiliser TLS
Configurer votre application pour faire confiance à et utiliser le certificat racine de votre Certificate Authority (CA).
Administration d'un cluster
Apprenez les tâches courantes pour administrer un cluster.
Administration d'une fédération
Configurez les composants dans une fédération de cluster.
Gestion des applications avec état
Effectuez des taches communes pour gérer des applications avec état, notamment la mise à l'échelle, la suppression et le debugging des objets StatefulSets.
Gestion des démons cluster
Effectuez des tâches courantes pour gérer un DaemonSet, telles que la mise à jour progressive.
Gestion des GPU
Configurer des GPUs NVIDIA pour les utiliser dans des noeuds dans un cluster.
Gestion des HugePages
Configuration des huge pages comme une ressource planifiable dans un cluster.
A suivre
Si vous souhaitez écrire une page, consultez Création d'une PullRequest de documentation.
5.1 - Outils d'installation
5.1.1 - Installer et configurer kubectl
L'outil en ligne de commande de kubernetes, kubectl, vous permet d'exécuter des commandes dans les clusters Kubernetes. Vous pouvez utiliser kubectl pour déployer des applications, inspecter et gérer les ressources du cluster et consulter les logs. Pour une liste complète des opérations kubectl, voir Aperçu de kubectl.
Pré-requis
Vous devez utiliser une version de kubectl qui différe seulement d'une version mineure de la version de votre cluster. Par exemple, un client v1.2 doit fonctionner avec un master v1.1, v1.2 et v1.3. L'utilisation de la dernière version de kubectl permet d'éviter des problèmes imprévus.
Installer kubectl sur Linux
Installer le binaire de kubectl avec curl sur Linux
-
Téléchargez la dernière release avec la commande :
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
Pour télécharger une version spécifique, remplacez
$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)
avec la version spécifique.Par exemple, pour télécharger la version v1.23.0 sur Linux, tapez :
curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.23.0/bin/linux/amd64/kubectl
-
Rendez le binaire kubectl exécutable.
chmod +x ./kubectl
-
Déplacez le binaire dans votre PATH.
sudo mv ./kubectl /usr/local/bin/kubectl
-
Testez pour vous assurer que la version que vous avez installée est à jour:
kubectl version --client
Installation à l'aide des gestionnaires des paquets natifs
sudo apt-get update && sudo apt-get install -y apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubectl
sudo cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
sudo yum install -y kubectl
Installation avec des gestionnaires de paquets alternatifs
Si vous êtes sur Ubuntu ou une autre distribution Linux qui supporte le gestionnaire de paquets snap, kubectl est disponible comme application snap.
snap install kubectl --classic
kubectl version --client
Si vous êtes sur Linux et que vous utiliser Homebrew comme gestionnaire de paquets, kubectl est disponible. installation
brew install kubectl
kubectl version --client
Installer kubectl sur macOS
Installer le binaire kubectl avec curl sur macOS
-
Téléchargez la dernière version:
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl
Pour télécharger une version spécifique, remplacez
$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)
avec la version spécifique.Par exemple, pour télécharger la version v1.23.0 sur macOS, tapez :
curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.23.0/bin/darwin/amd64/kubectl
-
Rendez le binaire kubectl exécutable.
chmod +x ./kubectl
-
Déplacez le binaire dans votre PATH.
sudo mv ./kubectl /usr/local/bin/kubectl
-
Testez pour vous assurer que la version que vous avez installée est à jour:
kubectl version --client
Installer avec Homebrew sur macOS
Si vous êtes sur MacOS et que vous utilisez le gestionnaire de paquets Homebrew, vous pouvez installer kubectl avec Homebrew.
-
Exécutez la commande d'installation:
brew install kubectl
ou
brew install kubernetes-cli
-
Testez pour vous assurer que la version que vous avez installée est à jour:
kubectl version --client
Installer avec Macports sur macOS
Si vous êtes sur MacOS et que vous utilisez le gestionnaire de paquets Macports, vous pouvez installer kubectl avec Macports.
-
Exécuter la commande d'installation:
sudo port selfupdate sudo port install kubectl
-
Testez pour vous assurer que la version que vous avez installée est à jour:
kubectl version --client
Installer kubectl sur Windows
Installer le binaire kubectl avec curl sur Windows
-
Téléchargez la dernière version v1.23.0 depuis ce lien.
Ou si vous avez
curl
installé, utilisez cette commande:curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.23.0/bin/windows/amd64/kubectl.exe
Pour connaître la dernière version stable (par exemple, en scripting), jetez un coup d'oeil à https://storage.googleapis.com/kubernetes-release/release/stable.txt.
-
Ajoutez le binaire dans votre PATH.
-
Testez pour vous assurer que la version que vous avez installée est à jour:
kubectl version --client
kubectl
au $PATH.
Si vous avez déjà installé Docker Desktop, vous devrez peut-être placer votre entrée PATH avant celle ajoutée par le programme d'installation de Docker Desktop ou supprimer le kubectl
de Docker Desktop.
Installer avec Powershell de PSGallery
Si vous êtes sous Windows et que vous utilisez le gestionnaire de paquets Powershell Gallery , vous pouvez installer et mettre à jour kubectl avec Powershell.
-
Exécutez les commandes d'installation (spécifier le
DownloadLocation
):Install-Script -Name install-kubectl -Scope CurrentUser -Force install-kubectl.ps1 [-DownloadLocation <path>]
Note: Si vous ne spécifiez pas unDownloadLocation
,kubectl
sera installé dans le répertoire temp de l'utilisateur.Le programme d'installation creé
$HOME/.kube
qui est suivie par la création d'un fichier de configuration -
Testez pour vous assurer que la version que vous avez installée est à jour:
kubectl version --client
Note: La mise à jour de l'installation s'effectue en réexécutant les deux commandes listées à l'étape 1.
Installer sur Windows avec Chocolatey ou Scoop
Pour installer kubectl sur Windows, vous pouvez utiliser le gestionnaire de paquets Chocolatey ou l'installateur en ligne de commande Scoop.
choco install kubernetes-cli
scoop install kubectl
```
kubectl version --client
```
-
Accédez à votre répertoire personnel:
cd %USERPROFILE%
-
Créez le répertoire
.kube
:mkdir .kube
-
Allez dans le répertoire
.kube
que vous venez de créer:cd .kube
-
Configurez kubectl pour utiliser un remote cluster Kubernetes:
New-Item config -type file
Note: Editez le fichier de configuration avec un éditeur de texte de votre choix, tel que Notepad.
Télécharger en tant qu'élément du SDK Google Cloud
Vous pouvez installer kubectl en tant qu'élément du SDK Google Cloud.
-
Installer Google Cloud SDK.
-
Exécutez la commande d'installation
kubectl
:gcloud components install kubectl
-
Testez pour vous assurer que la version que vous avez installée est à jour:
kubectl version --client
Vérification de la configuration de kubectl
Pour permettre à kubectl de trouver et d'accéder à un cluster Kubernetes, il lui faut un fichier kubeconfig, qui est créé automatiquement lorsque vous créez un cluster avec kube-up.sh ou en déployant un cluster Minikube avec succès. Par défaut, la configuration de kubectl est située sous ~/.kube/config
.
Vérifiez que kubectl est correctement configuré en obtenant l'état du cluster:
kubectl cluster-info
Si vous voyez une réponse avec une URL, kubectl est correctement configuré pour accéder à votre cluster.
Si vous voyez un message similaire à celui qui suit, kubectl n'est pas configuré correctement ou n'est pas capable de se connecter à un cluster Kubernetes.
The connection to the server <server-name:port> was refused - did you specify the right host or port?
Si par exemple, vous avez l'intention d'exécuter un cluster Kubernetes sur votre machine (localement), vous aurez besoin d'un outil comme Minikube pour être installé en premier et exécuter à nouveau les commandes décrites ci-dessus.
Si kubectl cluster-info retourne la réponse en url mais que vous ne pouvez pas accéder à votre cluster, vous pouvez vérifier s'il est configuré correctement, en utilisant:
kubectl cluster-info dump
Configurations kubectl optionnelles
Activation de l'auto-complétion de shell
kubectl fournit un support d'auto-complétion pour Bash et Zsh, ce qui peut vous éviter beaucoup de temps de saisie.
Vous trouverez ci-dessous les étapes à suivre pour configurer l'auto-complétion pour Bash (y compris la différence entre Linux et MacOS) et Zsh.
Introduction
Le script de complétion kubectl pour Bash peut être généré avec la commande kubectl completion bash
. Sourcer le script de completion dans votre shell permet l'auto-complétion de kubectl.
En revanche, le script de complétion dépend de bash-completion, ce qui implique que vous devez d'abord installer ce logiciel (vous pouvez tester si vous avez déjà installé bash-completion en utilisant type _init_completion
).
Installer bash-completion
bash-completion est fourni par plusieurs gestionnaires de paquets (voir ici). Vous pouvez l'installer avec apt-get install bash-completion
or yum install bash-completion
, etc.
Les commandes ci-dessus créent /usr/share/bash-completion/bash_completion
, qui est le script principal de bash-completion. En fonction de votre gestionnaire de paquets, vous devez manuellement sourcer ce fichier dans votre ~/.bashrc
.
Il vous suffit de recharger votre shell et de lancer type _init_completion
. Si la commande réussit, vous êtes déjà configuré, sinon ajoutez le suivant à votre fichier `~/.bashrc' :
source /usr/share/bash-completion/bash_completion
Rechargez votre shell et vérifiez que bash-completion est correctement installé en tapant type _init_completion
.
Activer l'auto-complétion de kubectl
Vous devez maintenant vérifier que le script de completion de kubectl est bien sourcé dans toutes vos sessions shell. Il y a deux façons de le faire:
-
Sourcer le script de completion dans votre fichier
~/.bashrc
:echo 'source <(kubectl completion bash)' >>~/.bashrc
-
Ajoutez le script de complétion dans le répertoire
/etc/bash_completion.d
:kubectl completion bash >/etc/bash_completion.d/kubectl
-
Si vous avez un alias pour kubectl, vous pouvez étendre la completion de votre shell pour fonctionner avec cet alias:
echo 'alias k=kubectl' >>~/.bashrc echo 'complete -F __start_kubectl k' >>~/.bashrc
/etc/bash_completion.d
.
Les deux approches sont équivalentes. Après avoir rechargé votre shell, l'auto-complétion de kubectl devrait fonctionner.
Introduction
Le script de complétion kubectl pour Bash peut être généré avec la commande kubectl completion bash
. Sourcer le script de completion dans votre shell permet l'auto-complétion de kubectl.
En revanche, le script de complétion dépend de bash-completion, ce qui implique que vous devez d'abord installer ce logiciel.
Installer bash-completion
Vous pouvez tester si vous avez déjà installé bash-completion en utilisant type _init_completion
. Si il n'est pas installé, vous pouvez installer bash-completion avec Homebrew:
brew install bash-completion@2
Comme indiqué dans la sortie de brew install
(section "Caveats"), ajoutez les lignes suivantes à votre fichier ~/.bashrc
ou ~/.bash_profile
:
export BASH_COMPLETION_COMPAT_DIR="/usr/local/etc/bash_completion.d"
[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"
Rechargez votre shell et vérifiez que bash-completion v2 est correctement installé avec type _init_completion
.
Activer l'auto-complétion de kubectl
Si vous n'avez pas installé via Homebrew, vous devez maintenant vous assurer que le script de complétion kubectl est bien sourcé dans toutes vos sessions shell comme suit:
-
Sourcer le script de completion dans votre fichier
~/.bashrc
:echo 'source <(kubectl completion bash)' >>~/.bashrc
-
Ajoutez le script de complétion dans le répertoire
/usr/local/etc/bash_completion.d
:kubectl completion bash >/usr/local/etc/bash_completion.d/kubectl
-
Si vous avez un alias pour kubectl, vous pouvez étendre la completion de votre shell pour fonctionner avec cet alias:
echo 'alias k=kubectl' >>~/.bashrc echo 'complete -F __start_kubectl k' >>~/.bashrc
Si vous avez installé kubectl avec Homebrew (comme expliqué ici), alors le script de complétion a été automatiquement installé dans /usr/local/etc/bash_completion.d/kubectl
. Dans ce cas, vous n'avez rien à faire.
BASH_COMPLETION_COMPAT_DIR
, c'est pourquoi les deux dernières méthodes fonctionnent.
Après avoir rechargé votre shell, l'auto-complétion de kubectl devrait fonctionner.
Le script de complétion de kubectl pour Zsh peut être généré avec la commande kubectl completion zsh
. Sourcer le script de completion dans votre shell permet l'auto-complétion de kubectl.
Pour faire ainsi dans toutes vos sessions shell, ajoutez ce qui suit à votre fichier ~/.zshrc
:
source <(kubectl completion zsh)
Si vous avez un alias pour kubectl, vous pouvez étendre la completion de votre shell pour fonctionner avec cet alias:
echo 'alias k=kubectl' >>~/.zshrc
echo 'compdef __start_kubectl k' >>~/.zshrc
Après avoir rechargé votre shell, l'auto-complétion de kubectl devrait fonctionner.
Si vous rencontrez une erreur comme complete:13: command not found: compdef
, alors ajoutez ce qui suit au début de votre fichier ~/.zshrc
:
autoload -Uz compinit
compinit
A suivre
- Installer Minikube
- Voir les guides de démarrage pour plus d'informations sur la création de clusters.
- Apprenez comment lancer et exposer votre application
- Si vous avez besoin d'accéder à un cluster que vous n'avez pas créé, consultez Partager l'accès du Cluster.
- Consulter les documents de référence de kubectl
5.1.2 - Installer Minikube
Cette page vous montre comment installer Minikube, qui est un outil qui fait tourner un cluster Kubernetes à un noeud unique dans une machine virtuelle sur votre machine.
Pré-requis
Pour vérifier si la virtualisation est prise en charge sur Linux, exécutez la commande suivante et vérifiez que la sortie n'est pas vide :
grep -E --color 'vmx|svm' /proc/cpuinfo
Pour vérifier si la virtualisation est prise en charge sur macOS, exécutez la commande suivante sur votre terminal.
sysctl -a | grep -E --color 'machdep.cpu.features|VMX'
Si vous trouvez VMX
dans la sortie, la fonction VT-x est supportée sur votre OS.
Pour vérifier si la virtualisation est prise en charge sur Windows 8 et au-delà, exécutez la commande suivante sur votre terminal Windows ou à l'invite de commande.
systeminfo
Si vous obtenez la sortie suivant, la virtualisation est prise en charge sur Windows.
Hyper-V Requirements: VM Monitor Mode Extensions: Yes
Virtualization Enabled In Firmware: Yes
Second Level Address Translation: Yes
Data Execution Prevention Available: Yes
Si vous voyez la sortie suivante, votre système a déjà un hyperviseur installé et vous pouvez ignorer l'étape suivante.
Configuration requise pour Hyper-V: un hyperviseur a été détecté. Les fonctionnalités requises pour Hyper-V ne seront pas affichées.
Installer Minikube
Installer kubectl
Installez kubectl en suivant les instructions de la section Installer et configurer kubectl.
Installer un hyperviseur
Si vous n'avez pas déjà un hyperviseur installé, installez-le maintenant pour votre système d'exploitation :
• KVM, qui utilise également QEMU
Minikube supporte également une option --vm-driver=none
qui exécute les composants Kubernetes sur la machine hôte et pas dans une VM.
L'utilisation de ce pilote nécessite Docker et un environnement Linux mais pas un hyperviseur.
Si vous utilisez le pilote none
dans Debian ou un dérivé, utilisez les paquets .deb
pour
Docker plutôt que le package snap, qui ne fonctionne pas avec Minikube.
Vous pouvez télécharger les packages .deb
depuis Docker.
none
peut entraîner des problèmes de sécurité et de perte de données.
Avant d'utiliser --driver=none
, consultez cette documentation pour plus d'informations.
Minikube prend également en charge un vm-driver=podman
similaire au pilote Docker. Podman est exécuté en tant que superutilisateur (utilisateur root), c'est le meilleur moyen de garantir que vos conteneurs ont un accès complet à toutes les fonctionnalités disponibles sur votre système.
podman
nécessite l’exécution des conteneurs en tant que root car les comptes d’utilisateurs normaux n’ont pas un accès complet à toutes les fonctionnalités du système d’exploitation que leurs conteneurs pourraient avoir besoin d’exécuter.
Installer Minikube à l'aide d'un package
Il existe des packages * expérimentaux * pour Minikube; vous pouvez trouver des packages Linux (AMD64) depuis la page releases de Minikube sur GitHub.
Utilisez l'outil de package de votre distribution Linux pour installer un package approprié.
Installez Minikube par téléchargement direct
Si vous n'installez pas via un package, vous pouvez télécharger un binaire autonome et l'utiliser.
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 \
&& chmod +x minikube
Voici un moyen simple d'ajouter l'exécutable Minikube à votre path :
sudo mkdir -p /usr/local/bin/
sudo install minikube /usr/local/bin/
Installer Minikube en utilisant Homebrew
Une autre alternative, vous pouvez installer Minikube en utilisant Linux [Homebrew] (https://docs.brew.sh/Homebrew-on-Linux) :
brew install minikube
Installer kubectl
Installez kubectl en suivant les instructions de la section Installer et configurer kubectl.
Installer un hyperviseur
Si vous n'avez pas encore installé d'hyperviseur, installez-en un maintenant :
• HyperKit
Installer Minikube
La façon la plus simple d'installer Minikube sur macOS est d'utiliser Homebrew:
brew install minikube
Vous pouvez aussi l'installer sur macOS en téléchargeant un binaire statique :
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 \
&& chmod +x minikube
Voici une façon simple d'ajouter l'exécutable de Minikube à votre path :
sudo mv minikube /usr/local/bin
Installer kubectl
Installez kubectl en suivant les instructions de la section Installer et configurer kubectl.
Installer un hyperviseur
Si vous n'avez pas encore installé d'hyperviseur, installez-en un maintenant :
• Hyper-V
Installer Minikube en utilisant Chocolatey
La façon la plus simple d'installer Minikube sur Windows est d'utiliser Chocolatey (exécuté avec les droits administrateur) :
choco install minikube
Une fois l'installation de Minikube terminée, fermez la session CLI en cours et redémarrez. Minikube devrait avoir été ajouté à votre path automatiquement.
Installer Minikube avec Windows Installer
Pour installer manuellement Minikube sur Windows à l'aide de Windows Installer, téléchargez minikube-installer.exe
et exécutez l'Installer.
Installer Minikube manuellement
Pour installer Minikube manuellement sur Windows, téléchargez minikube-windows-amd64
, renommez-le en minikube.exe
, et ajoutez-le à votre path.
Confirmer l'installation
Pour confirmer la réussite de l'installation d'un hyperviseur et d'un mini-cube, vous pouvez exécuter la commande suivante pour démarrer un cluster Kubernetes local :
--driver
avec minikube start
, entrez le nom de l'hyperviseur que vous avez installé en minuscules où <driver_name>
est mentionné ci-dessous. Une liste complète des valeurs --driver
est disponible dans la documentation spécifiant le pilote VM.
minikube start --driver=<driver_name>
Une fois minikube start
terminé, exécutez la commande ci-dessous pour vérifier l'état du cluster :
minikube status
Si votre cluster est en cours d'exécution, la sortie de minikube status
devrait être similaire à :
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
Après avoir vérifié si Minikube fonctionne avec l'hyperviseur choisi, vous pouvez continuer à utiliser Minikube ou arrêter votre cluster. Pour arrêter votre cluster, exécutez :
minikube stop
Tout nettoyer pour recommencer à zéro
Si vous avez déjà installé minikube, exécutez :
minikube start
Si cette commande renvoie une erreur :
machine does not exist
Vous devez supprimer les fichiers de configuration :
rm -rf ~/.minikube
A suivre
5.2 - Administration d'un cluster
5.2.1 - Administration avec kubeadm
5.2.2 - Gestion de la mémoire du CPU et des ressources d'API
5.2.3 - Installation d'un fournisseur de politiques de réseau
5.2.4 - Développer un Cloud Controller Manager
Kubernetes v1.11 [beta]
Kubernetes 1.8 [alpha]
Avant d’expliquer comment créer votre propre gestionnaire de contrôleur de cloud, il est utile d’avoir quelques informations sur son fonctionnement interne.
Le cloud controller manager est un code de kube-controller-manager
utilisant des interfaces Go pour permettre la mise en œuvre d'implémentations depuis n'importe quel cloud.
La plupart des implémentations de contrôleurs génériques seront au cœur du projet, mais elles seront toujours exécutées sur les interfaces de cloud fournies, à condition que l'interface du fournisseur de cloud soit satisfaite.
Pour approfondir un peu les détails de la mise en œuvre, tous les gestionnaires de contrôleurs de nuage vont importer des packages à partir de Kubernetes core, la seule différence étant que chaque projet enregistre son propre fournisseur de nuage en appelant cloudprovider.RegisterCloudProvider où une variable globale des fournisseurs de cloud disponibles est mise à jour.
Développement
Out of Tree
Pour construire un out-of-tree cloud-controller-manager pour votre cloud, suivez ces étapes:
- Créez un package Go avec une implémentation satisfaisantcloudprovider.Interface.
- Utilisez main.go dans cloud-controller-manager de Kubernetes core en tant que modèle pour votre main.go. Comme mentionné ci-dessus, la seule différence devrait être le package cloud qui sera importé.
- Importez votre paquet cloud dans
main.go
, assurez-vous que votre paquet a un blocinit
à exécuter cloudprovider.RegisterCloudProvider.
Utiliser des exemples de fournisseurs de cloud out-of-tree peut être utile. Vous pouvez trouver la liste ici.
In Tree
Pour les cloud in-tree, vous pouvez exécuter le in-tree cloud controller manager comme un Daemonset dans votre cluster. Voir la documentation sur l'exécution d'un cloud controller manager pour plus de détails.
5.2.5 - Kubernetes cloud-controller-manager
Kubernetes v1.23 [beta]
Kubernetes v1.6 a introduit un nouveau binaire appelé cloud-controller-manager
.
cloud-controller-manager
est un démon qui intègre des boucles de contrôle spécifiques au cloud.
Ces boucles de contrôle spécifiques au cloud étaient à l’origine dans le binaire kube-controller-manager
.
Étant donné que les fournisseurs de cloud développent et publient à un rythme différent de celui du projet Kubernetes, fournir une abstraction du code du cloud-controller-manager
permet aux fournisseurs de cloud d’évoluer indépendamment du code Kubernetes principal.
Le cloud-controller-manager
peut être lié à tout fournisseur de cloud satisfaisant l'interface cloudprovider.Interface.
Pour des raisons de retro-compatibilité, le cloud-controller-manager fourni dans le projet de base Kubernetes utilise les mêmes bibliothèques que kube-controller-manager
.
Les fournisseurs de cloud déjà pris en charge nativement par Kubernetes devraient utiliser le cloud-controller-manager disponible dans le code de Kubernetes pour effectuer une transition visant à faire sortir cette prise en charge du code de Kubernetes.
Dans les futures versions de Kubernetes, tous les cloud-controller-manager seront développés en dehors du projet de base de Kubernetes géré par des sig leads ou des fournisseurs de cloud.
Administration
Pré-requis
Chaque cloud a ses propres exigences pour l'exécution de sa propre intégration, ces exigences sont similaires à celles requises pour l'exécution de kube-controller-manager
.
En règle générale, vous aurez besoin de:
- cloud authentification/autorisation: votre cloud peut nécessiter un jeton ou des règles IAM pour permettre l'accès à leurs API
- kubernetes authentification/autorisation: cloud-controller-manager peut avoir besoin de règles RBAC définies pour parler à l'apiserver kubernetes
- la haute disponibilité: Comme pour kube-controller-manager, vous pouvez souhaiter une configuration hautement disponible pour le cloud controller mananger en utilisant l'élection de leader (activée par défaut).
Lancer cloud-controller-manager
L'exécution réussie de cloud-controller-manager nécessite certaines modifications de la configuration de votre cluster.
kube-apiserver
etkube-controller-manager
NE DOIVENT PAS spécifier l'option--cloud-provider
. Cela garantit qu'il n'exécutera aucune boucle spécifique au cloud qui serait exécutée par le cloud-controller-manager. À l'avenir, cet indicateur sera rendu obsolète et supprimé.kubelet
doit s'exécuter avec--cloud-provider=external
. C’est pour nous assurer que le kubelet est conscient qu'il doit être initialisé par le cloud-controller-manager avant qu'il ne commence à travailler.
N'oubliez pas que la configuration de votre cluster pour utiliser le cloud-controller-manager changera le comportement de votre cluster de plusieurs façons:
- Les kubelets lancés avec
--cloud-provider=external
auront un marquagenode.cloudprovider.kubernetes.io/uninitialized
avec un effetNoSchedule
pendant l'initialisation. Cela indique que le nœud nécessite une seconde initialisation à partir d'un contrôleur externe avant de pouvoir planifier un travail. Notez que si le cloud-controller-manager n'est pas disponible, les nouveaux nœuds du cluster ne seront pas valides. Le marquage est important car le planificateur peut nécessiter des informations spécifiques au cloud à propos des nœuds, telles que leur région ou leur type (CPU performant, gpu, mémoire importante, instance ponctuelle, etc.). - Les informations relatives aux nœuds s'exécutant dans le cloud ne seront plus récupérées à l'aide de métadonnées locales, mais tous les appels d'API pour récupérer les informations de ces nœuds passeront par le cloud-controller-manager. Cela peut signifier que vous pouvez restreindre l'accès à votre API de cloud sur les kubelets pour une sécurité accrue. Pour les clusters de plus grande taille, vous voudrez peut-être déterminer si le cloud-controller-manager atteindra les limites de requêtes sur les API de votre fournisseur de cloud puisqu'il est désormais responsable de la quasi-totalité des appels d'API vers votre cloud depuis le cluster.
À partir de la version 1.8, le cloud-controller-manager peut implémenter:
- contrôleur de nœud - responsable de la mise à jour des nœud kubernetes à l’aide des API de cloud et de la suppression des nœud kubernetes supprimés sur votre cloud.
- contrôleur de service - responsable des loadbalancers sur votre cloud vers des services de type LoadBalancer.
- contrôleur de route - responsable de la configuration des routes réseau sur votre cloud
- toute autre fonctionnalité que vous voudriez implémenter si vous exécutez en dehors de l'arborescence de Kubernetes.
Exemples
Si vous utilisez un cloud actuellement pris en charge nativement dans Kubernetes et souhaitez adopter le cloud-controller-manager, reportez-vous à la section cloud-controller-manager dans kubernetes core.
Pour les cloud-controller-manager ne faisant pas partie de Kubernetes, vous pouvez trouver les projets respectifs dans des dépôts maintenus par des fournisseurs de cloud ou des sig leads.
Pour les fournisseurs qui se trouvent déjà dans Kubernetes, vous pouvez exécuter le cloud-controller-manager dans l'arborescence en tant que Daemonset dans votre cluster. Utilisez ce qui suit comme guide:
# Voici un exemple de configuration de cloud-controller-manager en tant que Daemonset dans votre cluster.
# Il suppose que vos masters peuvent executer des pods et ont le role node-role.kubernetes.io/master
# Notez que ce Daemonset ne fonctionnera pas directement pour votre cloud, c’est juste un exemple.
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: cloud-controller-manager
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: system:cloud-controller-manager
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: cloud-controller-manager
namespace: kube-system
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
k8s-app: cloud-controller-manager
name: cloud-controller-manager
namespace: kube-system
spec:
selector:
matchLabels:
k8s-app: cloud-controller-manager
template:
metadata:
labels:
k8s-app: cloud-controller-manager
spec:
serviceAccountName: cloud-controller-manager
containers:
- name: cloud-controller-manager
# pour les fournisseurs in-tree, nous utilisons k8s.gcr.io/cloud-controller-manager
# cela peut être remplacé par n'importe quelle autre image pour les fournisseurs out-of-tree
image: k8s.gcr.io/cloud-controller-manager:v1.8.0
command:
- /usr/local/bin/cloud-controller-manager
- --cloud-provider=<YOUR_CLOUD_PROVIDER> # Ajoutez votre propre fournisseur de cloud ici!
- --leader-elect=true
- --use-service-account-credentials
# ces drapeaux varient pour chaque fournisseur de cloud
- --allocate-node-cidrs=true
- --configure-cloud-routes=true
- --cluster-cidr=172.17.0.0/16
tolerations:
# cela est nécessaire pour que CCM puisse s'initialiser
- key: node.cloudprovider.kubernetes.io/uninitialized
value: "true"
effect: NoSchedule
# le daemonset doit pouvoir être exécuté sur les nœuds master. Le marquage peut varier en fonction de la configuration de votre cluster.
- key: node-role.kubernetes.io/master
effect: NoSchedule
# ceci limite le fonctionnement du CCM sur des nœuds master
# le sélecteur de nœud peut varier en fonction de la configuration de votre cluster
nodeSelector:
node-role.kubernetes.io/master: ""
Limitations
L'exécution du cloud-controller-manager est soumise à quelques limitations. Bien que ces limitations soient levées dans les prochaines versions, il est important que vous connaissiez ces limitations pour les charges de travail de production.
Prise en charge des volumes
Le cloud-controller-manager n'implémente aucun des contrôleurs de volume trouvés dans kube-controller-manager
car les intégrations de volume nécessitent également une coordination avec les kubelets.
Au fur et à mesure de l'évolution de CSI (interface de stockage de conteneur) et de la prise en charge renforcée des plug-ins de volume flexible, le cloud-controller-manager prendra en charge le support nécessaire afin que les clouds puissent pleinement s'intégrer aux volumes.
Pour en savoir plus sur les plug-ins de volume CSI en dehors des sources de Kubernetes consultez ceci.
Charge sur les APIs cloud
Dans l'architecture précédente pour les fournisseurs de cloud, nous utilisions des kubelets utilisant un service de métadonnées local pour extraire des informations sur les nœuds. Avec cette nouvelle architecture, nous comptons désormais entièrement sur les cloud-controller-manager pour extraire les informations de tous les nœuds. Pour les très grand clusters, vous devez envisager les goulots d'étranglement tels que les besoins en ressources et la limitation de la vitesse des APIs de votre fournisseur cloud.
Problème de l'oeuf et de la poule
L'objectif du projet des cloud-controller-manager est de dissocier le développement des fonctionnalités de cloud computing du projet de base Kubernetes. Malheureusement, de nombreux aspects du projet Kubernetes supposent que les fonctionnalités de fournisseur de cloud soient étroitement intégrées au projet. Par conséquent, l'adoption de cette nouvelle architecture peut créer plusieurs situations dans lesquelles une demande d'informations auprès d'un fournisseur de cloud est demandée, mais le cloud-controller-manager peut ne pas être en mesure de renvoyer ces informations sans que la demande d'origine soit complète.
La fonctionnalité d’amorçage TLS dans Kubelet en est un bon exemple. Actuellement, l’amorçage TLS suppose que Kubelet aie la possibilité de demander au fournisseur de cloud (ou à un service de métadonnées local) tous ses types d’adresses (privé, public, etc.), mais le cloud-controller-manager ne peut pas définir les types d’adresse d’un nœud sans être initialisé dans le système. Ce qui nécessite que le kubelet possède des certificats TLS pour communiquer avec l’apiserver.
À mesure que cette initiative évoluera, des modifications seront apportées pour résoudre ces problèmes dans les prochaines versions.
Développer votre propre cloud-controller-manager
Pour créer et développer votre propre cloud-controller-manager, lisez la documentation Développer un cloud-controller-manager.
5.3 - Configuration des Pods et des conteneurs
5.3.1 - Allouer des ressources mémoire aux conteneurs et aux pods
Cette page montre comment assigner une mémoire request et une mémoire limit à un conteneur. Un conteneur est garanti d'avoir autant de mémoire qu'il le demande, mais n'est pas autorisé à consommer plus de mémoire que sa limite.
Pré-requis
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:
Pour consulter la version, entrezkubectl version
.
Chaque nœud de votre cluster doit avoir au moins 300 MiB de mémoire.
Pour quelques étapes de cette page, vous devez lancer [metrics-server] (https://github.com/kubernetes-incubator/metrics-server) dans votre cluster. Si vous avez déjà metrics-server vous pouvez sauter ces étapes.
Si vous utilisez Minikube, exécutez la commande suivante pour activer metrics-server :
minikube addons enable metrics-server
Pour voir si le metrics-server fonctionne, ou un autre fournisseur de l'API des métriques de ressources (metrics.k8s.io
), exécutez la commande suivante :
kubectl get apiservices
Si l'API des métriques de ressources est disponible, la sortie inclura une référence à metrics.k8s.io
.
NAME
v1beta1.metrics.k8s.io
Créer un namespace
Créez un namespace de manière à ce que les ressources que vous créez dans cet exercice soient isolées du reste de votre cluster.
kubectl create namespace mem-example
Spécifier une demande de mémoire et une limite de mémoire
Pour spécifier une demande de mémoire pour un conteneur, incluez le champ resources:requests
.
dans le manifeste des ressources du conteneur. Pour spécifier une limite de mémoire, incluez resources:limits
.
Dans cet exercice, vous créez un pod qui possède un seul conteneur. Le conteneur dispose d'une demande de mémoire de 100 MiB et une limite de mémoire de 200 MiB. Voici le fichier de configuration pour le Pod :
apiVersion: v1
kind: Pod
metadata:
name: memory-demo
namespace: mem-example
spec:
containers:
- name: memory-demo-ctr
image: polinux/stress
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
La section args
de votre fichier de configuration fournit des arguments pour le conteneur lorsqu'il démarre.
Les arguments "--vm-bytes", "150M"
indiquent au conteneur d'allouer 150 MiB de mémoire.
Créez le Pod:
kubectl apply -f https://k8s.io/examples/pods/resource/memory-request-limit.yaml --namespace=mem-example
Vérifiez que le Pod fonctionne :
kubectl get pod memory-demo --namespace=mem-example
Consultez des informations détaillées sur le Pod :
kubectl get pod memory-demo --output=yaml --namespace=mem-example
La sortie montre que le conteneur dans le Pod a une demande de mémoire de 100 MiB et une limite de mémoire de 200 MiB.
...
resources:
limits:
memory: 200Mi
requests:
memory: 100Mi
...
Exécutez kubectl top
pour récupérer les métriques du pod :
kubectl top pod memory-demo --namespace=mem-example
La sortie montre que le Pod utilise environ 162.900.000 bytes de mémoire, qui est d'environ 150 MiB. Ce qui est supérieur à la demande de 100 MiB du Pod, mais ne dépassant pas la limite de 200 Mio de Pod.
NAME CPU(cores) MEMORY(bytes)
memory-demo <something> 162856960
Supprimez votre Pod :
kubectl delete pod memory-demo --namespace=mem-example
Dépasser la limite de mémoire d'un conteneur
Un conteneur peut dépasser sa demande de mémoire si le nœud dispose de la mémoire disponible. Cependant, un conteneur n'est pas autorisé à utiliser plus que sa limite de mémoire. Si un conteneur alloue plus de mémoire que sa limite, le Conteneur devient un candidat à la terminaison. Si le conteneur continue à consommer de la mémoire au-delà de sa limite, le conteneur est arrêté. Si un conteneur terminé peut être redémarré, le kubelet le redémarre, comme pour tout autre type d'échec d'exécution.
Dans cet exercice, vous créez un Pod qui tente d'allouer plus de mémoire que sa limite. Voici le fichier de configuration d'un Pod qui contient un conteneur avec une demande de mémoire de 50 MiB et une limite de mémoire de 100 MiB :
apiVersion: v1
kind: Pod
metadata:
name: memory-demo-2
namespace: mem-example
spec:
containers:
- name: memory-demo-2-ctr
image: polinux/stress
resources:
requests:
memory: "50Mi"
limits:
memory: "100Mi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "250M", "--vm-hang", "1"]
Dans la section args
du fichier de configuration, vous pouvez voir que le conteneur
tentera d'allouer 250 MiB de mémoire, ce qui est bien au-dessus de la limite de 100 MiB.
Créez le Pod :
kubectl apply -f https://k8s.io/examples/pods/resource/memory-request-limit-2.yaml --namespace=mem-example
Consultez des informations détaillées sur le Pod :
kubectl get pod memory-demo-2 --namespace=mem-example
A ce niveau, le conteneur est soit en train de tourner, soit stoppé. Répétez la commande précédente jusqu'à ce que le conteneur soit terminé :
NAME READY STATUS RESTARTS AGE
memory-demo-2 0/1 OOMKilled 1 24s
Obtenez une vue plus détaillée de l'état du conteneur :
kubectl get pod memory-demo-2 --output=yaml --namespace=mem-example
La sortie indique que le conteneur a été stoppé suite à un manque de mémoire (OOM) :
lastState:
terminated:
containerID: docker://65183c1877aaec2e8427bc95609cc52677a454b56fcb24340dbd22917c23b10f
exitCode: 137
finishedAt: 2017-06-20T20:52:19Z
reason: OOMKilled
startedAt: null
Le conteneur dans cet exercice pourra être redémarré, ainsi le kubelet le redémarre. Répéter cette commande plusieurs fois pour s'assurer que le conteneur est stoppé et redémarré d'une manière répététive :
kubectl get pod memory-demo-2 --namespace=mem-example
La sortie permet de voir que le conteneur est stoppé, redémarré, stoppé à nouveau, redémarré, et ainsi de suite :
kubectl get pod memory-demo-2 --namespace=mem-example
NAME READY STATUS RESTARTS AGE
memory-demo-2 0/1 OOMKilled 1 37s
kubectl get pod memory-demo-2 --namespace=mem-example
NAME READY STATUS RESTARTS AGE
memory-demo-2 1/1 Running 2 40s
Affichez des informations détaillées sur l'historique du Pod :
kubectl describe pod memory-demo-2 --namespace=mem-example
La sortie indique que le conteneur se démarre et échoue continuellement :
... Normal Created Created container with id 66a3a20aa7980e61be4922780bf9d24d1a1d8b7395c09861225b0eba1b1f8511
... Warning BackOff Back-off restarting failed container
Affichez des informations détaillées sur les nœuds de votre cluster :
kubectl describe nodes
La sortie inclut un enregistrement de la mise à mort du conteneur suite à une condition hors mémoire :
Warning OOMKilling Memory cgroup out of memory: Kill process 4481 (stress) score 1994 or sacrifice child
Supprimez votre Pod :
kubectl delete pod memory-demo-2 --namespace=mem-example
Spécifiez une demande de mémoire trop volumineuse pour vos nœuds.
Les demandes de mémoire et les limites sont associées aux conteneurs, mais il est utile de réfléchir avant tout à la capacité de demande et limite mémoire des pods. La demande de mémoire pour le Pod est la somme des demandes de mémoire pour tous ses conteneurs. De même, la mémoire limite pour le Pod est la somme des limites de tous ses Conteneurs.
L'ordonnancement des modules est basé sur les demandes. Un Pod est schedulé pour se lancer sur un Nœud uniquement si le Nœud dispose de suffisamment de mémoire disponible pour répondre à la demande de mémoire du Pod.
Dans cet exercice, vous allez créer un Pod dont la demande de mémoire est si importante qu'elle dépasse la capacité de la mémoire de n'importe quel nœud de votre cluster. Voici le fichier de configuration d'un Pod qui possède un seul conteneur avec une demande de 1000 GiB de mémoire, qui dépasse probablement la capacité de tous les nœuds de votre cluster.
apiVersion: v1
kind: Pod
metadata:
name: memory-demo-3
namespace: mem-example
spec:
containers:
- name: memory-demo-3-ctr
image: polinux/stress
resources:
limits:
memory: "1000Gi"
requests:
memory: "1000Gi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
Créez le Pod :
kubectl apply -f https://k8s.io/examples/pods/resource/memory-request-limit-3.yaml --namespace=mem-example
Affichez l'état du Pod :
kubectl get pod memory-demo-3 --namespace=mem-example
La sortie indique que l'état du Pod est PENDING. En d'autres termes, le Pod n'est pas programmé pour tourner sur aucun Nœud, et il restera indéfiniment dans l'état PENDING :
kubectl get pod memory-demo-3 --namespace=mem-example
NAME READY STATUS RESTARTS AGE
memory-demo-3 0/1 Pending 0 25s
Affichez des informations détaillées sur le Pod, y compris les événements :
kubectl describe pod memory-demo-3 --namespace=mem-example
La sortie indique que le conteneur ne peut pas être planifié par manque de mémoire sur les nœuds :
Events:
... Reason Message
------ -------
... FailedScheduling No nodes are available that match all of the following predicates:: Insufficient memory (3).
Unités de mémoire
La ressource mémoire est mesurée en bytes. Vous pouvez exprimer la mémoire sous la forme d'un nombre entier simple ou d'un nombre avec l'un de ces suffixes : E, P, T, G, M, K, Ei, Pi, Ti, Gi, Mi, Ki. Par exemple, les valeurs suivantes représentent approximativement la même valeur :
128974848, 129e6, 129M , 123Mi
Supprimez votre Pod :
kubectl delete pod memory-demo-3 --namespace=mem-example
Si vous ne spécifiez pas de limite de mémoire
Si vous ne spécifiez pas de limite de mémoire pour un conteneur, l'une des situations suivantes s'applique :
-
Le conteneur n'a pas de limite maximale quant à la quantité de mémoire qu'il utilise. Le conteneur pourrait utiliser toute la mémoire disponible sur le nœud où il est en cours d'exécution, ce qui pourrait à son tour invoquer le OOM killer. De plus, dans le cas d'un OOM Kill, un conteneur sans limite de ressources aura plus de chance d'être stoppé.
-
Le conteneur s'exécute dans un namespace qui a une limite de mémoire par défaut, d'ou le conteneur est automatiquement affecté cette limite par defaut. Les administrateurs du cluster peuvent utiliser un LimitRange pour spécifier une valeur par défaut pour la limite de mémoire.
Motivation pour les demandes et les limites de mémoire
En configurant les demandes de mémoire et les limites pour les conteneurs qui s'exécutent dans votre cluster. vous pouvez utiliser efficacement les ressources mémoire disponibles sur les noeuds de votre cluster. En gardant la demande de mémoire d'un Pod basse, vous donnez au Pod une bonne chance d'être schedulé. En ayant une limite de mémoire supérieure à la demande de mémoire, vous accomplissez deux choses :
- Le Pod peut avoir des éclats d'activités où il fait usage de la mémoire qui se trouve être disponible.
- La quantité de mémoire qu'un Pod peut utiliser pendant un éclat d'activité est limitée à une quantité raisonnable.
Clean up
Supprimez votre namespace. Ceci va supprimer tous les Pods que vous avez créés dans cet exercice :
kubectl delete namespace mem-example
A suivre
Pour les développeurs d'applications
Pour les administrateurs de cluster
-
Configuration des demandes et des limites de mémoire par défaut pour un Namespace
-
Configuration des demandes et des limites par défaut de CPU pour un Namespace
-
Configuration des contraintes de mémoire minimales et maximales pour un Namespace
-
Configuration des contraintes minimales et maximales du CPU pour un Namespace
-
Configuration des quotas de mémoire et de CPU pour un Namespace
5.3.2 - Allouer des ressources CPU aux conteneurs et aux pods
Cette page montre comment assigner une demande (request en anglais) de CPU et une limite de CPU à un conteneur. Un conteneur est garanti d'avoir autant de CPU qu'il le demande, mais n'est pas autorisé à utiliser plus de CPU que sa limite.
Pré-requis
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:
Pour consulter la version, entrezkubectl version
.
Chaque nœud de votre cluster doit avoir au moins 1 CPU.
Pour certaines des étapes de cette page, vous devez lancer metrics-server dans votre cluster. Si le serveur de métriques est déja lancé, vous pouvez sauter ces étapes.
Si vous utilisez minikube, exécutez la commande suivante pour activer metrics-server :
minikube addons enable metrics-server
Pour voir si metrics-server (ou un autre fournisseur de l'API des métriques de ressources metrics.k8s.io
) est lancé, tapez la commande suivante:
kubectl get apiservices
Si l'API de métriques de ressources est disponible, la sortie inclura une
référence à metrics.k8s.io
.
NAME
v1beta1.metrics.k8s.io
Créer un namespace
Créez un namespace de manière à ce que les ressources que vous créez dans cet exercice soient isolés du reste de votre cluster.
kubectl create namespace cpu-example
Spécifier une demande de CPU et une limite de CPU
Pour spécifier une demande de CPU pour un conteneur, incluez le champ resources:requests
.
dans le manifeste des ressources du conteneur. Pour spécifier une limite de CPU, incluez resources:limits
.
Dans cet exercice, vous allez créer un Pod qui a un seul conteneur. Le conteneur a une demande de 0.5 CPU et une limite de 1 CPU. Voici le fichier de configuration du Pod :
apiVersion: v1
kind: Pod
metadata:
name: cpu-demo
namespace: cpu-example
spec:
containers:
- name: cpu-demo-ctr
image: vish/stress
resources:
limits:
cpu: "1"
requests:
cpu: "0.5"
args:
- -cpus
- "2"
La section args
du fichier de configuration fournit des arguments pour le conteneur lorsqu'il démarre. L'argument -cpus "2"
demande au conteneur d'utiliser 2 CPUs.
Créez le Pod:
kubectl apply -f https://k8s.io/examples/pods/resource/cpu-request-limit.yaml --namespace=cpu-example
Vérifiez que le Pod fonctionne :
kubectl get pod cpu-demo --namespace=cpu-example
Consultez des informations détaillées sur le Pod :
kubectl get pod cpu-demo --output=yaml --namespace=cpu-example
La sortie indique que le conteneur dans le Pod a une demande CPU de 500 milliCPU. et une limite de CPU de 1 CPU.
resources:
limits:
cpu: "1"
requests:
cpu: 500m
Utilisez kubectl top
pour récupérer les métriques du pod :
kubectl top pod cpu-demo --namespace=cpu-example
La sortie montre que le Pod utilise 974 milliCPU, ce qui est légèrement inférieur à la limite de 1 CPU spécifiée dans le fichier de configuration du Pod.
NAME CPU(cores) MEMORY(bytes)
cpu-demo 974m <something>
Souvenez-vous qu'en réglant -cpu "2"
, vous avez configuré le conteneur pour faire en sorte qu'il utilise 2 CPU, mais que le conteneur ne peut utiliser qu'environ 1 CPU. L'utilisation du CPU du conteneur est entravée, car le conteneur tente d'utiliser plus de ressources CPU que sa limite.
Unités de CPU
La ressource CPU est mesurée en unités CPU. Un CPU, à Kubernetes, est équivalent à:
- 1 AWS vCPU
- 1 GCP Core
- 1 Azure vCore
- 1 Hyperthread sur un serveur physique avec un processeur Intel qui a de l'hyperthreading.
Les valeurs fractionnelles sont autorisées. Un conteneur qui demande 0,5 CPU est garanti deux fois moins CPU par rapport à un conteneur qui demande 1 CPU. Vous pouvez utiliser le suffixe m pour signifier milli. Par exemple 100m CPU, 100 milliCPU, et 0.1 CPU sont tous égaux. Une précision plus fine que 1m n'est pas autorisée.
Le CPU est toujours demandé en tant que quantité absolue, jamais en tant que quantité relative, 0.1 est la même quantité de CPU sur une machine single-core, dual-core ou 48-core.
Supprimez votre pod :
kubectl delete pod cpu-demo --namespace=cpu-example
Spécifier une demande de CPU trop élevée pour vos nœuds.
Les demandes et limites de CPU sont associées aux conteneurs, mais il est utile de réfléchir à la demande et à la limite de CPU d'un pod. La demande de CPU pour un Pod est la somme des demandes de CPU pour tous les conteneurs du Pod. De même, la limite de CPU pour les un Pod est la somme des limites de CPU pour tous les conteneurs du Pod.
L'ordonnancement des pods est basé sur les demandes. Un Pod est prévu pour se lancer sur un Nœud uniquement si le nœud dispose de suffisamment de ressources CPU pour satisfaire la demande de CPU du Pod.
Dans cet exercice, vous allez créer un Pod qui a une demande de CPU si importante qu'elle dépassera la capacité de n'importe quel nœud de votre cluster. Voici le fichier de configuration d'un Pod qui a un seul conteneur. Le conteneur nécessite 100 CPU, ce qui est susceptible de dépasser la capacité de tous les nœuds de votre cluster.
apiVersion: v1
kind: Pod
metadata:
name: cpu-demo-2
namespace: cpu-example
spec:
containers:
- name: cpu-demo-ctr-2
image: vish/stress
resources:
limits:
cpu: "100"
requests:
cpu: "100"
args:
- -cpus
- "2"
Créez le Pod :
kubectl apply -f https://k8s.io/examples/pods/resource/cpu-request-limit-2.yaml --namespace=cpu-example
Affichez l'état du Pod :
kubectl get pod cpu-demo-2 --namespace=cpu-example
La sortie montre que l'état du Pod est en attente. En d'autres termes, le Pod n'a pas été planifié pour tourner sur n'importe quel Nœud, et il restera à l'état PENDING indéfiniment :
kubectl get pod cpu-demo-2 --namespace=cpu-example
NAME READY STATUS RESTARTS AGE
cpu-demo-2 0/1 Pending 0 7m
Afficher des informations détaillées sur le Pod, y compris les événements:
kubectl describe pod cpu-demo-2 --namespace=cpu-example
la sortie signale que le conteneur ne peut pas être planifié en raison d'une quantité insuffisante de ressources de CPU sur les Nœuds :
Events:
Reason Message
------ -------
FailedScheduling No nodes are available that match all of the following predicates:: Insufficient cpu (3).
Supprimez votre Pod :
kubectl delete pod cpu-demo-2 --namespace=cpu-example
Si vous ne spécifiez pas de limite CPU
Si vous ne spécifiez pas de limite CPU pour un conteneur, une de ces situations s'applique :
-
Le conteneur n'a pas de limite maximale quant aux ressources CPU qu'il peut utiliser. Le conteneur pourrait utiliser toutes les ressources CPU disponibles sur le nœud où il est lancé.
-
Le conteneur est lancé dans un namespace qui a une limite par défaut de CPU, ainsi le conteneur reçoit automatiquement cette limite par défaut. Les administrateurs du cluster peuvent utiliser un LimitRange pour spécifier une valeur par défaut pour la limite de CPU.
Motivation pour les demandes et les limites du CPU
En configurant les demandes et les limites de CPU des conteneurs qui se lancent sur votre cluster, vous pouvez utiliser efficacement les ressources CPU disponibles sur les Nœuds de votre cluster. En gardant une demande faible de CPU de pod, vous donnez au Pod une bonne chance d'être ordonnancé. En ayant une limite CPU supérieure à la demande de CPU, vous accomplissez deux choses :
- Le Pod peut avoir des pics d'activité où il utilise les ressources CPU qui se sont déjà disponible.
- La quantité de ressources CPU qu'un Pod peut utiliser pendant une pic d'activité est limitée à une quantité raisonnable.
Nettoyage
Supprimez votre namespace :
kubectl delete namespace cpu-example
A suivre
Pour les développeurs d'applications
Pour les administrateurs de cluster
-
Configuration des demandes et des limites de mémoire par défaut pour un Namespace
-
Configuration des demandes et des limites par défaut de CPU pour un Namespace
-
Configuration des contraintes de mémoire minimales et maximales pour un Namespace
-
Configuration des contraintes minimales et maximales du CPU pour un Namespace
-
Configuration des quotas de mémoire et de CPU pour un Namespace
5.3.3 - Configurer la qualité de service pour les pods
Cette page montre comment configurer les Pods pour qu'ils soient affectés à des classes particulières de qualité de service (QoS). Kubernetes utilise des classes de QoS pour prendre des décisions concernant l'ordonnancement et les évictions des pods.
Pré-requis
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:
Pour consulter la version, entrezkubectl version
.
Les Classes de QoS
Quand Kubernetes crée un Pod, il affecte une de ces classes QoS au Pod :
- Guaranteed
- Burstable
- BestEffort
Créez un namespace
Créez un namespace de manière à ce que les ressources que vous créez dans cet exercice soient isolées du reste de votre cluster.
kubectl create namespace qos-example
Créez un Pod qui se fait attribuer une classe QoS de Guaranteed
Pour qu'un Pod reçoive une classe de QoS Guaranteed :
- Chaque conteneur du Pod doit avoir une limite de mémoire et une demande de mémoire, et elles doivent être les mêmes.
- Chaque conteneur dans le Pod doit avoir une limite CPU et une demande CPU, et ils doivent être les mêmes.
Ci-dessous le fichier de configuration d'un Pod qui a un seul conteneur. Le conteneur dispose d'une limite de mémoire et d'une demande de mémoire, tous deux égaux à 200 MiB. Le conteneur a également une limite CPU et une demande CPU, toutes deux égales à 700 milliCPU :
apiVersion: v1
kind: Pod
metadata:
name: qos-demo
namespace: qos-example
spec:
containers:
- name: qos-demo-ctr
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "700m"
requests:
memory: "200Mi"
cpu: "700m"
Créez le Pod :
kubectl apply -f https://k8s.io/examples/pods/qos/qos-pod.yaml --namespace=qos-example
Consultez des informations détaillées sur le Pod :
kubectl get pod qos-demo --namespace=qos-example --output=yaml
Le résultat indique que Kubernetes a donné au pod une classe de qualité de service de type Guaranteed. De plus, il affiche que la demande de mémoire du conteneur du pod correspond à sa limite de mémoire, et que la demande de CPU correspond à sa limite de CPU.
spec:
containers:
...
resources:
limits:
cpu: 700m
memory: 200Mi
requests:
cpu: 700m
memory: 200Mi
...
status:
qosClass: Guaranteed
Supprimez votre Pod :
kubectl delete pod qos-demo --namespace=qos-example
Créez un Pod qui se fait attribuer une classe QoS de type Burstable
Un Pod reçoit une classe QoS de Burstable si :
- Le Pod ne répond pas aux critères de la classe QoS Guaranteed.
- Au moins un conteneur dans le Pod dispose d'une demande de mémoire ou de CPU.
Voici le fichier de configuration d'un pod qui a un seul conteneur. Le conteneur a une limite de mémoire de 200 MiB et une demande de mémoire de 100 MiB.
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-2
namespace: qos-example
spec:
containers:
- name: qos-demo-2-ctr
image: nginx
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"
Créez le Pod :
kubectl apply -f https://k8s.io/examples/pods/qos/qos-pod-2.yaml --namespace=qos-example
Consultez des informations détaillées sur le Pod :
kubectl get pod qos-demo-2 --namespace=qos-example --output=yaml
La sortie montre que Kubernetes a accordé au pod une classe QoS de type Burstable.
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: qos-demo-2-ctr
resources:
limits:
memory: 200Mi
requests:
memory: 100Mi
...
status:
qosClass: Burstable
Supprimez votre Pod :
kubectl delete pod qos-demo-2 --namespace=qos-example
Créez un Pod qui se fait attribuer une classe QoS de type BestEffort
Pour qu'un pod puisse avoir la classe QoS de BestEffort, les conteneurs dans le pod ne doivent pas avoir des limites ou des demandes de mémoire ou de CPU.
Voici le fichier de configuration d'un Pod qui a un seul conteneur. Le conteneur n'a pas des limites ou des demandes de mémoire ou de CPU :
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-3
namespace: qos-example
spec:
containers:
- name: qos-demo-3-ctr
image: nginx
Créez le Pod :
kubectl apply -f https://k8s.io/examples/pods/qos/qos-pod-3.yaml --namespace=qos-example
Consultez des informations détaillées sur le Pod :
kubectl get pod qos-demo-3 --namespace=qos-example --output=yaml
Le résultat montre que Kubernetes a accordé au pod une classe QoS de BestEffort.
spec:
containers:
...
resources: {}
...
status:
qosClass: BestEffort
Supprimez votre Pod :
kubectl delete pod qos-demo-3 --namespace=qos-example
Créez un pod qui contient deux conteneurs
Voici le fichier de configuration d'un Pod qui a deux conteneurs. Un conteneur spécifie une demande de mémoire de 200 MiB. L'autre conteneur ne spécifie aucune demande ou limite.
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-4
namespace: qos-example
spec:
containers:
- name: qos-demo-4-ctr-1
image: nginx
resources:
requests:
memory: "200Mi"
- name: qos-demo-4-ctr-2
image: redis
Notez que le pod répond aux critères de la classe QoS Burstable. En d'autres termes, il ne répond pas aux exigences de la classe de qualité de service Guaranteed, et l'un de ses conteneurs dispose d'une demande de mémoire.
Créez le Pod :
kubectl apply -f https://k8s.io/examples/pods/qos/qos-pod-4.yaml --namespace=qos-example
Consultez des informations détaillées sur le Pod :
kubectl get pod qos-demo-4 --namespace=qos-example --output=yaml
Le résultat montre que Kubernetes a accordé au pod une classe QoS de Burstable:
spec:
containers:
...
name: qos-demo-4-ctr-1
resources:
requests:
memory: 200Mi
...
name: qos-demo-4-ctr-2
resources: {}
...
status:
qosClass: Burstable
Supprimez votre pod :
kubectl delete pod qos-demo-4 --namespace=qos-example
Nettoyage
Supprimez votre namespace.
kubectl delete namespace qos-example
A suivre
Pour les développeurs d'applications
Pour les administrateurs de cluster
-
Configuration des demandes et des limites de mémoire par défaut pour un Namespace
-
Configuration des demandes et des limites par défaut de CPU pour un Namespace
-
Configuration des contraintes de mémoire minimales et maximales pour un Namespace
-
Configuration des contraintes minimales et maximales du CPU pour un Namespace
-
Configuration des quotas de mémoire et de CPU pour un Namespace
5.3.4 - Affecter des ressources supplémentaires à un conteneur
Cette page montre comment affecter des ressources supplémentaires à un conteneur.
Kubernetes v1.23 [stable]
Pré-requis
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:
Pour consulter la version, entrezkubectl version
.
Avant de commencer cet exercice, procédez à l'exercice en Annoncer des ressources supplémentaires pour un nœud. Cela configurera l'un de vos nœuds pour qu'il annoncera une ressource dongle.
Affecter une ressource supplémentaire à un Pod
Pour demander une ressource supplémentaire, incluez le champ resources:requests
dans votre fichier de manifeste du conteneur. Les ressources supplémentaires sont entièrement qualifiées dans n'importe quel domaine à l'extérieur de *.kubernetes.io/
.
Les noms de ressources supplémentaires valides ont la forme example.com/foo
où example.com
est remplacé par le domaine de votre organisation et foo
est le nom descriptif de la ressource.
Voici le fichier de configuration d'un Pod qui a un seul conteneur :
apiVersion: v1
kind: Pod
metadata:
name: extended-resource-demo
spec:
containers:
- name: extended-resource-demo-ctr
image: nginx
resources:
requests:
example.com/dongle: 3
limits:
example.com/dongle: 3
Dans le fichier de configuration, vous pouvez constater que le conteneur demande 3 dongles.
Créez un pod :
kubectl apply -f https://k8s.io/examples/pods/resource/extended-resource-pod.yaml
Vérifiez que le Pod fonctionne :
kubectl get pod extended-resource-demo
Décrivez le Pod :
kubectl describe pod extended-resource-demo
La sortie affiche les demandes des dongles :
Limits:
example.com/dongle: 3
Requests:
example.com/dongle: 3
Tentative de création d'un deuxième Pod
Voici le fichier de configuration d'un Pod qui a un seul conteneur. Le conteneur demande deux dongles.
apiVersion: v1
kind: Pod
metadata:
name: extended-resource-demo-2
spec:
containers:
- name: extended-resource-demo-2-ctr
image: nginx
resources:
requests:
example.com/dongle: 2
limits:
example.com/dongle: 2
Kubernetes ne pourra pas satisfaire la demande de deux dongles, parce que le premier Pod a utilisé trois des quatre dongles disponibles.
Essayez de créer un Pod :
kubectl apply -f https://k8s.io/examples/pods/resource/extended-resource-pod-2.yaml
Décrivez le Pod :
kubectl describe pod extended-resource-demo-2
La sortie montre que le Pod ne peut pas être planifié, du fait qu'il n'y a pas de Nœud qui a 2 dongles disponibles :
Conditions:
Type Status
PodScheduled False
...
Events:
...
... Warning FailedScheduling pod (extended-resource-demo-2) failed to fit in any node
fit failure summary on nodes : Insufficient example.com/dongle (1)
Affichez l'état du Pod :
kubectl get pod extended-resource-demo-2
La sortie indique que le Pod a été créé, mais pas programmé pour tourner sur un Nœud. Il a le statut Pending :
NAME READY STATUS RESTARTS AGE
extended-resource-demo-2 0/1 Pending 0 6m
Nettoyage
Supprimez les Pods que vous avez créés dans cet exercice :
kubectl delete pod extended-resource-demo
kubectl delete pod extended-resource-demo-2
A suivre
Pour les développeurs d'applications
- Allocation des ressources mémoire aux conteneurs et pods
- Allocation des ressources CPU aux conteneurs et pods
Pour les administrateurs de cluster
5.3.5 - Configurer un pod en utilisant un volume pour le stockage
Cette page montre comment configurer un Pod pour utiliser un Volume pour le stockage.
Le système de fichiers d'un conteneur ne vit que tant que le conteneur vit. Ainsi, quand un conteneur se termine et redémarre, les modifications apportées au système de fichiers sont perdues. Pour un stockage plus consistant et indépendant du conteneur, vous pouvez utiliser un Volume. C'est particulièrement important pour les applications Stateful, telles que les key-value stores (comme par exemple Redis) et les bases de données.
Pré-requis
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:
Pour consulter la version, entrezkubectl version
.
Configurer un volume pour un Pod
Dans cet exercice, vous créez un pod qui contient un seul conteneur. Ce Pod a un Volume de type emptyDir qui dure toute la vie du Pod, même si le conteneur se termine et redémarre. Voici le fichier de configuration du Pod :
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
volumeMounts:
- name: redis-storage
mountPath: /data/redis
volumes:
- name: redis-storage
emptyDir: {}
-
Créez le Pod :
kubectl apply -f https://k8s.io/examples/pods/storage/redis.yaml
-
Vérifiez que le conteneur du pod est en cours d'exécution, puis surveillez les modifications apportées au pod :
kubectl get pod redis --watch
La sortie ressemble à ceci :
NAME READY STATUS RESTARTS AGE redis 1/1 Running 0 13s
-
Dans un autre terminal, accédez à la console shell du conteneur en cours d'exécution :
kubectl exec -it redis -- /bin/bash
-
Dans votre shell, allez dans
/data/redis
, puis créez un fichier :root@redis:/data# cd /data/redis/ root@redis:/data/redis# echo Hello > test-file
-
Dans votre shell, listez les processus en cours d'exécution :
root@redis:/data/redis# apt-get update root@redis:/data/redis# apt-get install procps root@redis:/data/redis# ps aux
La sortie ressemble à ceci :
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND redis 1 0.1 0.1 33308 3828 ? Ssl 00:46 0:00 redis-server *:6379 root 12 0.0 0.0 20228 3020 ? Ss 00:47 0:00 /bin/bash root 15 0.0 0.0 17500 2072 ? R+ 00:48 0:00 ps aux
-
Dans votre shell, arrêtez le processus Redis :
root@redis:/data/redis# kill <pid>
où
<pid>
est l'ID de processus Redis (PID). -
Dans votre terminal initial, surveillez les changements apportés au Pod de Redis. Éventuellement, vous verrez quelque chose comme ça :
NAME READY STATUS RESTARTS AGE redis 1/1 Running 0 13s redis 0/1 Completed 0 6m redis 1/1 Running 1 6m
A ce stade, le conteneur est terminé et redémarré. C'est dû au fait que le Pod de Redis a une
restartPolicy
fixé à Always
.
-
Accédez à la console shell du conteneur redémarré :
kubectl exec -it redis -- /bin/bash
-
Dans votre shell, allez dans
/data/redis
, et vérifiez quetest-file
est toujours là.root@redis:/data/redis# cd /data/redis/ root@redis:/data/redis# ls test-file
-
Supprimez le pod que vous avez créé pour cet exercice :
kubectl delete pod redis
A suivre
-
Voir Volume.
-
Voir Pod.
-
En plus du stockage sur disque local fourni par
emptyDir
, Kubernetes supporte de nombreuses solutions de stockage connectées au réseau, y compris PD sur GCE et EBS sur EC2, qui sont préférés pour les données critiques et qui s'occuperont des autres détails tels que le montage et le démontage sur les nœuds. Voir Volumes pour plus de détails.
5.3.6 - Configurer les comptes de service pour les pods
Un ServiceAccount (compte de service) fournit une identité pour les processus qui s'exécutent dans un Pod.
Ceci est une introduction aux comptes de service pour les utilisateurs. Voir aussi Guide de l'administrateur du cluster des comptes de service.
Lorsque vous (un humain) accédez au cluster (par exemple, en utilisant kubectl
), vous êtes
authentifié par l'apiserver en tant que compte d'utilisateur particulier (actuellement, il s'agit
généralement de l'utilisateur admin
, à moins que votre administrateur de cluster n'ait personnalisé votre cluster). Les processus dans les conteneurs dans les Pods peuvent également contacter l'apiserver. Dans ce cas, ils sont authentifiés en tant que compte de service particulier (par exemple, default
).
Pré-requis
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:
Pour consulter la version, entrezkubectl version
.
Utiliser le compte de service par défaut pour accéder au API server.
Si vous obtenez le raw json ou yaml pour un Pod que vous avez créé (par exemple, kubectl get pods/<podname> -o yaml
), vous pouvez voir que le champ spec.serviceAccountName
a été automatiquement assigné.
Vous pouvez accéder à l'API depuis l'intérieur d'un Pod en utilisant les identifiants de compte de service montés automatiquement, comme décrit dans Accès au cluster. Les permissions API du compte de service dépendent du plugin d'autorisation et de la politique en usage.
Dans la version 1.6+, vous pouvez choisir de ne pas utiliser le montage automatique des identifiants API pour un compte de service en définissant automountServiceAccountToken: false
sur le compte de service :
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-robot
automountServiceAccountToken: false
...
Dans la version 1.6+, vous pouvez également choisir de ne pas monter automatiquement les identifiants API pour un Pod particulier :
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
serviceAccountName: build-robot
automountServiceAccountToken: false
...
La spéc de Pod a prépondérance par rapport au compte de service si les deux spécifient la valeur automountServiceAccountToken
.
Utiliser plusieurs comptes de services.
Chaque Namespace possède une ressource ServiceAccount par défaut appelée default
.
Vous pouvez lister cette ressource et toutes les autres ressources de ServiceAccount dans le Namespace avec cette commande :
kubectl get serviceAccounts
La sortie est comme la suivante :
NAME SECRETS AGE
default 1 1d
Vous pouvez créer des objets ServiceAccount supplémentaires comme ceci :
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-robot
EOF
Si vous obtenez un dump complet de l'objet compte de service, par exemple :
kubectl get serviceaccounts/build-robot -o yaml
La sortie est comme la suivante :
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: 2015-06-16T00:12:59Z
name: build-robot
namespace: default
resourceVersion: "272500"
selfLink: /api/v1/namespaces/default/serviceaccounts/build-robot
uid: 721ab723-13bc-11e5-aec2-42010af0021e
secrets:
- name: build-robot-token-bvbk5
vous verrez alors qu'un token a été automatiquement créé et est référencé par le compte de service.
Vous pouvez utiliser des plugins d'autorisation pour définir les permissions sur les comptes de service.
Pour utiliser un compte de service autre que par défaut, il suffit de spécifier le spec.serviceAccountName
d'un Pod au nom du compte de service que vous souhaitez utiliser.
Le compte de service doit exister au moment de la création du Pod, sinon il sera rejeté.
Vous ne pouvez pas mettre à jour le compte de service d'un Pod déjà créé.
Vous pouvez supprimer le compte de service de cet exemple comme ceci :
kubectl delete serviceaccount/build-robot
Créez manuellement un API token de compte de service.
Supposons que nous ayons un compte de service existant nommé "build-robot" comme mentionné ci-dessus,et que nous allons créer un nouveau Secret manuellement.
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: build-robot-secret
annotations:
kubernetes.io/service-account.name: build-robot
type: kubernetes.io/service-account-token
EOF
Vous pouvez maintenant confirmer que le Secret nouvellement construit est rempli d'un API token pour le compte de service "build-robot".
Tous les tokens pour des comptes de service non-existants seront nettoyés par le contrôleur de token.
kubectl describe secrets/build-robot-secret
La sortie est comme la suivante :
Name: build-robot-secret
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account: name=build-robot
kubernetes.io/service-account: uid=da68f9c6-9d26-11e7-b84e-002dc52800da
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1338 bytes
namespace: 7 bytes
token: ...
token
est éludé ici.
Ajouter ImagePullSecrets à un compte de service
Tout d'abord, créez un imagePullSecret, comme décrit ici. Puis, vérifiez qu'il a été créé. Par exemple :
kubectl get secrets myregistrykey
La sortie est comme la suivante :
NAME TYPE DATA AGE
myregistrykey kubernetes.io/.dockerconfigjson 1 1d
Ensuite, modifiez le compte de service par défaut du Namespace pour utiliser ce Secret comme un imagePullSecret
.
kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}'
La version interactive nécessite un traitement manuel :
kubectl get serviceaccounts default -o yaml > ./sa.yaml
La sortie du fichier sa.yaml
est similaire à celle-ci :
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: 2015-08-07T22:02:39Z
name: default
namespace: default
resourceVersion: "243024"
selfLink: /api/v1/namespaces/default/serviceaccounts/default
uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6
secrets:
- name: default-token-uudge
En utilisant l'éditeur de votre choix (par exemple vi
), ouvrez le fichier sa.yaml
, supprimez la ligne avec la clé resourceVersion
, ajoutez les lignes avec imagePullSecrets:
et sauvegardez.
La sortie du fichier sa.yaml
est similaire à celle-ci :
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: 2015-08-07T22:02:39Z
name: default
namespace: default
selfLink: /api/v1/namespaces/default/serviceaccounts/default
uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6
secrets:
- name: default-token-uudge
imagePullSecrets:
- name: myregistrykey
Enfin, remplacez le compte de service par le nouveau fichier sa.yaml
mis à jour.
kubectl replace serviceaccount default -f ./sa.yaml
Maintenant, tous les nouveaux Pods créés dans le Namespace courant auront ceci ajouté à leurs spécifications :
spec:
imagePullSecrets:
- name: myregistrykey
Projection du volume des tokens de compte de service
Kubernetes v1.12 [beta]
Ce ServiceAccountTokenVolumeProjection est beta en 1.12 et activé en passant tous les paramètres suivants au serveur API :
--service-account-issuer
--service-account-signing-key-file
--service-account-api-audiences
Kubelet peut également projeter un token de compte de service dans un Pod. Vous pouvez spécifier les propriétés souhaitées du token, telles que l'audience et la durée de validité. Ces propriétés ne sont pas configurables sur le compte de service par défaut. Le token de compte de service devient également invalide par l'API lorsque le Pod ou le ServiceAccount est supprimé
Ce comportement est configuré sur un PodSpec utilisant un type de ProjectedVolume appelé ServiceAccountToken. Pour fournir un Pod avec un token avec une audience de "vault" et une durée de validité de deux heures, vous devriez configurer ce qui suit dans votre PodSpec :
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- mountPath: /var/run/secrets/tokens
name: vault-token
serviceAccountName: build-robot
volumes:
- name: vault-token
projected:
sources:
- serviceAccountToken:
path: vault-token
expirationSeconds: 7200
audience: vault
Créez le Pod
kubectl create -f https://k8s.io/examples/pods/pod-projected-svc-token.yaml
Kubelet demandera et stockera le token a la place du Pod, rendra le token disponible pour le Pod à un chemin d'accès configurable, et rafraîchissez le token à l'approche de son expiration. Kubelet fait tourner le token de manière proactive s'il est plus vieux que 80% de son TTL total, ou si le token est plus vieux que 24 heures.
L'application est responsable du rechargement du token lorsque celui ci est renouvelé. Un rechargement périodique (par ex. toutes les 5 minutes) est suffisant pour la plupart des cas d'utilisation.
5.3.7 - Récupération d'une image d'un registre privé
Cette page montre comment créer un Pod qui utilise un Secret pour récupérer une image d'un registre privé.
Pré-requis
-
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:
Pour consulter la version, entrezkubectl version
. -
Pour faire cet exercice, vous avez besoin d'un Docker ID et un mot de passe.
Connectez-vous à Docker
Sur votre ordinateur, vous devez vous authentifier à un registre afin de récupérer une image privée :
docker login
Une fois que c'est fait, entrez votre nom d'utilisateur et votre mot de passe Docker.
Le processus de connexion crée ou met à jour un fichier config.json
qui contient un token d'autorisation.
Consultez le fichier config.json
:
cat ~/.docker/config.json
La sortie comporte une section similaire à celle-ci :
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "c3R...zE2"
}
}
}
auth
mais une entrée credsStore
avec le nom du Store comme valeur.
Créez un Secret basé sur les identifiants existants du Docker
Le cluster Kubernetes utilise le type Secret de docker-registry
pour s'authentifier avec
un registre de conteneurs pour y récupérer une image privée.
Si vous avez déjà lancé docker login
, vous pouvez copier ces identifiants dans Kubernetes
kubectl create secret generic regcred \
--from-file=.dockerconfigjson=<path/to/.docker/config.json> \
--type=kubernetes.io/dockerconfigjson
Si vous avez besoin de plus de contrôle (par exemple, pour définir un Namespace ou un label sur le nouveau secret), vous pouvez alors personnaliser le secret avant de le stocker. Assurez-vous de :
- Attribuer la valeur
.dockerconfigjson
dans le nom de l'élément data - Encoder le fichier docker en base64 et colle cette chaîne, non interrompue, comme valeur du champ
data[".dockerconfigjson"]
. - Mettre
type
àkubernetes.io/dockerconfigjson
.
Exemple:
apiVersion: v1
kind: Secret
metadata:
name: myregistrykey
namespace: awesomeapps
data:
.dockerconfigjson: UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg==
type: kubernetes.io/dockerconfigjson
Si vous obtenez le message d'erreur error: no objects passed to create
, cela peut signifier que la chaîne encodée en base64 est invalide.
Si vous obtenez un message d'erreur comme Secret "myregistrykey" is invalid: data[.dockerconfigjson]: invalid value ...
, cela signifie que la chaîne encodée en base64 a été décodée avec succès, mais n'a pas pu être interprétée comme un fichier .docker/config.json
.
Créez un Secret en fournissant les identifiants sur la ligne de commande
Créez ce secret, en le nommant regcred
:
kubectl create secret docker-registry regcred --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>
où :
<your-registry-server>
est votre FQDN de registre de docker privé. (https://index.docker.io/v1/ for DockerHub)<your-name>
est votre nom d'utilisateur Docker.<your-pword>
est votre mot de passe Docker.<your-email>
est votre email Docker.
Vous avez réussi à définir vos identifiants Docker dans le cluster comme un secret appelé regcred
.
kubectl
.
Inspection du secret regcred
Pour comprendre le contenu du Secret regcred
que vous venez de créer, commencez par visualiser le Secret au format YAML :
kubectl get secret regcred --output=yaml
La sortie est similaire à celle-ci :
apiVersion: v1
kind: Secret
metadata:
...
name: regcred
...
data:
.dockerconfigjson: eyJodHRwczovL2luZGV4L ... J0QUl6RTIifX0=
type: kubernetes.io/dockerconfigjson
La valeur du champ .dockerconfigjson
est une représentation en base64 de vos identifiants Docker.
Pour comprendre ce que contient le champ .dockerconfigjson
, convertissez les données secrètes en un format lisible :
kubectl get secret regcred --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
La sortie est similaire à celle-ci :
{"auths":{"your.private.registry.example.com":{"username":"janedoe","password":"xxxxxxxxxxx","email":"[email protected]","auth":"c3R...zE2"}}}
Pour comprendre ce qui se cache dans le champ `auth', convertissez les données encodées en base64 dans un format lisible :
echo "c3R...zE2" | base64 --decode
La sortie en tant que nom d'utilisateur et mot de passe concaténés avec un :
, est similaire à ceci :
janedoe:xxxxxxxxxxx
Remarquez que les données secrètes contiennent le token d'autorisation similaire à votre fichier local ~/.docker/config.json
.
Vous avez réussi à définir vos identifiants de Docker comme un Secret appelé regcred
dans le cluster.
Créez un Pod qui utilise votre Secret
Voici un fichier de configuration pour un Pod qui a besoin d'accéder à vos identifiants Docker dans regcred
:
apiVersion: v1
kind: Pod
metadata:
name: private-reg
spec:
containers:
- name: private-reg-container
image: <your-private-image>
imagePullSecrets:
- name: regcred
Téléchargez le fichier ci-dessus :
wget -O my-private-reg-pod.yaml https://k8s.io/examples/pods/private-reg-pod.yaml
Dans le fichier my-private-reg-pod.yaml
, remplacez <your-private-image>
par le chemin d'accès à une image dans un registre privé tel que
your.private.registry.example.com/janedoe/jdoe-private:v1
Pour récupérer l'image du registre privé, Kubernetes a besoin des identifiants.
Le champ imagePullSecrets
dans le fichier de configuration spécifie que Kubernetes doit obtenir les informations d'identification d'un Secret nommé regcred
.
Créez un Pod qui utilise votre secret et vérifiez que le Pod est bien lancé :
kubectl apply -f my-private-reg-pod.yaml
kubectl get pod private-reg
A suivre
- Pour en savoir plus sur les Secrets.
- Pour en savoir plus sur l'utilisation d'un registre privé.
- Pour en savoir plus sur l'ajout d'un imagePullSecrets à un compte de service.
- Voir kubectl crée un Secret de registre de docker.
- Voir Secret.
- Voir le champ
imagePullSecrets
de PodSpec.
5.3.8 - Configurer les Liveness, Readiness et Startup Probes
Cette page montre comment configurer les liveness, readiness et startup probes pour les conteneurs.
Le Kubelet utilise les liveness probes pour détecter quand redémarrer un conteneur. Par exemple, les Liveness probes pourraient attraper un deadlock dans le cas où une application est en cours d'exécution, mais qui est incapable de traiter les requêtes. Le redémarrage d'un conteneur dans un tel état rend l'application plus disponible malgré les bugs.
Le Kubelet utilise readiness probes pour savoir quand un conteneur est prêt à accepter le trafic. Un Pod est considéré comme prêt lorsque tous ses conteneurs sont prêts. Ce signal sert notamment à contrôler les pods qui sont utilisés comme backends pour les Services. Lorsqu'un Pod n'est pas prêt, il est retiré des équilibreurs de charge des Services.
Le Kubelet utilise startup probes pour savoir quand une application d'un conteneur a démarré. Si une telle probe est configurée, elle désactive les contrôles de liveness et readiness jusqu'à cela réussit, en s'assurant que ces probes n'interfèrent pas avec le démarrage de l'application. Cela peut être utilisé dans le cas des liveness checks sur les conteneurs à démarrage lent, en les évitant de se faire tuer par le Kubelet avant qu'ils ne soient opérationnels.
Pré-requis
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:
Pour consulter la version, entrezkubectl version
.
Définir une commande de liveness
De nombreuses applications fonctionnant pour des longues périodes finissent par passer à des états de rupture et ne peuvent pas se rétablir, sauf en étant redémarrées. Kubernetes fournit des liveness probes pour détecter et remédier à ces situations.
Dans cet exercice, vous allez créer un Pod qui exécute un conteneur basé sur l'image k8s.gcr.io/busybox
. Voici le fichier de configuration pour le Pod :
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: k8s.gcr.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
Dans le fichier de configuration, vous constatez que le Pod a un seul conteneur.
Le champ periodSeconds
spécifie que le Kubelet doit effectuer un check de liveness toutes les 5 secondes. Le champ initialDelaySeconds
indique au Kubelet qu'il devrait attendre 5 secondes avant d'effectuer la première probe. Pour effectuer une probe, le Kubelet exécute la commande cat /tmp/healthy
dans le conteneur. Si la commande réussit, elle renvoie 0, et le Kubelet considère que le conteneur est vivant et en bonne santé. Si la commande renvoie une valeur non nulle, le Kubelet tue le conteneur et le redémarre.
Au démarrage, le conteneur exécute cette commande :
/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
Pour les 30 premières secondes de la vie du conteneur, il y a un fichier /tmp/healthy
.
Donc pendant les 30 premières secondes, la commande cat /tmp/healthy
renvoie un code de succès. Après 30 secondes, cat /tmp/healthy
renvoie un code d'échec.
Créez le Pod :
kubectl apply -f https://k8s.io/examples/pods/probe/exec-liveness.yaml
Dans les 30 secondes, visualisez les événements du Pod :
kubectl describe pod liveness-exec
La sortie indique qu'aucune liveness probe n'a encore échoué :
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
24s 24s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "k8s.gcr.io/busybox"
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "k8s.gcr.io/busybox"
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined]
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e
Après 35 secondes, visualisez à nouveau les événements du Pod :
kubectl describe pod liveness-exec
Au bas de la sortie, il y a des messages indiquant que les liveness probes ont échoué, et que les conteneurs ont été tués et recréés.
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
37s 37s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "k8s.gcr.io/busybox"
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "k8s.gcr.io/busybox"
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined]
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e
2s 2s 1 {kubelet worker0} spec.containers{liveness} Warning Unhealthy Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
Attendez encore 30 secondes et vérifiez que le conteneur a été redémarré :
kubectl get pod liveness-exec
La sortie montre que RESTARTS
a été incrémenté :
NAME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 1 1m
Définir une requête HTTP de liveness
Un autre type de liveness probe utilise une requête GET HTTP. Voici la configuration
d'un Pod qui fait fonctionner un conteneur basé sur l'image k8s.gcr.io/liveness
.
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness
image: k8s.gcr.io/liveness
args:
- /server
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
Dans le fichier de configuration, vous pouvez voir que le Pod a un seul conteneur.
Le champ periodSeconds
spécifie que le Kubelet doit effectuer une liveness probe toutes les 3 secondes. Le champ initialDelaySeconds
indique au Kubelet qu'il devrait attendre 3 secondes avant d'effectuer la première probe. Pour effectuer une probe, le Kubelet envoie une requête HTTP GET au serveur qui s'exécute dans le conteneur et écoute sur le port 8080. Si le handler du chemin /healthz
du serveur renvoie un code de succès, le Kubelet considère que le conteneur est vivant et en bonne santé. Si le handler renvoie un code d'erreur, le Kubelet tue le conteneur et le redémarre.
Tout code supérieur ou égal à 200 et inférieur à 400 indique un succès. Tout autre code indique un échec.
Vous pouvez voir le code source du serveur dans server.go.
Pendant les 10 premières secondes où le conteneur est en vie, le handler /healthz
renvoie un statut de 200. Après cela, le handler renvoie un statut de 500.
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
duration := time.Now().Sub(started)
if duration.Seconds() > 10 {
w.WriteHeader(500)
w.Write([]byte(fmt.Sprintf("erreur: %v", duration.Seconds())))
} else {
w.WriteHeader(200)
w.Write([]byte("ok"))
}
})
Le Kubelet commence à effectuer des contrôles de santé 3 secondes après le démarrage du conteneur. Ainsi, les premiers contrôles de santé seront réussis. Mais après 10 secondes, les contrôles de santé échoueront, et le Kubelet tuera et redémarrera le conteneur.
Pour essayer le HTTP liveness check, créez un Pod :
kubectl apply -f https://k8s.io/examples/pods/probe/http-liveness.yaml
Après 10 secondes, visualisez les événements du Pod pour vérifier que les liveness probes ont échoué et le conteneur a été redémarré :
kubectl describe pod liveness-http
Dans les versions antérieures à la v1.13 (y compris la v1.13), au cas où la variable d'environnement http_proxy
(ou HTTP_PROXY
) est définie sur le noeud où tourne un Pod, le HTTP liveness probe utilise ce proxy.
Dans les versions postérieures à la v1.13, les paramètres de la variable d'environnement du HTTP proxy local n'affectent pas le HTTP liveness probe.
Définir une TCP liveness probe
Un troisième type de liveness probe utilise un TCP Socket. Avec cette configuration, le Kubelet tentera d'ouvrir un socket vers votre conteneur sur le port spécifié. S'il arrive à établir une connexion, le conteneur est considéré comme étant en bonne santé, s'il n'y arrive pas, c'est un échec.
apiVersion: v1
kind: Pod
metadata:
name: goproxy
labels:
app: goproxy
spec:
containers:
- name: goproxy
image: k8s.gcr.io/goproxy:0.1
ports:
- containerPort: 8080
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
Comme vous le voyez, la configuration pour un check TCP est assez similaire à un check HTTP.
Cet exemple utilise à la fois des readiness et liveness probes. Le Kubelet transmettra la première readiness probe 5 secondes après le démarrage du conteneur. Il tentera de se connecter au conteneur goproxy
sur le port 8080. Si la probe réussit, le conteneur sera marqué comme prêt. Kubelet continuera à effectuer ce check tous les 10 secondes.
En plus de la readiness probe, cette configuration comprend une liveness probe.
Le Kubelet effectuera la première liveness probe 15 secondes après que le conteneur démarre. Tout comme la readiness probe, celle-ci tentera de se connecter au conteneur de goproxy
sur le port 8080. Si la liveness probe échoue, le conteneur sera redémarré.
Pour essayer la TCP liveness check, créez un Pod :
kubectl apply -f https://k8s.io/examples/pods/probe/tcp-liveness-readiness.yaml
Après 15 secondes, visualisez les événements de Pod pour vérifier les liveness probes :
kubectl describe pod goproxy
Utilisation d'un port nommé
Vous pouvez utiliser un ContainerPort nommé pour les HTTP or TCP liveness probes :
ports:
- name: liveness-port
containerPort: 8080
hostPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
Protéger les conteneurs à démarrage lent avec des startup probes
Parfois, vous devez faire face à des applications legacy qui peuvent nécessiter un temps de démarrage supplémentaire lors de leur première initialisation.
Dans de telles situations, il peut être compliqué de régler les paramètres de la liveness probe sans compromettant la réponse rapide aux blocages qui ont motivé une telle probe.
L'astuce est de configurer une startup probe avec la même commande, HTTP ou TCP check avec un failureThreshold * periodSeconds
assez long pour couvrir le pire des scénarios des temps de démarrage.
Ainsi, l'exemple précédent deviendrait :
ports:
- name: liveness-port
containerPort: 8080
hostPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 1
periodSeconds: 10
startupProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 30
periodSeconds: 10
Grâce à la startup probe, l'application aura un maximum de 5 minutes (30 * 10 = 300s) pour terminer son démarrage.
Une fois que la startup probe a réussi, la liveness probe prend le relais pour fournir une réponse rapide aux blocages de conteneurs.
Si la startup probe ne réussit jamais, le conteneur est tué après 300s puis soumis à la restartPolicy
(politique de redémarrage) du Pod.
Définir les readiness probes
Parfois, les applications sont temporairement incapables de servir le trafic. Par exemple, une application peut avoir besoin de charger des larges données ou des fichiers de configuration pendant le démarrage, ou elle peut dépendre de services externes après le démarrage. Dans ces cas, vous ne voulez pas tuer l'application, mais vous ne voulez pas non plus lui envoyer de requêtes. Kubernetes fournit des readiness probes pour détecter et atténuer ces situations. Un pod avec des conteneurs qui signale qu'elle n'est pas prête ne reçoit pas de trafic par les services de Kubernetes.
Readiness probes sont configurées de la même façon que les liveness probes. La seule différence est que vous utilisez le champ readinessProbe
au lieu du champ livenessProbe
.
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
La configuration des readiness probes HTTP et TCP reste également identique à celle des liveness probes.
Les readiness et liveness probes peuvent être utilisées en parallèle pour le même conteneur. L'utilisation des deux peut garantir que le trafic n'atteigne pas un conteneur qui n'est pas prêt et que les conteneurs soient redémarrés en cas de défaillance.
Configurer les Probes
Probes ont un certain nombre de champs qui vous pouvez utiliser pour contrôler plus précisément le comportement de la vivacité et de la disponibilité des probes :
initialDelaySeconds
: Nombre de secondes après le démarrage du conteneur avant que les liveness et readiness probes ne soient lancées. La valeur par défaut est de 0 seconde. La valeur minimale est 0.periodSeconds
: La fréquence (en secondes) à laquelle la probe doit être effectuée. La valeur par défaut est de 10 secondes. La valeur minimale est de 1.timeoutSeconds
: Nombre de secondes après lequel la probe time out. Valeur par défaut à 1 seconde. La valeur minimale est de 1.successThreshold
: Le minimum de succès consécutifs pour que la probe soit considérée comme réussie après avoir échoué. La valeur par défaut est 1. Doit être 1 pour la liveness probe. La valeur minimale est de 1.failureThreshold
: Quand un Pod démarre et que la probe échoue, Kubernetes va tenterfailureThreshold
fois avant d'abandonner. Abandonner en cas de liveness probe signifie le redémarrage du conteneur. En cas de readiness probe, le Pod sera marqué Unready. La valeur par défaut est 3, la valeur minimum est 1.
HTTP probes
ont des champs supplémentaires qui peuvent être définis sur httpGet
:
host
: Nom de l'hôte auquel se connecter, par défaut l'IP du pod. Vous voulez peut être mettre "Host" en httpHeaders à la place.scheme
: Schéma à utiliser pour se connecter à l'hôte (HTTP ou HTTPS). La valeur par défaut est HTTP.path
: Chemin d'accès sur le serveur HTTP.httpHeaders
: En-têtes personnalisés à définir dans la requête. HTTP permet des en-têtes répétés.port
: Nom ou numéro du port à accéder sur le conteneur. Le numéro doit être dans un intervalle de 1 à 65535.
Pour une probe HTTP, le Kubelet envoie une requête HTTP au chemin et au port spécifiés pour effectuer la vérification. Le Kubelet envoie la probe à l'adresse IP du Pod, à moins que l'adresse ne soit surchargée par le champ optionnel host
dans httpGet
. Si Le champ scheme
est mis à HTTPS
, le Kubelet envoie une requête HTTPS en ignorant la vérification du certificat. Dans la plupart des scénarios, vous ne voulez pas définir le champ host
.
Voici un scénario où vous le mettriez en place. Supposons que le conteneur écoute sur 127.0.0.1 et que le champ hostNetwork
du Pod a la valeur true. Alors host
, sous httpGet
, devrait être défini à 127.0.0.1. Si votre Pod repose sur des hôtes virtuels, ce qui est probablement plus courant, vous ne devriez pas utiliser host
, mais plutôt mettre l'en-tête Host
dans httpHeaders
.
Le Kubelet fait la connexion de la probe au noeud, pas dans le Pod, ce qui signifie que vous ne pouvez pas utiliser un nom de service dans le paramètre host
puisque le Kubelet est incapable pour le résoudre.
A suivre
- Pour en savoir plus sur Probes des Conteneurs.
Référence
5.3.9 - Assigner des pods aux nœuds
Cette page montre comment assigner un Pod à un nœud particulier dans un cluster Kubernetes.
Pré-requis
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:
Pour consulter la version, entrezkubectl version
.
Ajouter un label à un nœud
-
Listez les nœuds de votre cluster :
kubectl get nodes
La sortie est la suivante :
NAME STATUS ROLES AGE VERSION worker0 Ready <none> 1d v1.13.0 worker1 Ready <none> 1d v1.13.0 worker2 Ready <none> 1d v1.13.0
-
Choisissez l'un de vos nœuds et ajoutez-y un label :
kubectl label nodes <your-node-name> disktype=ssd
où
<your-node-name>
est le nom du noeud que vous avez choisi. -
Vérifiez que le nœud que vous avez choisi a le label
disktype=ssd
:kubectl get nodes --show-labels
La sortie est la suivante :
NAME STATUS ROLES AGE VERSION LABELS worker0 Ready <none> 1d v1.13.0 ...,disktype=ssd,kubernetes.io/hostname=worker0 worker1 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker1 worker2 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker2
Dans la sortie précédente, vous constatez que le nœud
worker0
possède le labeldisktype=ssd
.
Créez un pod qui sera planifié sur un nœud sélectionné.
Le fichier de configuration de pod décrit un pod qui possède un selector de nœud de type disktype:ssd
. Cela signifie que le pod sera planifié sur un nœud ayant le label disktype=ssd
.
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disktype: ssd
-
Utilisez le fichier de configuration pour créer un pod qui sera ordonnancé sur votre nœud choisi :
kubectl apply -f https://k8s.io/examples/pods/pod-nginx.yaml
-
Vérifiez que le pod fonctionne sur le nœud que vous avez choisi :
kubectl get pods --output=wide
La sortie est la suivante :
NAME READY STATUS RESTARTS AGE IP NODE nginx 1/1 Running 0 13s 10.200.0.4 worker0
Créez un pod qui va être planifié sur un nœud spécifique
Vous pouvez également ordonnancer un pod sur un nœud spécifique via le paramètre nodeName
.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
nodeName: foo-node # schedule pod to specific node
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
Utilisez le fichier de configuration pour créer un pod qui sera ordonnancé sur foo-node
uniquement.
A suivre
Pour en savoir plus sur labels et selectors.
5.3.10 - Configurer l'initialisation du pod
Cette page montre comment utiliser un Init conteneur pour initialiser un Pod avant de lancer un conteneur d'application.
Pré-requis
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:
Pour consulter la version, entrezkubectl version
.
Créer un Pod qui a un Init Container
Dans cet exercice, vous allez créer un Pod qui a un conteneur d'application et Init conteneur. Le conteneur d'initialisation est achevé avant que le conteneur d'application ne démarre.
Voici le fichier de configuration du Pod :
apiVersion: v1
kind: Pod
metadata:
name: init-demo
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: workdir
mountPath: /usr/share/nginx/html
# These containers are run during pod initialization
initContainers:
- name: install
image: busybox
command:
- wget
- "-O"
- "/work-dir/index.html"
- http://kubernetes.io
volumeMounts:
- name: workdir
mountPath: "/work-dir"
dnsPolicy: Default
volumes:
- name: workdir
emptyDir: {}
Dans le fichier de configuration, vous pouvez voir que le Pod a un Volume que le conteneur d'initialisation et le conteneur d'application partagent.
Le conteneur d'initialisation monte le volume partagé à /work-dir
, et le conteneur d'application monte le volume partagé à /usr/share/nginx/html
. Le conteneur d'initialisation exécute la commande suivante puis se termine :
wget -O /work-dir/index.html http://kubernetes.io
Remarquez que le conteneur d'initialisation écrit le fichier index.html
dans le répertoire racine
du serveur nginx.
Créez le Pod :
kubectl apply -f https://k8s.io/examples/pods/init-containers.yaml
Vérifiez que le conteneur nginx fonctionne :
kubectl get pod init-demo
La sortie montre que le conteneur nginx est en cours d'exécution :
NAME READY STATUS RESTARTS AGE
init-demo 1/1 Running 0 1m
Entrez dans la console shell du conteneur nginx du Pod init-demo :
kubectl exec -it init-demo -- /bin/bash
Dans votre shell, envoyez une requête GET au serveur nginx :
root@nginx:~# apt-get update
root@nginx:~# apt-get install curl
root@nginx:~# curl localhost
La sortie montre que nginx sert la page web qui a été écrite par le conteneur d'initialisation :
<!Doctype html>
<html id="home">
<head>
...
"url": "http://kubernetes.io/"}</script>
</head>
<body>
...
<p>Kubernetes is open source giving you the freedom to take advantage ...</p>
...
A suivre
- Pour en savoir plus sur communiquer entre conteneurs fonctionnant dans le même Pod.
- Pour en savoir plus sur Init Conteneurs.
- Pour en savoir plus sur Volumes.
- Pour en savoir plus sur Débogage des Init Conteneurs
5.3.11 - Configurer un pod pour utiliser une ConfigMap
Les ConfigMaps vous permettent de découpler les artefacts de configuration du contenu de l'image pour garder les applications conteneurisées portables. Cette page fournit une série d'exemples d'utilisation montrant comment créer des ConfigMaps et configurer des pods à l'aide des données stockées dans des ConfigMaps.
Pré-requis
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:
Pour consulter la version, entrezkubectl version
.
Créer un ConfigMap
Vous pouvez utiliser soit kubectl create configmap
ou un générateur ConfigMap dans kustomization.yaml
pour créer un ConfigMap.
Notez que kubectl
prends en charge kustomization.yaml
à partir de la version 1.14.
Créer un ConfigMap à l'aide de kubectl create configmap
Utilisez la commande kubectl create configmap
pour créer des Configmaps depuis des dossiers, fichiers, ou des valeurs littérales:
kubectl create configmap <map-name> <data-source>
où <map-name> est le nom que vous souhaitez attribuer à ConfigMap et <data-source> est le répertoire, le fichier ou la valeur littérale à partir de laquelle récupérer les données.
La source de données correspond à une paire clé-valeur dans ConfigMap, où
- clé = le nom du fichier ou la clé que vous avez fournie sur la ligne de commande, et
- valeur = le contenu du fichier ou la valeur littérale que vous avez fournie sur la ligne de commande.
Vous pouvez utiliser kubectl describe
ou kubectl get
pour récupérer des informations sur un ConfigMap.
Créer des ConfigMaps à partir de répertoires
Vous pouvez utiliser kubectl create configmap
pour créer un ConfigMap à partir de plusieurs fichiers dans le même répertoire.
Par exemple:
# Créez le répertoire local
mkdir -p configure-pod-container/configmap/
# Téléchargez les exemples de fichiers dans le répertoire `configure-pod-container/configmap/`
wget https://kubernetes.io/examples/configmap/game.properties -O configure-pod-container/configmap/game.properties
wget https://kubernetes.io/examples/configmap/ui.properties -O configure-pod-container/configmap/ui.properties
# Créer la configmap
kubectl create configmap game-config --from-file=configure-pod-container/configmap/
combine le contenu du répertoire configure-pod-container/configmap/
game.properties
ui.properties
dans le ConfigMap suivant:
kubectl describe configmaps game-config
où la sortie est similaire à ceci:
Name: game-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
game.properties: 158 bytes
ui.properties: 83 bytes
Les fichiers game.properties
et ui.properties
dans le répertoire configure-pod-container/configmap/
sont représentés dans la section data
de la ConfigMap.
kubectl get configmaps game-config -o yaml
La sortie est similaire à ceci:
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2016-02-18T18:52:05Z
name: game-config
namespace: default
resourceVersion: "516"
uid: b4952dc3-d670-11e5-8cd0-68f728db1985
data:
game.properties: |
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
ui.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
Créer des ConfigMaps à partir de fichiers
Vous pouvez utiliser kubectl create configmap
pour créer un ConfigMap à partir d'un fichier individuel ou de plusieurs fichiers.
Par exemple,
kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/game.properties
produirait le ConfigMap suivant:
kubectl describe configmaps game-config-2
où la sortie est similaire à ceci:
Name: game-config-2
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
game.properties: 158 bytes
Vous pouvez passer l'argument --from-file
plusieurs fois pour créer un ConfigMap à partir de plusieurs sources de données.
kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/game.properties --from-file=configure-pod-container/configmap/ui.properties
Décrivez la ConfigMap crée game-config-2
:
kubectl describe configmaps game-config-2
La sortie est similaire à ceci:
Name: game-config-2
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
game.properties: 158 bytes
ui.properties: 83 bytes
Utilisez l'option --from-env-file
pour créer un ConfigMap à partir d'un fichier env, par exemple:
# Les fichiers env contiennent une liste de variables d'environnement.
# Ces règles de syntaxe s'appliquent:
# Chaque ligne d'un fichier env doit être au format VAR=VAL.
# Les lignes commençant par # (c'est-à-dire les commentaires) sont ignorées.
# Les lignes vides sont ignorées.
# Il n'y a pas de traitement spécial des guillemets (c'est-à-dire qu'ils feront partie de la valeur ConfigMap)).
# Téléchargez les exemples de fichiers dans le dossier `configure-pod-container/configmap/`
wget https://kubernetes.io/examples/configmap/game-env-file.properties -O configure-pod-container/configmap/game-env-file.properties
# Le fichier env `game-env-file.properties` ressemble à ceci
cat configure-pod-container/configmap/game-env-file.properties
enemies=aliens
lives=3
allowed="true"
# Ce commentaire et la ligne vide au-dessus sont ignorés
kubectl create configmap game-config-env-file \
--from-env-file=configure-pod-container/configmap/game-env-file.properties
produirait le ConfigMap suivant:
kubectl get configmap game-config-env-file -o yaml
où la sortie est similaire à ceci:
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2017-12-27T18:36:28Z
name: game-config-env-file
namespace: default
resourceVersion: "809965"
uid: d9d1ca5b-eb34-11e7-887b-42010a8002b8
data:
allowed: '"true"'
enemies: aliens
lives: "3"
--from-env-file
pour créer un ConfigMap à partir de plusieurs sources de données, seul le dernier fichier env est utilisé.
Le comportement consistant à passer plusieurs fois --from-env-file
est démontré par:
# Téléchargez les exemples de fichiers dans le répertoire `configure-pod-container/configmap/`
wget https://k8s.io/examples/configmap/ui-env-file.properties -O configure-pod-container/configmap/ui-env-file.properties
# Créez le configmap
kubectl create configmap config-multi-env-files \
--from-env-file=configure-pod-container/configmap/game-env-file.properties \
--from-env-file=configure-pod-container/configmap/ui-env-file.properties
produirait le ConfigMap suivant:
kubectl get configmap config-multi-env-files -o yaml
où la sortie est similaire à ceci:
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2017-12-27T18:38:34Z
name: config-multi-env-files
namespace: default
resourceVersion: "810136"
uid: 252c4572-eb35-11e7-887b-42010a8002b8
data:
color: purple
how: fairlyNice
textmode: "true"
Définissez la clé à utiliser lors de la création d'un ConfigMap à partir d'un fichier
Vous pouvez définir une clé autre que le nom de fichier à utiliser dans la section data
de votre ConfigMap lorsque vous utilisez l'argument --from-file
:
kubectl create configmap game-config-3 --from-file=<my-key-name>=<path-to-file>
où <my-key-name>
est la clé que vous souhaitez utiliser dans la ConfigMap et <path-to-file>
est l'emplacement du fichier de source de données que vous souhaitez que la clé représente.
Par exemple:
kubectl create configmap game-config-3 --from-file=game-special-key=configure-pod-container/configmap/game.properties
produirait la ConfigMap suivante:
kubectl get configmaps game-config-3 -o yaml
où la sortie est similaire à ceci:
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2016-02-18T18:54:22Z
name: game-config-3
namespace: default
resourceVersion: "530"
uid: 05f8da22-d671-11e5-8cd0-68f728db1985
data:
game-special-key: |
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
Créer des ConfigMaps à partir de valeurs littérales
Vous pouvez utiliser kubectl create configmap
avec l'argument --from-literal
définir une valeur littérale à partir de la ligne de commande:
kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
Vous pouvez transmettre plusieurs paires clé-valeur.
Chaque paire fournie sur la ligne de commande est représentée comme une entrée distincte dans la section data
de la ConfigMap.
kubectl get configmaps special-config -o yaml
La sortie est similaire à ceci:
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2016-02-18T19:14:38Z
name: special-config
namespace: default
resourceVersion: "651"
uid: dadce046-d673-11e5-8cd0-68f728db1985
data:
special.how: very
special.type: charm
Créer un ConfigMap à partir du générateur
kubectl
supporte kustomization.yaml
depuis 1.14.
Vous pouvez également créer un ConfigMap à partir de générateurs, puis l'appliquer pour créer l'objet sur l'Apiserver.
Les générateurs doivent être spécifiés dans un kustomization.yaml
à l'intérieur d'un répertoire.
Générer des ConfigMaps à partir de fichiers
Par exemple, pour générer un ConfigMap à partir de fichiers configure-pod-container/configmap/game.properties
# Create a kustomization.yaml file with ConfigMapGenerator
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: game-config-4
files:
- configure-pod-container/configmap/game.properties
EOF
Appliquer le dossier kustomization pour créer l'objet ConfigMap.
kubectl apply -k .
configmap/game-config-4-m9dm2f92bt created
Vous pouvez vérifier que le ConfigMap a été créé comme ceci:
kubectl get configmap
NAME DATA AGE
game-config-4-m9dm2f92bt 1 37s
kubectl describe configmaps/game-config-4-m9dm2f92bt
Name: game-config-4-m9dm2f92bt
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","data":{"game.properties":"enemies=aliens\nlives=3\nenemies.cheat=true\nenemies.cheat.level=noGoodRotten\nsecret.code.p...
Data
====
game.properties:
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
Events: <none>
Notez que le nom ConfigMap généré a un suffixe obtenu par hachage de son contenu. Cela garantit qu'un nouveau ConfigMap est généré chaque fois que le contenu est modifié.
Définissez la clé à utiliser lors de la génération d'un ConfigMap à partir d'un fichier
Vous pouvez définir une clé autre que le nom de fichier à utiliser dans le générateur ConfigMap.
Par exemple, pour générer un ConfigMap à partir du fichier configure-pod-container/configmap/game.properties
avec la clé game-special-key
# Créer un fichier kustomization.yaml avec ConfigMapGenerator
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: game-config-5
files:
- game-special-key=configure-pod-container/configmap/game.properties
EOF
Appliquer le dossier kustomization pour créer l'objet ConfigMap.
kubectl apply -k .
configmap/game-config-5-m67dt67794 created
Générer des ConfigMaps à partir de littéraux
Pour générer un ConfigMap à partir de littéraux special.type=charm
et special.how=very
, vous pouvez spécifier le générateur ConfigMap dans kustomization.yaml
comme
# Create a kustomization.yaml file with ConfigMapGenerator
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: special-config-2
literals:
- special.how=very
- special.type=charm
EOF
Appliquez le dossier kustomization pour créer l'objet ConfigMap.
kubectl apply -k .
configmap/special-config-2-c92b5mmcf2 created
Définir des variables d'environnement de conteneur à l'aide des données ConfigMap
Définissez une variable d'environnement de conteneur avec les données d'une seule ConfigMap
-
Définissez une variable d'environnement comme paire clé-valeur dans un ConfigMap:
kubectl create configmap special-config --from-literal=special.how=very
-
Attribuez la valeur
special.how
défini dans ConfigMap à la variable d'environnementSPECIAL_LEVEL_KEY
dans la spécification du Pod.apiVersion: v1 kind: Pod metadata: name: dapi-test-pod spec: containers: - name: test-container image: k8s.gcr.io/busybox command: [ "/bin/sh", "-c", "env" ] env: # Définie la variable d'environnement - name: SPECIAL_LEVEL_KEY valueFrom: configMapKeyRef: # La ConfigMap contenant la valeur que vous voulez attribuer à SPECIAL_LEVEL_KEY name: special-config # Spécifier la clé associée à la valeur key: special.how restartPolicy: Never
Créez le pod:
kubectl create -f https://kubernetes.io/examples/pods/pod-single-configmap-env-variable.yaml
Maintenant, la sortie du Pod comprend une variable d'environnement SPECIAL_LEVEL_KEY=very
.
Définir des variables d'environnement de conteneur avec des données de plusieurs ConfigMaps
-
Comme avec l'exemple précédent, créez d'abord les ConfigMaps.
apiVersion: v1 kind: ConfigMap metadata: name: special-config namespace: default data: special.how: very --- apiVersion: v1 kind: ConfigMap metadata: name: env-config namespace: default data: log_level: INFO
Créez le ConfigMap:
kubectl create -f https://kubernetes.io/examples/configmap/configmaps.yaml
-
Définissez les variables d'environnement dans la spécification Pod.
apiVersion: v1 kind: Pod metadata: name: dapi-test-pod spec: containers: - name: test-container image: k8s.gcr.io/busybox command: [ "/bin/sh", "-c", "env" ] env: - name: SPECIAL_LEVEL_KEY valueFrom: configMapKeyRef: name: special-config key: special.how - name: LOG_LEVEL valueFrom: configMapKeyRef: name: env-config key: log_level restartPolicy: Never
Créez le pod:
kubectl create -f https://kubernetes.io/examples/pods/pod-multiple-configmap-env-variable.yaml
Maintenant, la sortie du Pod comprend des variables d'environnement SPECIAL_LEVEL_KEY=very
et LOG_LEVEL=INFO
.
Configurer toutes les paires clé-valeur dans un ConfigMap en tant que variables d'environnement de conteneur
-
Créez un ConfigMap contenant plusieurs paires clé-valeur.
apiVersion: v1 kind: ConfigMap metadata: name: special-config namespace: default data: SPECIAL_LEVEL: very SPECIAL_TYPE: charm
Créez le ConfigMap:
kubectl create -f https://kubernetes.io/examples/configmap/configmap-multikeys.yaml
- Utilisez
envFrom
pour définir toutes les données du ConfigMap en tant que variables d'environnement du conteneur. La clé de ConfigMap devient le nom de la variable d'environnement dans le pod.
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "/bin/sh", "-c", "env" ]
envFrom:
- configMapRef:
name: special-config
restartPolicy: Never
Créez le pod:
kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-envFrom.yaml
Maintenant, la sortie du Pod comprend les variables d'environnement SPECIAL_LEVEL=very
et SPECIAL_TYPE=charm
.
Utiliser des variables d'environnement définies par ConfigMap dans les commandes du Pod
Vous pouvez utiliser des variables d'environnement définies par ConfigMap dans la section command
de la spécification du Pod en utilisant la syntaxe de substitution Kubernetes $(VAR_NAME)
.
Par exemple, la spécification de pod suivante
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "/bin/echo", "$(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]
env:
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: SPECIAL_LEVEL
- name: SPECIAL_TYPE_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: SPECIAL_TYPE
restartPolicy: Never
créé en exécutant
kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-env-var-valueFrom.yaml
produit la sortie suivante dans le conteneur test-container
:
very charm
Ajouter des données ConfigMap à un volume
Comme expliqué dans Créer des ConfigMaps à partir de fichiers, lorsque vous créez un ConfigMap à l'aide --from-file
, le nom de fichier devient une clé stockée dans la section data
du ConfigMap.
Le contenu du fichier devient la valeur de la clé.
Les exemples de cette section se réfèrent à un ConfigMap nommé special-config, illustré ci-dessous.
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
SPECIAL_LEVEL: very
SPECIAL_TYPE: charm
Créez le ConfigMap:
kubectl create -f https://kubernetes.io/examples/configmap/configmap-multikeys.yaml
Remplissez un volume avec des données stockées dans un ConfigMap
Ajoutez le nom ConfigMap sous la section volumes
de la spécification Pod.
Ceci ajoute les données ConfigMap au répertoire spécifié comme volumeMounts.mountPath
(dans ce cas, /etc/config
).
La section command
répertorie les fichiers de répertoire dont les noms correspondent aux clés de ConfigMap.
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "/bin/sh", "-c", "ls /etc/config/" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
# Indiquez le nom de la ConfigMap contenant les fichiers que vous souhaitez ajouter au conteneur
name: special-config
restartPolicy: Never
Créez le pod:
kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-volume.yaml
Lorsque le pod s'exécute, la commande ls /etc/config/
produit la sortie ci-dessous:
SPECIAL_LEVEL
SPECIAL_TYPE
/etc/config/
, ils seront supprimés.
Ajouter un configmap à un chemin spécifique dans un volume
Utilisez le champ path
pour spécifier le chemin de fichier souhaité pour les éléments de configmap spécifiques.
Dans ce cas, le SPECIAL_LEVEL
sera monté dans le volume config-volume
au chemin /etc/config/keys
.
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "/bin/sh","-c","cat /etc/config/keys" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: special-config
items:
- key: SPECIAL_LEVEL
path: keys
restartPolicy: Never
Créez le Pod :
kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-volume-specific-key.yaml
Lorsque le pod fonctionne, la commande cat /etc/config/keys
produit la sortie ci-dessous :
very
/etc/config/
seront supprimés.
Projections de clés pour des chemins et des autorisations de fichiers spécifiques
Vous pouvez projeter des clés vers des chemins spécifiques avec des autorisations spécifiques fichiers par fichiers. Le guide de l'utilisateur Secrets explique la syntaxe.
Les ConfigMaps montées sont mises à jour automatiquement
Lorsqu'une ConfigMap déjà consommée dans un volume est mise à jour, les clés projetées sont éventuellement mises à jour elles aussi. Kubelet vérifie si la ConfigMap montée est fraîche à chaque synchronisation périodique. Cependant, il utilise son cache local basé sur le ttl pour obtenir la valeur actuelle de la ConfigMap. Par conséquent, le délai total entre le moment où la ConfigMap est mise à jour et le moment où les nouvelles clés sont projetées vers le pod peut être aussi long que la période de synchronisation de kubelet (1 minute par défaut) + le ttl du cache ConfigMaps (1 minute par défaut) dans kubelet. Vous pouvez déclencher un rafraîchissement immédiat en mettant à jour l'une des annotations du pod.
Comprendre le lien entre les ConfigMaps et les Pods
La ressource API ConfigMap stocke les données de configuration sous forme de paires clé-valeur. Les données peuvent être consommées dans des pods ou fournir les configurations des composants du système tels que les contrôleurs. ConfigMap est similaire à Secrets, mais fournit un moyen de travailler avec des chaînes de caractères qui ne contiennent pas d'informations sensibles. Les utilisateurs comme les composants du système peuvent stocker des données de configuration dans un ConfigMap.
/etc
de Linux et à son contenu.
Par exemple, si vous créez un volume Kubernetes à partir d'une ConfigMap, chaque élément de données de la ConfigMap est représenté par un fichier individuel dans le volume.
Le champ data
de la ConfigMap contient les données de configuration.
Comme le montre l'exemple ci-dessous, cela peut être simple -- comme des propriétés individuelles définies à l'aide de --from-literal
-- ou complexe -- comme des fichiers de configuration ou des blobs JSON définis à l'aide de --from-file
.
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2016-02-18T19:14:38Z
name: example-config
namespace: default
data:
# example of a simple property defined using --from-literal
example.property.1: hello
example.property.2: world
# example of a complex property defined using --from-file
example.property.file: |-
property.1=value-1
property.2=value-2
property.3=value-3
Restrictions
-
Vous devez créer un ConfigMap avant de le référencer dans une spécification de Pod (sauf si vous marquez le ConfigMap comme "facultatif"). Si vous faites référence à un ConfigMap qui n'existe pas, le Pod ne démarrera pas. De même, les références à des clés qui n'existent pas dans la ConfigMap empêcheront le pod de démarrer.
-
Si vous utilisez
envFrom
pour définir des variables d'environnement à partir de ConfigMaps, les clés considérées comme invalides seront ignorées. Le pod sera autorisé à démarrer, mais les noms invalides seront enregistrés dans le journal des événements (InvalidVariableNames
). Le message du journal énumère chaque clé sautée. Par exemple :kubectl get events
Le résultat est similaire à celui-ci :
LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON SOURCE MESSAGE 0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames {kubelet, 127.0.0.1} Keys [1badkey, 2alsobad] from the EnvFrom configMap default/myconfig were skipped since they are considered invalid environment variable names.
-
Les ConfigMaps résident dans un Namespace. Un ConfigMap ne peut être référencé que par des pods résidant dans le même namespace.
-
Vous ne pouvez pas utiliser des ConfigMaps pour static pods, car le Kubelet ne le supporte pas.
A suivre
- Suivez un exemple concret de Configurer Redis en utilisant un ConfigMap.
5.3.12 - Partager l'espace de nommage des processus entre les conteneurs d'un Pod
Kubernetes v1.17 [stable]
Cette page montre comment configurer le partage de l'espace de noms d'un processus pour un pod. Lorsque le partage de l'espace de noms des processus est activé, les processus d'un conteneur sont visibles pour tous les autres conteneurs de ce pod.
Vous pouvez utiliser cette fonctionnalité pour configurer les conteneurs coopérants, comme un conteneur de sidecar de gestionnaire de journaux, ou pour dépanner les images de conteneurs qui n'incluent pas d'utilitaires de débogage comme un shell.
Pré-requis
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:
Votre serveur Kubernetes doit être au moins à la version v1.10. Pour consulter la version, entrezkubectl version
.
Configurer un Pod
Le partage de l'espace de nommage du processus est activé en utilisant le champ shareProcessNamespace
de v1.PodSpec
. Par exemple:
-
Créez le pod
nginx
sur votre cluster :kubectl apply -f https://k8s.io/examples/pods/share-process-namespace.yaml
-
Attachez-le au conteneur
shell
et lancezps
:kubectl attach -it nginx -c shell
Si vous ne verrez pas d'invite de commande, appuyez sur la touche Entrée.
/ # ps ax PID USER TIME COMMAND 1 root 0:00 /pause 8 root 0:00 nginx: master process nginx -g daemon off; 14 101 0:00 nginx: worker process 15 root 0:00 sh 21 root 0:00 ps ax
Vous pouvez signaler les processus dans d'autres conteneurs. Par exemple, envoyez SIGHUP
à
nginx pour relancer le processus de worker. Cela nécessite la fonctionnalité SYS_PTRACE
.
/ # kill -HUP 8
/ # ps ax
PID USER TIME COMMAND
1 root 0:00 /pause
8 root 0:00 nginx: master process nginx -g daemon off;
15 root 0:00 sh
22 101 0:00 nginx: worker process
23 root 0:00 ps ax
Il est même possible d'accéder aux autres conteneurs en utilisant le lien /proc/$pid/root
.
/ # head /proc/8/root/etc/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
Comprendre le processus de partage de l'espace de nommage
Les pods partagent de nombreuses ressources, il est donc logique qu'elles partagent également un espace de noms des processus. Pour certaines images de conteneur, on peut envisager de les isoler les uns des autres. Il est donc important de comprendre ces différences :
-
Le processus de conteneur n'a plus de PID 1. Certaines images de conteneurs refusent de démarrer sans PID 1 (par exemple, les conteneurs utilisant
systemd
) ou exécuter des commandes commekill -HUP 1
pour signaler le processus du conteneur. Dans les pods avec un espace de noms partagé du processus,kill -HUP 1
signalera la sandbox du pod. (/pause
dans l'exemple ci-dessus.) -
Les processus sont visibles par les autres conteneurs du pod. Cela inclut tout les informations visibles dans
/proc
, comme les mots de passe passés en argument ou les variables d'environnement. Celles-ci ne sont protégées que par des permissions Unix régulières. -
Les systèmes de fichiers des conteneurs sont visibles par les autres conteneurs du pod à travers le lien
/proc/$pid/root
. Cela rend le débogage plus facile, mais cela signifie aussi que les secrets du système de fichiers ne sont protégés que par les permissions du système de fichiers.
5.3.13 - Convertir un fichier Docker Compose en ressources Kubernetes
C'est quoi Kompose ? C'est un outil de conversion de tout ce qui compose (notamment Docker Compose) en orchestrateurs de conteneurs (Kubernetes ou OpenShift). Vous trouverez plus d'informations sur le site web de Kompose à http://kompose.io.
Pré-requis
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:
Pour consulter la version, entrezkubectl version
.
Installer Kompose
Nous disposons de plusieurs façons d'installer Kompose. Notre méthode préférée est de télécharger le binaire de la dernière version de GitHub.
Kompose est publié via GitHub sur un cycle de trois semaines, vous pouvez voir toutes les versions actuelles sur la page des releases de Github.
# Linux
curl -L https://github.com/kubernetes/kompose/releases/download/v1.16.0/kompose-linux-amd64 -o kompose
# macOS
curl -L https://github.com/kubernetes/kompose/releases/download/v1.16.0/kompose-darwin-amd64 -o kompose
# Windows
curl -L https://github.com/kubernetes/kompose/releases/download/v1.16.0/kompose-windows-amd64.exe -o kompose.exe
chmod +x kompose
sudo mv ./kompose /usr/local/bin/kompose
Alternativement, vous pouvez télécharger le tarball.
L'installation en utilisant go get
extrait de la branche master avec les derniers changements de développement.
go get -u github.com/kubernetes/kompose
Kompose est dans le dépôt CentOS EPEL.
Si vous n'avez pas le dépôt EPEL déjà installé et activé, vous pouvez le faire en lançant sudo yum install epel-release
Si vous avez EPEL activé dans votre système, vous pouvez installer Kompose comme n'importe quel autre logiciel.
sudo yum -y install kompose
Kompose est dans les dépôts Fedora 24, 25 et 26. Vous pouvez l'installer comme n'importe quel autre paquetage.
sudo dnf -y install kompose
Sur macOS, vous pouvez installer la dernière version via Homebrew:
brew install kompose
Utiliser Kompose
En quelques étapes, nous vous emmenons de Docker Compose à Kubernetes. Tous dont vous avez besoin est un fichier docker-compose.yml
.
-
Allez dans le répertoire contenant votre fichier
docker-compose.yml
. Si vous n'en avez pas, faites un test en utilisant celui-ci.version: "2" services: redis-master: image: k8s.gcr.io/redis:e2e ports: - "6379" redis-slave: image: gcr.io/google_samples/gb-redisslave:v3 ports: - "6379" environment: - GET_HOSTS_FROM=dns frontend: image: gcr.io/google-samples/gb-frontend:v4 ports: - "80:80" environment: - GET_HOSTS_FROM=dns labels: kompose.service.type: LoadBalancer
-
Lancez la commande
kompose up
pour déployer directement sur Kubernetes, ou passez plutôt à l'étape suivante pour générer un fichier à utiliser aveckubectl
.$ kompose up We are going to create Kubernetes Deployments, Services and PersistentVolumeClaims for your Dockerized application. If you need different kind of resources, use the 'kompose convert' and 'kubectl apply -f' commands instead. INFO Successfully created Service: redis INFO Successfully created Service: web INFO Successfully created Deployment: redis INFO Successfully created Deployment: web Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods,pvc' for details.
-
Pour convertir le fichier
docker-compose.yml
en fichiers que vous pouvez utiliser aveckubectl
, lancezkompose convert
et ensuitekubectl apply -f <output file>
.$ kompose convert INFO Kubernetes file "frontend-service.yaml" created INFO Kubernetes file "redis-master-service.yaml" created INFO Kubernetes file "redis-slave-service.yaml" created INFO Kubernetes file "frontend-deployment.yaml" created INFO Kubernetes file "redis-master-deployment.yaml" created INFO Kubernetes file "redis-slave-deployment.yaml" created
$ kubectl apply -f frontend-service.yaml,redis-master-service.yaml,redis-slave-service.yaml,frontend-deployment.yaml,redis-master-deployment.yaml,redis-slave-deployment.yaml service/frontend created service/redis-master created service/redis-slave created deployment.apps/frontend created deployment.apps/redis-master created deployment.apps/redis-slave created
Vos déploiements fonctionnent sur Kubernetes.
-
Accédez à votre application.
Si vous utilisez déjà
minikube
pour votre processus de développement :$ minikube service frontend
Sinon, regardons quelle IP votre service utilise !
$ kubectl describe svc frontend Name: frontend Namespace: default Labels: service=frontend Selector: service=frontend Type: LoadBalancer IP: 10.0.0.183 LoadBalancer Ingress: 192.0.2.89 Port: 80 80/TCP NodePort: 80 31144/TCP Endpoints: 172.17.0.4:80 Session Affinity: None No events.
Si vous utilisez un fournisseur de cloud computing, votre IP sera listée à côté de
LoadBalancer Ingress
.$ curl http://192.0.2.89
Guide de l'utilisateur
- CLI
- Documentation
Kompose supporte deux fournisseurs : OpenShift et Kubernetes.
Vous pouvez choisir un fournisseur ciblé en utilisant l'option globale --provider
. Si aucun fournisseur n'est spécifié, Kubernetes est défini par défaut.
kompose convert
Kompose prend en charge la conversion des fichiers Docker Compose V1, V2 et V3 en objets Kubernetes et OpenShift.
Kubernetes
$ kompose --file docker-voting.yml convert
WARN Unsupported key networks - ignoring
WARN Unsupported key build - ignoring
INFO Kubernetes file "worker-svc.yaml" created
INFO Kubernetes file "db-svc.yaml" created
INFO Kubernetes file "redis-svc.yaml" created
INFO Kubernetes file "result-svc.yaml" created
INFO Kubernetes file "vote-svc.yaml" created
INFO Kubernetes file "redis-deployment.yaml" created
INFO Kubernetes file "result-deployment.yaml" created
INFO Kubernetes file "vote-deployment.yaml" created
INFO Kubernetes file "worker-deployment.yaml" created
INFO Kubernetes file "db-deployment.yaml" created
$ ls
db-deployment.yaml docker-compose.yml docker-gitlab.yml redis-deployment.yaml result-deployment.yaml vote-deployment.yaml worker-deployment.yaml
db-svc.yaml docker-voting.yml redis-svc.yaml result-svc.yaml vote-svc.yaml worker-svc.yaml
Vous pouvez également fournir plusieurs fichiers de composition du Docker en même temps :
$ kompose -f docker-compose.yml -f docker-guestbook.yml convert
INFO Kubernetes file "frontend-service.yaml" created
INFO Kubernetes file "mlbparks-service.yaml" created
INFO Kubernetes file "mongodb-service.yaml" created
INFO Kubernetes file "redis-master-service.yaml" created
INFO Kubernetes file "redis-slave-service.yaml" created
INFO Kubernetes file "frontend-deployment.yaml" created
INFO Kubernetes file "mlbparks-deployment.yaml" created
INFO Kubernetes file "mongodb-deployment.yaml" created
INFO Kubernetes file "mongodb-claim0-persistentvolumeclaim.yaml" created
INFO Kubernetes file "redis-master-deployment.yaml" created
INFO Kubernetes file "redis-slave-deployment.yaml" created
$ ls
mlbparks-deployment.yaml mongodb-service.yaml redis-slave-service.jsonmlbparks-service.yaml
frontend-deployment.yaml mongodb-claim0-persistentvolumeclaim.yaml redis-master-service.yaml
frontend-service.yaml mongodb-deployment.yaml redis-slave-deployment.yaml
redis-master-deployment.yaml
Lorsque plusieurs fichiers de docker-compose sont fournis, la configuration est fusionnée. Toute configuration qui est commune sera surchargée par le fichier suivant.
OpenShift
$ kompose --provider openshift --file docker-voting.yml convert
WARN [worker] Service cannot be created because of missing port.
INFO OpenShift file "vote-service.yaml" created
INFO OpenShift file "db-service.yaml" created
INFO OpenShift file "redis-service.yaml" created
INFO OpenShift file "result-service.yaml" created
INFO OpenShift file "vote-deploymentconfig.yaml" created
INFO OpenShift file "vote-imagestream.yaml" created
INFO OpenShift file "worker-deploymentconfig.yaml" created
INFO OpenShift file "worker-imagestream.yaml" created
INFO OpenShift file "db-deploymentconfig.yaml" created
INFO OpenShift file "db-imagestream.yaml" created
INFO OpenShift file "redis-deploymentconfig.yaml" created
INFO OpenShift file "redis-imagestream.yaml" created
INFO OpenShift file "result-deploymentconfig.yaml" created
INFO OpenShift file "result-imagestream.yaml" created
Il supporte également la création de buildconfig pour la directive de build dans un service. Par défaut, il utilise le répertoire distant de la branche git courante comme répertoire source, et la branche courante comme branche source pour le build. Vous pouvez spécifier un repo source et une branche différents en utilisant respectivement les options --build-repo
et --build-branch
.
$ kompose --provider openshift --file buildconfig/docker-compose.yml convert
WARN [foo] Service cannot be created because of missing port.
INFO OpenShift Buildconfig using [email protected]:rtnpro/kompose.git::master as source.
INFO OpenShift file "foo-deploymentconfig.yaml" created
INFO OpenShift file "foo-imagestream.yaml" created
INFO OpenShift file "foo-buildconfig.yaml" created
oc create -f
, vous devez vous assurer que vous poussez l'artefact imagestream avant l'artefact buildconfig, pour contourner ce problème OpenShift : https://github.com/openshift/origin/issues/4518 .
kompose up
Kompose propose un moyen simple de déployer votre application "composée" sur Kubernetes ou OpenShift via kompose up
.
Kubernetes
$ kompose --file ./examples/docker-guestbook.yml up
We are going to create Kubernetes deployments and services for your Dockerized application.
If you need different kind of resources, use the 'kompose convert' and 'kubectl apply -f' commands instead.
INFO Successfully created service: redis-master
INFO Successfully created service: redis-slave
INFO Successfully created service: frontend
INFO Successfully created deployment: redis-master
INFO Successfully created deployment: redis-slave
INFO Successfully created deployment: frontend
Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods' for details.
$ kubectl get deployment,svc,pods
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.extensions/frontend 1 1 1 1 4m
deployment.extensions/redis-master 1 1 1 1 4m
deployment.extensions/redis-slave 1 1 1 1 4m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/frontend ClusterIP 10.0.174.12 <none> 80/TCP 4m
service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 13d
service/redis-master ClusterIP 10.0.202.43 <none> 6379/TCP 4m
service/redis-slave ClusterIP 10.0.1.85 <none> 6379/TCP 4m
NAME READY STATUS RESTARTS AGE
pod/frontend-2768218532-cs5t5 1/1 Running 0 4m
pod/redis-master-1432129712-63jn8 1/1 Running 0 4m
pod/redis-slave-2504961300-nve7b 1/1 Running 0 4m
Note:
- Vous devez avoir un cluster Kubernetes en cours d'exécution avec kubectl pré-configuré.
- Seuls les déploiements et les services sont générés et déployés dans Kubernetes. Si vous avez besoin d'autres types de ressources, utilisez les commandes
kompose convert
etkubectl apply -f
à la place.
OpenShift
$ kompose --file ./examples/docker-guestbook.yml --provider openshift up
We are going to create OpenShift DeploymentConfigs and Services for your Dockerized application.
If you need different kind of resources, use the 'kompose convert' and 'oc create -f' commands instead.
INFO Successfully created service: redis-slave
INFO Successfully created service: frontend
INFO Successfully created service: redis-master
INFO Successfully created deployment: redis-slave
INFO Successfully created ImageStream: redis-slave
INFO Successfully created deployment: frontend
INFO Successfully created ImageStream: frontend
INFO Successfully created deployment: redis-master
INFO Successfully created ImageStream: redis-master
Your application has been deployed to OpenShift. You can run 'oc get dc,svc,is' for details.
$ oc get dc,svc,is
NAME REVISION DESIRED CURRENT TRIGGERED BY
dc/frontend 0 1 0 config,image(frontend:v4)
dc/redis-master 0 1 0 config,image(redis-master:e2e)
dc/redis-slave 0 1 0 config,image(redis-slave:v1)
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc/frontend 172.30.46.64 <none> 80/TCP 8s
svc/redis-master 172.30.144.56 <none> 6379/TCP 8s
svc/redis-slave 172.30.75.245 <none> 6379/TCP 8s
NAME DOCKER REPO TAGS UPDATED
is/frontend 172.30.12.200:5000/fff/frontend
is/redis-master 172.30.12.200:5000/fff/redis-master
is/redis-slave 172.30.12.200:5000/fff/redis-slave v1
Note:
- Vous devez avoir un cluster OpenShift en cours d'exécution avec
oc
pré-configuré (oc login
)
kompose down
Une fois que vous avez déployé l'application "composée" sur Kubernetes, $ kompose down
vous
facilitera la suppression de l'application en supprimant ses déploiements et services. Si vous avez besoin de supprimer d'autres ressources, utilisez la commande 'kubectl'.
$ kompose --file docker-guestbook.yml down
INFO Successfully deleted service: redis-master
INFO Successfully deleted deployment: redis-master
INFO Successfully deleted service: redis-slave
INFO Successfully deleted deployment: redis-slave
INFO Successfully deleted service: frontend
INFO Successfully deleted deployment: frontend
Note:
- Vous devez avoir un cluster Kubernetes en cours d'exécution avec kubectl pré-configuré.
Construire et pousser des images de docker
Kompose permet de construire et de pousser des images Docker. Lorsque vous utilisez la clé build
dans votre fichier Docker Compose, votre image sera :
- Automatiquement construite avec le Docker en utilisant la clé "image" spécifiée dans votre fichier
- Être poussé vers le bon dépôt Docker en utilisant les identifiants locaux (situés dans
.docker/config
)
Utilisation d'un exemple de fichier Docker Compose:
version: "2"
services:
foo:
build: "./build"
image: docker.io/foo/bar
En utilisant kompose up
avec une clé build
:
$ kompose up
INFO Build key detected. Attempting to build and push image 'docker.io/foo/bar'
INFO Building image 'docker.io/foo/bar' from directory 'build'
INFO Image 'docker.io/foo/bar' from directory 'build' built successfully
INFO Pushing image 'foo/bar:latest' to registry 'docker.io'
INFO Attempting authentication credentials 'https://index.docker.io/v1/
INFO Successfully pushed image 'foo/bar:latest' to registry 'docker.io'
INFO We are going to create Kubernetes Deployments, Services and PersistentVolumeClaims for your Dockerized application. If you need different kind of resources, use the 'kompose convert' and 'kubectl apply -f' commands instead.
INFO Deploying application in "default" namespace
INFO Successfully created Service: foo
INFO Successfully created Deployment: foo
Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods,pvc' for details.
Afin de désactiver cette fonctionnalité, ou de choisir d'utiliser la génération de BuildConfig (avec OpenShift) --build (local|build-config|none)
peut être passé.
# Désactiver la construction/poussée d'images Docker
$ kompose up --build none
# Générer des artefacts de Build Config pour OpenShift
$ kompose up --provider openshift --build build-config
Autres conversions
La transformation par défaut komposer
va générer des Déploiements et Services de Kubernetes, au format yaml. Vous avez une autre option pour générer json avec -j
. Vous pouvez aussi générer des objets de Replication Controllers, Daemon Sets, ou Helm charts.
$ kompose convert -j
INFO Kubernetes file "redis-svc.json" created
INFO Kubernetes file "web-svc.json" created
INFO Kubernetes file "redis-deployment.json" created
INFO Kubernetes file "web-deployment.json" created
Les fichiers *-deployment.json
contiennent les objets Déploiements.
$ kompose convert --replication-controller
INFO Kubernetes file "redis-svc.yaml" created
INFO Kubernetes file "web-svc.yaml" created
INFO Kubernetes file "redis-replicationcontroller.yaml" created
INFO Kubernetes file "web-replicationcontroller.yaml" created
Les fichiers *-replicationcontroller.yaml
contiennent les objets du Contrôleur de Réplication. Si vous voulez spécifier des répliques (la valeur par défaut est 1), utilisez l'option --replicas
: $ kompose convert --replication-controller --replicas 3
$ kompose convert --daemon-set
INFO Kubernetes file "redis-svc.yaml" created
INFO Kubernetes file "web-svc.yaml" created
INFO Kubernetes file "redis-daemonset.yaml" created
INFO Kubernetes file "web-daemonset.yaml" created
Les fichiers *-daemonset.yaml
contiennent les objets du Daemon Set
Si vous voulez générer un Chart à utiliser avec Helm, faites-le simplement :
$ kompose convert -c
INFO Kubernetes file "web-svc.yaml" created
INFO Kubernetes file "redis-svc.yaml" created
INFO Kubernetes file "web-deployment.yaml" created
INFO Kubernetes file "redis-deployment.yaml" created
chart created in "./docker-compose/"
$ tree docker-compose/
docker-compose
├── Chart.yaml
├── README.md
└── templates
├── redis-deployment.yaml
├── redis-svc.yaml
├── web-deployment.yaml
└── web-svc.yaml
La structure du Chart est destinée à fournir un modèle pour la construction de vos chartes de Helm.
Étiquettes
kompose
supporte les étiquettes spécifiques à Kompose dans le fichier docker-compose.yml
afin de définir explicitement le comportement d'un service lors de la conversion.
- Le fichier
kompose.service.type
définit le type de service à créer.
Par exemple :
version: "2"
services:
nginx:
image: nginx
dockerfile: foobar
build: ./foobar
cap_add:
- ALL
container_name: foobar
labels:
kompose.service.type: nodeport
kompose.service.expose
définit si le service doit être accessible depuis l'extérieur du cluster ou non. Si la valeur est fixée à "true", le fournisseur définit automatiquement l'extrémité, et pour toute autre valeur, la valeur est définie comme le nom d'hôte. Si plusieurs ports sont définis dans un service, le premier est choisi pour être l'exposé.- Pour le fournisseur Kubernetes, une ressource ingress est créée et il est supposé qu'un contrôleur ingress a déjà été configuré.
- Pour le fournisseur OpenShift, une route est créée.
Par exemple :
version: "2"
services:
web:
image: tuna/docker-counter23
ports:
- "5000:5000"
links:
- redis
labels:
kompose.service.expose: "counter.example.com"
redis:
image: redis:3.0
ports:
- "6379"
Les options actuellement supportées sont :
Key | Value |
---|---|
kompose.service.type | nodeport / clusterip / loadbalancer |
kompose.service.expose | true / hostname |
kompose.service.type
doit être défini avec ports
uniquement, sinon kompose
échouera.
Redémarrer
Si vous voulez créer des pods normaux sans contrôleurs, vous pouvez utiliser la construction
restart
de docker-compose pour définir cela. Suivez le tableau ci-dessous pour voir ce qui se passe avec la valeur de restart
.
docker-compose restart |
object created | Pod restartPolicy |
---|---|---|
"" |
controller object | Always |
always |
controller object | Always |
on-failure |
Pod | OnFailure |
no |
Pod | Never |
déploiement
ou replicationcontroller
, etc.
Par exemple, le service pival
deviendra un Pod. Ce conteneur a calculé la valeur de pi
.
version: '2'
services:
pival:
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restart: "on-failure"
Avertissement concernant les configurations de déploiement
Si le fichier Docker Compose a un volume spécifié pour un service, la stratégie Deployment (Kubernetes) ou DeploymentConfig (OpenShift) est changée en "Recreate" au lieu de "RollingUpdate" (par défaut). Ceci est fait pour éviter que plusieurs instances d'un service n'accèdent à un volume en même temps.
Si le fichier Docker Compose a un nom de service avec _
dedans (par exemple web_service
), alors il sera remplacé par -
et le nom du service sera renommé en conséquence (par exemple web-service
). Kompose fait cela parce que "Kubernetes" n'autorise pas _
dans le nom de l'objet.
Veuillez noter que changer le nom du service peut casser certains fichiers docker-compose
.
Versions du Docker Compose
Kompose supporte les versions Docker Compose : 1, 2 et 3. Nous avons un support limité sur les versions 2.1 et 3.2 en raison de leur nature expérimentale.
Une liste complète sur la compatibilité entre les trois versions est donnée dans notre document de conversion incluant une liste de toutes les clés Docker Compose incompatibles.
5.4 - Gérez vos objets Kubernetes
5.5 - Injection des données dans les applications
5.6 - Exécution des applications
5.7 - Exécution des jobs
5.8 - Accès aux applications dans un cluster
5.8.1 - Tableau de bord (Dashboard)
Le tableau de bord (Dashboard) est une interface web pour Kubernetes. Vous pouvez utiliser ce tableau de bord pour déployer des applications conteneurisées dans un cluster Kubernetes, dépanner votre application conteneurisée et gérer les ressources du cluster. Vous pouvez utiliser le tableau de bord pour obtenir une vue d'ensemble des applications en cours d'exécution dans votre cluster, ainsi que pour créer ou modifier des ressources Kubernetes individuelles. (comme des Deployments, Jobs, DaemonSets, etc). Par exemple, vous pouvez redimensionner un Deployment, lancer une mise à jour progressive, recréer un pod ou déployez de nouvelles applications à l'aide d'un assistant de déploiement.
Le tableau de bord fournit également des informations sur l'état des ressources Kubernetes de votre cluster et sur les erreurs éventuelles.
Déploiement du tableau de bord
L'interface utilisateur du tableau de bord n'est pas déployée par défaut. Pour le déployer, exécutez la commande suivante:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended.yaml
Accès à l'interface utilisateur du tableau de bord
Pour protéger vos données dans le cluster, le tableau de bord se déploie avec une configuration RBAC minimale par défaut. Actuellement, le tableau de bord prend uniquement en charge la connexion avec un jeton de support. Pour créer un jeton pour cette démo, vous pouvez suivre notre guide sur créer un exemple d'utilisateur.
Proxy en ligne de commande
Vous pouvez accéder au tableau de bord à l'aide de l'outil en ligne de commande kubectl en exécutant la commande suivante:
kubectl proxy
Kubectl mettra le tableau de bord à disposition à l'adresse suivante: http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/.
Vous ne pouvez accéder à l'interface utilisateur que depuis la machine sur laquelle la commande est exécutée.
Voir kubectl proxy --help
pour plus d'options.
Page de bienvenue
Lorsque vous accédez au tableau de bord sur un cluster vide, la page d'accueil s'affiche.
Cette page contient un lien vers ce document ainsi qu'un bouton pour déployer votre première application.
De plus, vous pouvez voir quelles applications système sont exécutées par défaut dans le namespace kubernetes-dashboard
de votre cluster, par exemple le tableau de bord lui-même.
Déploiement d'applications conteneurisées
Le tableau de bord vous permet de créer et de déployer une application conteneurisée en tant que Deployment et optionnellement un Service avec un simple assistant. Vous pouvez spécifier manuellement les détails de l'application ou charger un fichier YAML ou JSON contenant la configuration de l'application.
Cliquez sur le bouton CREATE dans le coin supérieur droit de n’importe quelle page pour commencer.
Spécifier les détails de l'application
L'assistant de déploiement s'attend à ce que vous fournissiez les informations suivantes:
-
App name (obligatoire): Nom de votre application. Un label avec le nom sera ajouté au Deployment et Service, le cas échéant, qui sera déployé.
Le nom de l'application doit être unique dans son namespace Kubernetes. Il doit commencer par une lettre minuscule et se terminer par une lettre minuscule ou un chiffre et ne contenir que des lettres minuscules, des chiffres et des tirets (-). Il est limité à 24 caractères. Les espaces de début et de fin sont ignorés.
-
Container image (obligatoire): L'URL d'une image de conteneur sur n'importe quel registre, ou une image privée (généralement hébergée sur le registre de conteneurs Google ou le hub Docker). La spécification d'image de conteneur doit se terminer par un deux-points.
-
Number of pods (obligatoire): Nombre cible de pods dans lesquels vous souhaitez déployer votre application. La valeur doit être un entier positif.
Un objet Deployment sera créé pour maintenir le nombre souhaité de pods dans votre cluster.
-
Service (optionnel): Pour certaines parties de votre application (par exemple les serveurs frontaux), vous souhaiterez peut-être exposer un Service sur une adresse IP externe, peut-être publique, en dehors de votre cluster (Service externe). Pour les Services externes, vous devrez peut-être ouvrir un ou plusieurs ports pour le faire. Trouvez plus de détails ici.
Les autres services visibles uniquement de l'intérieur du cluster sont appelés Services internes.
Quel que soit le type de service, si vous choisissez de créer un service et que votre conteneur écoute sur un port (entrant), vous devez spécifier deux ports. Le Service sera créé en mappant le port (entrant) sur le port cible vu par le conteneur. Ce Service acheminera le trafic vers vos pods déployés. Les protocoles pris en charge sont TCP et UDP. Le nom DNS interne de ce service sera la valeur que vous avez spécifiée comme nom d'application ci-dessus.
Si nécessaire, vous pouvez développer la section Options avancées dans laquelle vous pouvez spécifier davantage de paramètres:
-
Description: Le texte que vous entrez ici sera ajouté en tant qu'annotation au Deployment et affiché dans les détails de l'application.
-
Labels: Les labels par défaut à utiliser pour votre application sont le nom et la version de l’application. Vous pouvez spécifier des labels supplémentaires à appliquer au Deployment, Service (le cas échéant), et Pods, tels que la release, l'environnement, le niveau, la partition et la piste d'édition.
Exemple:
release=1.0 tier=frontend environment=pod track=stable
-
Namespace: Kubernetes prend en charge plusieurs clusters virtuels s'exécutant sur le même cluster physique. Ces clusters virtuels sont appelés namespaces. Ils vous permettent de partitionner les ressources en groupes nommés de manière logique.
Le tableau de bord propose tous les namespaces disponibles dans une liste déroulante et vous permet de créer un nouveau namespace. Le nom du namespace peut contenir au maximum 63 caractères alphanumériques et des tirets (-), mais ne peut pas contenir de lettres majuscules. Les noms de Namespace ne devraient pas être composés uniquement de chiffres. Si le nom est défini sous la forme d’un nombre, tel que 10, le pod sera placé dans le namespace par défaut.
Si la création du namespace réussit, celle-ci est sélectionnée par défaut. Si la création échoue, le premier namespace est sélectionné.
-
Image Pull Secret: Si l'image de conteneur spécifiée est privée, il peut être nécessaire de configurer des identifiants de pull secret.
Le tableau de bord propose tous les secrets disponibles dans une liste déroulante et vous permet de créer un nouveau secret. Le nom de secret doit respecter la syntaxe du nom de domaine DNS, par exemple.
new.image-pull.secret
. Le contenu d'un secret doit être codé en base64 et spécifié dans un fichier.dockercfg
. Le nom du secret peut contenir 253 caractères maximum.Si la création du secret d’extraction d’image est réussie, celle-ci est sélectionnée par défaut. Si la création échoue, aucun secret n'est appliqué.
-
CPU requirement (cores) et Memory requirement (MiB): Vous pouvez spécifier les limites de ressource minimales pour le conteneur. Par défaut, les pods fonctionnent avec des limites de CPU et de mémoire illimitées.
-
Run command et Run command arguments: Par défaut, vos conteneurs exécutent les valeurs par défaut de la commande d'entrée de l'image spécifiée. Vous pouvez utiliser les options de commande et les arguments pour remplacer la valeur par défaut.
-
Run as privileged: Ce paramètre détermine si les processus dans conteneurs privilégiés sont équivalents aux processus s'exécutant en tant que root sur l'hôte. Les conteneurs privilégiés peuvent utiliser des fonctionnalités telles que la manipulation de la pile réseau et l'accès aux périphériques.
-
Environment variables: Kubernetes expose ses Services via des variables d'environnement. Vous pouvez composer une variable d'environnement ou transmettre des arguments à vos commandes en utilisant les valeurs des variables d'environnement.
Ils peuvent être utilisés dans les applications pour trouver un Service. Les valeurs peuvent référencer d'autres variables à l'aide de la syntaxe$(VAR_NAME)
.
Téléchargement d'un fichier YAML ou JSON
Kubernetes supporte la configuration déclarative. Dans ce style, toute la configuration est stockée dans des fichiers de configuration YAML ou JSON à l'aide des schémas de ressources de l'API de Kubernetes.
Au lieu de spécifier les détails de l'application dans l'assistant de déploiement, vous pouvez définir votre application dans des fichiers YAML ou JSON et télécharger les fichiers à l'aide du tableau de bord.
Utilisation du tableau de bord
Les sections suivantes décrivent des vues du tableau de bord de Kubernetes; ce qu'elles fournissent et comment peuvent-elles être utilisées.
Navigation
Lorsque des objets Kubernetes sont définis dans le cluster, le tableau de bord les affiche dans la vue initiale. Par défaut, seuls les objets du namespace default sont affichés, ce qui peut être modifié à l'aide du sélecteur d'espace de nom situé dans le menu de navigation.
Le tableau de bord montre la plupart des types d'objets Kubernetes et les regroupe dans quelques catégories de menus.
Vue d'ensemble de l'administrateur
Pour les administrateurs de cluster et de namespace, le tableau de bord répertorie les noeuds, les namespaces et les volumes persistants et propose des vues de détail pour ceux-ci. La vue Liste de nœuds contient les mesures d'utilisation de CPU et de la mémoire agrégées sur tous les nœuds. La vue détaillée affiche les métriques d'un nœud, ses spécifications, son statut, les ressources allouées, les événements et les pods s'exécutant sur le nœud.
Charges de travail
Affiche toutes les applications en cours d'exécution dans le namespace selectionné. La vue répertorie les applications par type de charge de travail. (e.g., Deployments, Replica Sets, Stateful Sets, etc.) et chaque type de charge de travail peut être visualisé séparément. Les listes récapitulent les informations exploitables sur les charges de travail, telles que le nombre de Pods prêts pour un Replica Set ou l'utilisation actuelle de la mémoire pour un Pod.
Les vues détaillées des charges de travail affichent des informations sur l'état et les spécifications, ainsi que les relations de surface entre les objets. Par exemple, les Pods qu'un Replica Set controle ou bien les nouveaux Replica Sets et Horizontal Pod Autoscalers pour les Deployments.
Services
Affiche les ressources Kubernetes permettant d’exposer les services au monde externe et de les découvrir au sein d’un cluster. Pour cette raison, les vues Service et Ingress montrent les Pods ciblés par eux, les points de terminaison internes pour les connexions au cluster et les points de terminaison externes pour les utilisateurs externes.
Stockage
La vue de stockage montre les ressources Persistent Volume Claim qui sont utilisées par les applications pour stocker des données.
Config Maps et Secrets
Affiche toutes les ressources Kubernetes utilisées pour la configuration en temps réel d'applications s'exécutant dans des clusters. La vue permet d’éditer et de gérer des objets de configuration et d’afficher les secrets cachés par défaut.
Visualisation de journaux
Les listes de Pod et les pages de détail renvoient à une visionneuse de journaux intégrée au tableau de bord. Le visualiseur permet d’exploiter les logs des conteneurs appartenant à un seul Pod.
A suivre
Pour plus d'informations, voir la page du projet Kubernetes Dashboard.
5.8.2 - Configurer l'accès à plusieurs clusters
Cette page montre comment configurer l'accès à plusieurs clusters à l'aide de fichiers de configuration.
Une fois vos clusters, utilisateurs et contextes définis dans un ou plusieurs fichiers de configuration, vous pouvez basculer rapidement entre les clusters en utilisant la commande kubectl config use-context
.
kubeconfig
.
Pré-requis
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:
Pour vérifier que kubectl est installé, executez kubectl version --client
.
La version kubectl doit être dans une version mineure de votre
serveur API du cluster.
Définir des clusters, des utilisateurs et des contextes
Supposons que vous ayez deux clusters, un pour le développement et un pour le travail scratch
.
Dans le cluster development
, vos développeurs frontend travaillent dans un espace de noms appelé frontend
, et vos développeurs de stockage travaillent dans un espace de noms appelé storage
.
Dans votre cluster scratch
, les développeurs travaillent dans le namespace par défaut ou créent des namespaces auxiliaires comme bon leur semble.
L'accès au cluster development
nécessite une authentification par certificat.
L'accès au cluster scratch
nécessite une authentification par nom d'utilisateur et mot de passe.
Créez un répertoire nommé config-exercice
.
Dans votre répertoire config-exercice
, créez un fichier nommé config-demo
avec ce contenu:
apiVersion: v1
kind: Config
preferences: {}
clusters:
- cluster:
name: development
- cluster:
name: scratch
users:
- name: developer
- name: experimenter
contexts:
- context:
name: dev-frontend
- context:
name: dev-storage
- context:
name: exp-scratch
Un fichier de configuration décrit les clusters, les utilisateurs et les contextes.
Votre fichier config-demo
a le cadre pour décrire deux clusters, deux utilisateurs et trois contextes.
Allez dans votre répertoire config-exercice
.
Entrez ces commandes pour ajouter les détails du cluster à votre fichier de configuration:
kubectl config --kubeconfig=config-demo set-cluster development --server=https://1.2.3.4 --certificate-authority=fake-ca-file
kubectl config --kubeconfig=config-demo set-cluster scratch --server=https://5.6.7.8 --insecure-skip-tls-verify
Ajoutez les détails de l'utilisateur à votre fichier de configuration:
kubectl config --kubeconfig=config-demo set-credentials developer --client-certificate=fake-cert-file --client-key=fake-key-seefile
kubectl config --kubeconfig=config-demo set-credentials experimenter --username=exp --password=some-password
- Pour supprimer un utilisateur, vous pouvez exécuter
kubectl --kubeconfig=config-demo config unset users.<name>
- Pour supprimer un cluster, vous pouvez exécuter
kubectl --kubeconfig=config-demo config unset clusters.<name>
- Pour supprimer un contexte, vous pouvez exécuter
kubectl --kubeconfig=config-demo config unset contexts.<name>
Ajoutez des détails de contexte à votre fichier de configuration:
kubectl config --kubeconfig=config-demo set-context dev-frontend --cluster=development --namespace=frontend --user=developer
kubectl config --kubeconfig=config-demo set-context dev-storage --cluster=development --namespace=storage --user=developer
kubectl config --kubeconfig=config-demo set-context exp-scratch --cluster=scratch --namespace=default --user=experimenter
Ouvrez votre fichier config-demo
pour voir les détails ajoutés.
Au lieu d'ouvrir le fichier config-demo
, vous pouvez utiliser la commande kubectl config view
.
kubectl config --kubeconfig=config-demo view
La sortie montre les deux clusters, deux utilisateurs et trois contextes:
apiVersion: v1
clusters:
- cluster:
certificate-authority: fake-ca-file
server: https://1.2.3.4
name: development
- cluster:
insecure-skip-tls-verify: true
server: https://5.6.7.8
name: scratch
contexts:
- context:
cluster: development
namespace: frontend
user: developer
name: dev-frontend
- context:
cluster: development
namespace: storage
user: developer
name: dev-storage
- context:
cluster: scratch
namespace: default
user: experimenter
name: exp-scratch
current-context: ""
kind: Config
preferences: {}
users:
- name: developer
user:
client-certificate: fake-cert-file
client-key: fake-key-file
- name: experimenter
user:
password: some-password
username: exp
Le fake-ca-file
, fake-cert-file
et fake-key-file
ci-dessus sont les espaces réservés pour les noms de chemin des fichiers de certificat.
Vous devez les remplacer par les noms de chemin réels des fichiers de certificat dans votre environnement.
Parfois, vous souhaiterez peut-être utiliser des données encodées en Base64 incorporées ici au lieu de fichiers de certificat séparés; dans ce cas, vous devez ajouter le suffixe -data
aux clés, par exemple, certificate-Authority-data
, client-certificate-data
, client-key-data
.
Chaque contexte est un triplet (cluster, utilisateur, namespace).
Par exemple, le contexte dev-frontend
dit, "Utilisez les informations d'identification de l'utilisateur developer
pour accéder au namespace frontend
du cluster development
".
Définissez le contexte actuel:
kubectl config --kubeconfig=config-demo use-context dev-frontend
Maintenant, chaque fois que vous entrez une commande kubectl
, l'action s'appliquera au cluster et au namespace répertorié dans le contexte dev-frontend
.
Et la commande utilisera les informations d'identification de l'utilisateur répertoriées dans le contexte dev-frontend
.
Pour voir uniquement les informations de configuration associées au contexte actuel, utilisez l'indicateur --minify
.
kubectl config --kubeconfig=config-demo view --minify
La sortie affiche les informations de configuration associées au contexte dev-frontend
:
apiVersion: v1
clusters:
- cluster:
certificate-authority: fake-ca-file
server: https://1.2.3.4
name: development
contexts:
- context:
cluster: development
namespace: frontend
user: developer
name: dev-frontend
current-context: dev-frontend
kind: Config
preferences: {}
users:
- name: developer
user:
client-certificate: fake-cert-file
client-key: fake-key-file
Supposons maintenant que vous souhaitiez travailler pendant un certain temps dans le cluster scratch.
Changez le contexte actuel en exp-scratch
:
kubectl config --kubeconfig=config-demo use-context exp-scratch
Maintenant, toute commande kubectl
que vous donnez s'appliquera au namespace par défaut du cluster scratch
.
Et la commande utilisera les informations d'identification de l'utilisateur répertoriées dans le contexte exp-scratch
.
Afficher la configuration associée au nouveau contexte actuel, exp-scratch
.
kubectl config --kubeconfig=config-demo view --minify
Enfin, supposons que vous vouliez travailler pendant un certain temps dans le namespace storage
du cluster development
.
Changez le contexte actuel en dev-storage
:
kubectl config --kubeconfig=config-demo use-context dev-storage
Afficher la configuration associée au nouveau contexte actuel, dev-storage
.
kubectl config --kubeconfig=config-demo view --minify
Créer un deuxième fichier de configuration
Dans votre répertoire config-exercice
, créez un fichier nommé config-demo-2
avec ce contenu:
apiVersion: v1
kind: Config
preferences: {}
contexts:
- context:
cluster: development
namespace: ramp
user: developer
name: dev-ramp-up
Le fichier de configuration précédent définit un nouveau contexte nommé dev-ramp-up
.
Définissez la variable d'environnement KUBECONFIG
Vérifiez si vous avez une variable d'environnement nommée KUBECONFIG
.
Si tel est le cas, enregistrez la valeur actuelle de votre variable d'environnement KUBECONFIG
, afin de pouvoir la restaurer ultérieurement.
Par exemple:
Linux
export KUBECONFIG_SAVED=$KUBECONFIG
Windows PowerShell
$Env:KUBECONFIG_SAVED=$ENV:KUBECONFIG
La variable d'environnement KUBECONFIG
est une liste de chemins vers les fichiers de configuration.
La liste est délimitée par deux-points pour Linux et Mac et par des points-virgules pour Windows.
Si vous avez une variable d'environnement KUBECONFIG
, familiarisez-vous avec les fichiers de configuration de la liste.
Ajoutez temporairement deux chemins à votre variable d'environnement KUBECONFIG
.
Par exemple:
Linux
export KUBECONFIG=$KUBECONFIG:config-demo:config-demo-2
Windows PowerShell
$Env:KUBECONFIG=("config-demo;config-demo-2")
Dans votre répertoire config-exercice
, entrez cette commande:
kubectl config view
La sortie affiche les informations fusionnées de tous les fichiers répertoriés dans votre variable d'environnement KUBECONFIG
.
En particulier, notez que les informations fusionnées ont le contexte dev-ramp-up
du fichier config-demo-2
et les trois contextes du fichier config-demo
:
contexts:
- context:
cluster: development
namespace: frontend
user: developer
name: dev-frontend
- context:
cluster: development
namespace: ramp
user: developer
name: dev-ramp-up
- context:
cluster: development
namespace: storage
user: developer
name: dev-storage
- context:
cluster: scratch
namespace: default
user: experimenter
name: exp-scratch
Pour plus d'informations sur la manière dont les fichiers kubeconfig sont fusionnés, consultez Organisation de l'accès au cluster à l'aide des fichiers kubeconfig
Explorez le répertoire $HOME/.kube
Si vous avez déjà un cluster, et vous pouvez utiliser kubectl
pour interagir avec le cluster, alors vous avez probablement un fichier nommé config
dans le repertoire $HOME/.kube
.
Allez dans $ HOME/.kube
, et voyez quels fichiers sont là.
En règle générale, il existe un fichier nommé config
.
Il peut également y avoir d'autres fichiers de configuration dans ce répertoire.
Familiarisez-vous brièvement avec le contenu de ces fichiers.
Ajoutez $HOME/.kube/config à votre variable d'environnement KUBECONFIG
Si vous avez un fichier $ HOME/.kube/config
, et qu'il n'est pas déjà répertorié dans votre variable d'environnement KUBECONFIG
, ajoutez-le maintenant à votre variable d'environnement KUBECONFIG
.
Par exemple:
Linux
export KUBECONFIG=$KUBECONFIG:$HOME/.kube/config
Windows Powershell
$Env:KUBECONFIG="$Env:KUBECONFIG;$HOME\.kube\config"
Affichez les informations de configuration fusionnées à partir de tous les fichiers qui sont maintenant répertoriés dans votre variable d'environnement KUBECONFIG
.
Dans votre répertoire config-exercice, entrez:
kubectl config view
Nettoyage
Remettez votre variable d'environnement KUBECONFIG
à sa valeur d'origine.
Par exemple:
Linux
export KUBECONFIG=$KUBECONFIG_SAVED
Windows PowerShell
$Env:KUBECONFIG=$ENV:KUBECONFIG_SAVED
A suivre
5.8.3 - Lister toutes les images de conteneur exécutées dans un cluster
Cette page montre comment utiliser kubectl pour répertorier toutes les images de conteneur pour les pods s'exécutant dans un cluster.
Pré-requis
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:
Pour consulter la version, entrezkubectl version
.
Dans cet exercice, vous allez utiliser kubectl pour récupérer tous les pods exécutés dans un cluster et formater la sortie pour extraire la liste des conteneurs pour chacun.
Répertorier toutes les images de conteneurs dans tous les namespaces
- Récupérez tous les pods dans tous les namespace à l'aide de
kubectl get pods --all-namespaces
- Formatez la sortie pour inclure uniquement la liste des noms d'image de conteneur à l'aide de
-o jsonpath={.items[*].spec.containers[*].image}
. Cela analysera récursivement le champimage
du json retourné.- Voir la reference jsonpath pour plus d'informations sur l'utilisation de jsonpath.
- Formatez la sortie à l'aide des outils standard:
tr
,sort
,uniq
- Utilisez
tr
pour remplacer les espaces par des nouvelles lignes - Utilisez
sort
pour trier les résultats - Utilisez
uniq
pour agréger le nombre d'images
- Utilisez
kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" |\
tr -s '[[:space:]]' '\n' |\
sort |\
uniq -c
La commande ci-dessus renverra récursivement tous les champs nommés image
pour tous les éléments retournés.
Comme alternative, il est possible d'utiliser le chemin absolu vers le champ d'image dans le Pod.
Cela garantit que le champ correct est récupéré même lorsque le nom du champ est répété, par ex. de nombreux champs sont appelés name
dans un élément donné:
kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}"
Le jsonpath est interprété comme suit:
.items[*]
: pour chaque valeur renvoyée.spec
: obtenir les spécifications.containers[*]
: pour chaque conteneur.image
: obtenir l'image
kubectl get pod nginx
, la portion .items[*]
du chemin doit être omis car un seul pod est renvoyé au lieu d'une liste d'éléments.
Liste des images de conteneurs par pod
Le formatage peut être contrôlé davantage en utilisant l'opération range
pour parcourir les éléments individuellement.
kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |\
sort
Filtrage des images de conteneur de liste par label de pod
Pour cibler uniquement les pods correspondant à un label spécifique, utilisez l'indicateur -l.
Les éléments suivants correspondent uniquement aux pods avec les labels app=nginx
.
kubectl get pods --all-namespaces -o=jsonpath="{.items[*].spec.containers[*].image}" -l app=nginx
Filtrage des images de conteneur de liste par namespace de pod
Pour cibler uniquement les pods dans un namespace spécifique, utilisez l'indicateur de namespace.
Ce qui suit correspond uniquement aux pods du namespace kube-system
.
kubectl get pods --namespace kube-system -o jsonpath="{.items[*].spec.containers[*].image}"
Répertorier les images de conteneurs en utilisant un go-template au lieu de jsonpath
Comme alternative à jsonpath, Kubectl peut aussi utiliser les go-templates pour formater la sortie:
kubectl get pods --all-namespaces -o go-template --template="{{range .items}}{{range .spec.containers}}{{.image}} {{end}}{{end}}"
A suivre
Reference
- Guide de référence pour Jsonpath
- Guide de référence pour les Go template
5.9 - Monitoring, Logging et Debugging
5.9.1 - Obtenez un shell dans un conteneur en cours d'exécution
Cette page montre comment utiliser kubectl exec
pour obtenir un shell dans un conteneur en cours d'exécution.
Pré-requis
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:
Pour consulter la version, entrezkubectl version
.
Obtenir un shell dans un conteneur
Dans cet exercice, vous allez créer un pod contenant un conteneur. Le conteneur exécute une image nginx. Voici le fichier de configuration du Pod:
apiVersion: v1
kind: Pod
metadata:
name: shell-demo
spec:
volumes:
- name: shared-data
emptyDir: {}
containers:
- name: nginx
image: nginx
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
hostNetwork: true
dnsPolicy: Default
Créez le Pod:
kubectl apply -f https://k8s.io/examples/application/shell-demo.yaml
Vérifiez que le conteneur est en cours d'exécution:
kubectl get pod shell-demo
Obtenez un shell pour le conteneur en cours d'exécution:
kubectl exec -it shell-demo -- /bin/bash
Dans votre shell, listez le répertoire racine:
root@shell-demo:/# ls /
Dans votre shell, testez d'autres commandes. Voici quelques exemples:
root@shell-demo:/# ls /
root@shell-demo:/# cat /proc/mounts
root@shell-demo:/# cat /proc/1/maps
root@shell-demo:/# apt-get update
root@shell-demo:/# apt-get install -y tcpdump
root@shell-demo:/# tcpdump
root@shell-demo:/# apt-get install -y lsof
root@shell-demo:/# lsof
root@shell-demo:/# apt-get install -y procps
root@shell-demo:/# ps aux
root@shell-demo:/# ps aux | grep nginx
Écriture de la page racine de nginx
Regardez à nouveau le fichier de configuration de votre Pod.
Le pod a un volume emptyDir
et le conteneur monte le volume dans /usr/share/nginx/html
.
Dans votre shell, créez un fichier index.html
dans le répertoire /usr/share/nginx/html
:
root@shell-demo:/# echo Hello shell demo > /usr/share/nginx/html/index.html
Dans votre shell, envoyez une requête GET au serveur nginx:
root@shell-demo:/# apt-get update
root@shell-demo:/# apt-get install curl
root@shell-demo:/# curl localhost
La sortie affiche le texte que vous avez écrit dans le fichier index.html
:
Hello shell demo
Lorsque vous avez terminé avec votre shell, entrez exit
.
Exécution de commandes individuelles dans un conteneur
Dans une fenêtre de commande ordinaire, pas votre shell, répertoriez les variables d'environnement dans le conteneur en cours d'exécution:
kubectl exec shell-demo env
Essayez d'exécuter d'autres commandes. Voici quelques exemples:
kubectl exec shell-demo ps aux
kubectl exec shell-demo ls /
kubectl exec shell-demo cat /proc/1/mounts
Ouverture d'un shell lorsqu'un pod possède plusieurs conteneurs
Si un pod a plusieurs conteneurs, utilisez --container
ou -c
pour spécifier un conteneur dans la commande kubectl exec
.
Par exemple, supposons que vous ayez un pod nommé my-pod et que le pod ait deux conteneurs nommés main-app et helper-app.
La commande suivante ouvrirait un shell sur le conteneur de l'application principale.
kubectl exec -it my-pod --container main-app -- /bin/bash
A suivre
5.10 - Extensions de Kubernetes
5.10.1 - Utilisation des ressources personnalisées
5.11 - TLS
5.12 - Fédération
5.12.1 - Administration du Control Plane de la fédération
5.13 - Gestion des démons du cluster
5.14 - Installation du catalogue de services
6 - Tutoriels
Cette section de la documentation de Kubernetes contient des tutoriels.
Un tutoriel montre comment atteindre un objectif qui est plus grand qu'une simple tâche. Il contient différentes sections, et une section contient différentes étapes.
Avant d'explorer chacun des tutoriels, il peut-être utile de garder un signet pour le Glossaire standardisé pour pouvoir le consulter plus facilement par la suite.
Elémentaires
-
Kubernetes Élémentaire (EN) est un tutoriel interactif en profondeur qui vous aidera à comprendre le système de Kubernetes et de commencer avec des fonctionnalités élémentaires de Kubernetes.
Configuration
Applications Sans États (stateless applications)
-
Exposer une adresse IP externe pour accéder a une application dans un cluster (EN)
-
Exemple: Déployer l'application PHP Guestbook avec Redis (EN)
Applications Avec États (stateful applications)
Clusters
Services
A suivre
Si vous voulez écrire un tutoriel, regardez la section des modèles de page de tutoriel dans l'Utilisation des modèles de pages .
6.1 - Hello Minikube
Ce tutoriel vous montre comment exécuter une simple application Hello World Node.js sur Kubernetes en utilisant Minikube et Katacoda. Katacoda fournit un environnement Kubernetes gratuit dans le navigateur.
Objectifs
- Déployez une application Hello World sur Minikube.
- Lancez l'application.
- Afficher les journaux des applications.
Pré-requis
Ce tutoriel fournit une image de conteneur construite à partir des fichiers suivants :
var http = require('http');
var handleRequest = function(request, response) {
console.log('Received request for URL: ' + request.url);
response.writeHead(200);
response.end('Hello World!');
};
var www = http.createServer(handleRequest);
www.listen(8080);
FROM node:6.14.2
EXPOSE 8080
COPY server.js .
CMD node server.js
Pour plus d'informations sur la commande docker build
, lisez la documentation de Docker.
Créer un cluster Minikube
-
Cliquez sur Lancer le terminal.
Note: Si vous avez installé Minikube localement, lancezminikube start
. -
Ouvrez le tableau de bord Kubernetes dans un navigateur :
minikube dashboard
-
Environnement Katacoda seulement : En haut du volet du terminal, cliquez sur le signe plus, puis cliquez sur Sélectionner le port pour afficher sur l'hôte 1.
-
Environnement Katacoda seulement : Tapez
30000
, puis cliquez sur Afficher le port.
Créer un déploiement
Un Pod Kubernetes est un groupe d'un ou plusieurs conteneurs, liés entre eux à des fins d'administration et de mise en réseau. Dans ce tutoriel, le Pod n'a qu'un seul conteneur. Un Déploiement Kubernetes vérifie l'état de santé de votre Pod et redémarre le conteneur du Pod s'il se termine. Les déploiements sont le moyen recommandé pour gérer la création et la mise à l'échelle des Pods.
-
Utilisez la commande
kubectl create
pour créer un déploiement qui gère un Pod. Le Pod utilise un conteneur basé sur l'image Docker fournie.kubectl create deployment hello-node --image=k8s.gcr.io/echoserver:1.4
-
Affichez le déploiement :
kubectl get deployments
Sortie :
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE hello-node 1 1 1 1 1m
-
Voir le Pod :
kubectl get pods
Sortie :
NAME READY STATUS RESTARTS AGE hello-node-5f76cf6ccf-br9b5 1/1 Running 0 1m
-
Afficher les événements du cluster :
kubectl get events
-
Voir la configuration de
kubectl
:kubectl config view
Note: Pour plus d'informations sur les commandes.kubectl
, voir la vue d'ensemble de kubectl
Créer un service
Par défaut, le Pod n'est accessible que par son adresse IP interne dans le cluster Kubernetes.
Pour rendre le conteneur hello-node
accessible depuis l'extérieur du réseau virtuel Kubernetes, vous devez exposer le Pod comme un Service Kubernetes.
-
Exposez le Pod à internet en utilisant la commande
kubectl expose
:kubectl expose deployment hello-node --type=LoadBalancer --port=8080
L'indicateur
--type=LoadBalancer
indique que vous voulez exposer votre Service à l'extérieur du cluster. -
Affichez le Service que vous venez de créer :
kubectl get services
Sortie :
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-node LoadBalancer 10.108.144.78 <pending> 8080:30369/TCP 21s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 23m
Sur les fournisseurs de cloud qui supportent les load balancers, une adresse IP externe serait fournie pour accéder au Service. Sur Minikube, le type
LoadBalancer
rend le Service accessible via la commandeminikube service
. -
Exécutez la commande suivante :
minikube service hello-node
-
Environnement Katacoda seulement : Cliquez sur le signe plus, puis cliquez sur Sélectionner le port pour afficher sur l'hôte 1.
-
Environnement Katacoda seulement : Tapez
30369
(voir port en face de8080
dans la sortie services), puis cliquez sur Afficher le port.Cela ouvre une fenêtre de navigateur qui sert votre application et affiche le message
Hello World
.
Activer les extensions
Minikube dispose d'un ensemble d'extensions intégrées qui peuvent être activées, désactivées et ouvertes dans l'environnement Kubernetes local.
-
Énumérer les extensions actuellement pris en charge :
minikube addons list
Sortie:
addon-manager: enabled coredns: disabled dashboard: enabled default-storageclass: enabled efk: disabled freshpod: disabled heapster: disabled ingress: disabled kube-dns: enabled metrics-server: disabled nvidia-driver-installer: disabled nvidia-gpu-device-plugin: disabled registry: disabled registry-creds: disabled storage-provisioner: enabled
-
Activez une extension, par exemple,
heapster
:minikube addons enable heapster
Sortie :
heapster was successfully enabled
-
Affichez le pod et le service que vous venez de créer :
kubectl get pod,svc -n kube-system
Sortie :
NAME READY STATUS RESTARTS AGE pod/heapster-9jttx 1/1 Running 0 26s pod/influxdb-grafana-b29w8 2/2 Running 0 26s pod/kube-addon-manager-minikube 1/1 Running 0 34m pod/kube-dns-6dcb57bcc8-gv7mw 3/3 Running 0 34m pod/kubernetes-dashboard-5498ccf677-cgspw 1/1 Running 0 34m pod/storage-provisioner 1/1 Running 0 34m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/heapster ClusterIP 10.96.241.45 <none> 80/TCP 26s service/kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 34m service/kubernetes-dashboard NodePort 10.109.29.1 <none> 80:30000/TCP 34m service/monitoring-grafana NodePort 10.99.24.54 <none> 80:30002/TCP 26s service/monitoring-influxdb ClusterIP 10.111.169.94 <none> 8083/TCP,8086/TCP 26s
-
Désactivez
heapster
:minikube addons disable heapster
Sortie :
heapster was successfully disabled
Nettoyage
Vous pouvez maintenant nettoyer les ressources que vous avez créées dans votre cluster :
kubectl delete service hello-node
kubectl delete deployment hello-node
Si nécessaire, arrêtez la machine virtuelle Minikube (VM) :
minikube stop
Si nécessaire, effacez la VM Minikube :
minikube delete
A suivre
- En savoir plus sur les déploiement.
- En savoir plus sur le Déploiement d'applications.
- En savoir plus sur les Services.
6.2 - Apprendre les bases de Kubernetes
Les bases de Kubernetes
Ce tutoriel offre une présentation des bases du système d’orchestration de cluster Kubernetes. Chaque module contient des informations de base sur les principales caractéristiques et concepts de Kubernetes, ainsi qu'un didacticiel en ligne interactif. Ces tutoriels interactifs vous permettent de gérer vous-même un cluster simple et ses applications conteneurisées.
À l'aide des didacticiels interactifs, vous pouvez apprendre à:
- Déployer une application conteneurisée sur un cluster
- Passage à l'échelle du déploiement
- Mettre à jour l'application conteneurisée avec une nouvelle version du logiciel
- Déboguer l'application conteneurisée
Les didacticiels utilisent Katacoda pour exécuter un navigateur virtuel dans votre navigateur Web, qui exécute Minikube, un déploiement local à petite échelle de Kubernetes pouvant être exécuté n’importe où. Il n'est pas nécessaire d'installer un logiciel ou de configurer quoi que ce soit; chaque didacticiel interactif s’exécute directement à partir de votre navigateur Web.
Qu'est-ce que Kubernetes peut faire pour vous?
Avec les services Web modernes, les utilisateurs s'attendent à ce que les applications soient disponibles 24 heures sur 24, 7 jours sur 7 et les développeurs prévoient de déployer de nouvelles versions de ces applications plusieurs fois par jour. La conteneurisation aide les progiciels à atteindre ces objectifs, en permettant aux applications d'être publiées et mises à jour de manière simple et rapide sans temps d'arrêt. Kubernetes vous aide à vous assurer que ces applications conteneurisées s'exécutent où et quand vous le souhaitez, et les aide à trouver les ressources et les outils dont elles ont besoin pour travailler. Kubernetes est une plate-forme open source prête pour la production, conçue avec l'expérience accumulée de Google dans l'orchestration de conteneurs, associée aux meilleures idées de la communauté.
6.2.1 - Créer un cluster
6.2.1.1 - Utiliser Minikube pour créer un cluster
Objectifs
- Découvrez ce qu'est un cluster Kubernetes.
- Apprenez ce qu'est Minikube.
- Démarrez un cluster Kubernetes à l'aide d'un terminal en ligne.
Kubernetes Clusters
Kubernetes coordonne un groupe d'ordinateurs hautement disponibles qui sont connectés pour fonctionner comme une seule et même unité. Les abstractions de Kubernetes vous permettent de déployer des applications conteneurisées dans un cluster sans les lier spécifiquement à des ordinateurs individuels. Pour utiliser ce nouveau modèle de déploiement, les applications doivent être empaquetées de manière à les dissocier des hôtes individuels: elles doivent être conteneurisées. Les applications conteneurisées sont plus flexibles et disponibles que dans les modèles de déploiement précédents, dans lesquels les applications étaient installées directement sur des machines spécifiques sous la forme de packages profondément intégrés à l'hôte. Kubernetes automatise plus efficacement la distribution et la planification des conteneurs d'applications dans un cluster. Kubernetes est une plate-forme open source prête pour la production.
Un cluster Kubernetes est constitué de deux types de ressources:
- Le maître coordonne le cluster.
- Les nœuds sont les serveurs qui exécutent des applications.
Sommaire:
- Kubernetes cluster
- Minikube
Kubernetes est une plate-forme open source pour la production qui orchestre le placement (planification) et l'exécution de conteneurs d'applications à l'intérieur et à travers des clusters d'ordinateur.
Schéma du Cluster
Le maître est responsable de la gestion du cluster. Le maître coordonne toutes les activités de votre cluster, telles que la planification des applications, la gestion de l'état souhaité des applications, la mise à l'échelle des applications et le déploiement de nouvelles mises à jour.
Un nœud est une machine virtuelle ou un ordinateur physique servant d’ordinateur de travail dans un cluster Kubernetes. Chaque nœud est doté d’un Kubelet, qui est un agent permettant de gérer le nœud et de communiquer avec le maître Kubernetes. Le nœud doit également disposer d'outils permettant de gérer les opérations de conteneur, telles que Docker ou rkt. Un cluster Kubernetes qui gère le trafic de production doit comporter au moins trois nœuds.
Les maîtres gèrent le cluster et les nœuds sont utilisés pour héberger les applications en cours d'exécution.
Lorsque vous déployez des applications sur Kubernetes, vous indiquez au maître de démarrer les conteneurs d'applications. Le maître planifie l'exécution des conteneurs sur les nœuds du cluster. Les nœuds communiquent avec le maître à l'aide de l'API Kubernetes , que le maître expose. Les utilisateurs finaux peuvent également utiliser l'API Kubernetes directement pour interagir avec le cluster.
Un cluster Kubernetes peut être déployé sur des machines physiques ou virtuelles. Pour démarrer avec le développement de Kubernetes, vous pouvez utiliser Minikube. Minikube est une implémentation Kubernetes légère qui crée une machine virtuelle sur votre machine locale et déploie un cluster simple contenant un seul nœud. Minikube est disponible pour les systèmes Linux, macOS et Windows. La CLI Minikube fournit des opérations d’amorçage de base permettant d’utiliser votre cluster, notamment les fonctions de démarrage, d’arrêt, de statut et de suppression. Pour ce tutoriel, toutefois, vous utiliserez un terminal en ligne fourni avec Minikube pré-installé.
Maintenant que vous savez ce qu'est Kubernetes, allons au didacticiel en ligne et commençons notre premier cluster!
6.2.1.2 - Didacticiel interactif - Création d'un cluster
6.2.2 - Déployer une application
6.2.2.1 - Utiliser kubectl pour créer un déploiement
Objectifs
- En savoir plus sur les déploiements d'applications.
- Déployez votre première application sur Kubernetes avec kubectl.
Déploiements Kubernetes
Une fois que vous avez un cluster Kubernetes en cours d'exécution, vous pouvez déployer vos applications conteneurisées par dessus. Pour ce faire, vous créez une configuration de Déploiement (Deployments) Kubernetes. Le déploiement instruit Kubernetes de comment créer et mettre à jour des instances de votre application. Une fois que vous avez créé un déploiement, le plannificateur de Kubernetes (kube-scheduler) planifient les instanciations d'application sur des nœuds du cluster.
Une fois les instances d’application créées, un contrôleur de déploiement Kubernetes surveille en permanence ces instances. Si le nœud hébergeant une instance tombe en panne ou est supprimé, le contrôleur de déploiement remplace l'instance par une instance située sur un autre nœud du cluster. Ceci fournit un mécanisme d'auto-réparation pour faire face aux pannes ou à la maintenance de la machine.
Dans le monde de pré-orchestration, les scripts d'installation étaient souvent utilisés pour démarrer des applications, mais ils ne permettaient pas une récupération après une panne d'ordinateur. En créant et en maintenant vos instances d’application sur plusieurs nœuds, les Déploiements Kubernetes offre une approche fondamentalement différente de la gestion des applications.
Sommaire:
- Déploiements
- Kubectl
Un déploiement est responsable de la création et de la mise à jour des instances de votre application.
Déploiement de votre première application sur Kubernetes
Vous pouvez créer et gérer un déploiement à l'aide de l'interface de ligne de commande, Kubectl.
Kubectl utilise l'API Kubernetes pour interagir avec le cluster. Dans ce module, vous apprendrez les commandes Kubectl les plus courantes nécessaires à la création de déploiements exécutant vos applications sur un cluster Kubernetes.
Lorsque vous créez un déploiement, vous devez spécifier l'image de conteneur de votre application et le nombre de réplicas que vous souhaitez exécuter. Vous pouvez modifier ces informations ultérieurement en mettant à jour votre déploiement.; Modules 5 et 6 du bootcamp, expliquez comment vous pouvez faire évoluer et mettre à jour vos déploiements.
Les applications doivent être regroupées dans l’un des formats de conteneur pris en charge pour pouvoir être déployées sur Kubernetes.
Pour notre premier déploiement, nous utiliserons une application Node.js intégrée dans un conteneur Docker. Pour créer l'application Node.js et déployer le conteneur Docker, suivez les instructions du Tutoriel Hello Minikube.
Maintenant que vous savez ce que sont les déploiements, allons au didacticiel en ligne et déployons notre première application!
6.2.2.2 - Tutoriel interactif - Déploiement d'une application
6.2.3 - Explorez vos applications
6.2.4 - Rendre publique votre application
6.2.5 - Mise à l'échelle des applications
6.2.6 - Mise à jour des applications
6.3 - Formations en ligne
6.4 - Configuration
6.5 - Applications sans états
6.6 - Applications avec états
6.7 - Clusters
6.8 - Services
7 - Documents de Référence
Cette section de la documentation de Kubernetes contient les informations de références.
Documents de Référence de l'API
- Vue d'ensemble de l'API de Kubernetes
- Documentation de référence de l'API de Kubernetes par version:
Bibliothèques client de l'API
Pour appeler l'API de Kubernetes depuis un langage de programmation on peut utiliser une bibliothèque client. Les bibliothèques client officiellement supportées sont:
- Kubernetes Go client library
- Kubernetes Python client library
- Kubernetes Java client library
- Kubernetes JavaScript client library
Documents de Référence des outils en ligne de commande (CLI)
- kubectl - Principal outil en ligne de commande (CLI) pour exécuter et gérer un cluster Kubernetes.
- JSONPath - Guide de la syntaxe des expressions JSONPath avec kubectl.
- kubeadm - Outil en ligne de commande (CLI) pour provisionner facilement un cluster Kubernetes sécurisé.
- kubefed - Outil en ligne de commande (CLI) pour aider à administrer des clusters fédérés.
Documents de Référence pour la configuration
- kubelet - Le principal agent qui s'exécute sur chaque noeud. Kubelet prends un ensemble de PodSpecs et s'assure que les conteneurs qui y sont décrit s'exécutent correctement.
- kube-apiserver - L'API REST qui valide et configure les données des objects de l'API tels que les Pods, Services, Deployments ...
- kube-controller-manager - Démon en charge de la principale boucle de régulation (core control loop) de Kubernetes.
- kube-proxy - S'occupe de reacheminer (forwarding) simplement les flux TCP/UDP ou bien en utilisant un Round-Robin sur un ensemble de back-ends.
- kube-scheduler - Ordonnanceur (scheduler) qui gère la disponibilité, la performance et la capacité.
- federation-apiserver - Serveur API pour les clusters fédérés.
- federation-controller-manager - Démon en charge de la boucle de régulation (core control loop) d'une fédération de clusters Kubernetes.
Documents de Conception
7.1 - Glosarium
7.2 - Problèmes et alertes de sécurité de Kubernetes
7.3 - Utilisation de l'API Kubernetes
7.4 - Accéder à l'API
7.5 - Référence de l'API
7.6 - Référence des outils d'installation
7.6.1 - Kubeadm
7.6.1.1 - Aperçu de kubeadm
Kubeadm est un outil conçu afin que les commandes kubeadm init
et kubeadm join
soient la meilleure façon de créer rapidement des clusters Kubernetes.
Kubeadm effectue les actions nécessaires afin d'obtenir un cluster minimal mais fonctionnel et en état de marche. Son objectif est d'assembler le cluster sans pour autant provisioner les machines qui le composent. De la même façon, kubeadm ne supporte pas l'installation des extensions habituelles comme le Dashboard (tableau de bord), les solutions de surveillance ou bien encore les extensions spécifiques aux fournisseurs cloud.
On préférera des outils plus spécifiques et de plus haut niveau, construits autour de kubeadm, et qui, idéalement, utiliseront kubeadm comme base de déploiement afin de créer facilement des clusters conformes.
Prochaines étapes
- kubeadm init pour assembler un noeud Kubernetes control-plane
- kubeadm join pour assembler un noeud Kubernetes worker node et le joindre au cluster
- kubeadm upgrade pour mettre à jour un cluster Kubernetes vers une version plus récente
- kubeadm config si vous avez initialisé votre cluster en utilisant kubeadm v1.7.x ou antérieur, pour configurer votre cluster avec
kubeadm upgrade
- kubeadm token pour gérer vos jetons avec
kubeadm join
- kubeadm reset pour annuler des changements faits avec
kubeadm init
oukubeadm join
à cet hôte - kubeadm version pour afficher la version de kubeadm
- kubeadm alpha pour utiliser un lot de fonctionnalités rendus disponibles afin d'obtenir le retour de la communauté
7.6.1.2 - Kubeadm généré
7.6.1.2.1 -
Utilisez cette commande afin de configurer le control plane Kubernetes
Synopsis
Utilisez cette commande afin de configurer le control plane Kubernetes
La commande "init" exécute les phases suivantes :
preflight Exécute les vérifications en amont
kubelet-start Sauvegarde les réglages kubelet et (re)démarre kubelet
certs Génération de certificats
/etcd-ca Génère le certificat CA auto signé pour fournir les identités à etcd
/apiserver-etcd-client Génère le certificat que l'apiserver utilisera pour communiquer avec etcd
/etcd-healthcheck-client Génère le certificat pour les sondes de vivacité (liveness) qui contrôlent etcd
/etcd-server Génère le certificat pour l'accès à etcd
/etcd-peer Génère le certificat pour que les noeuds etcd puissent communiquer ensemble
/ca Génère le certificat CA auto signé de Kubernetes pour fournir les identités aux autres composants Kubernetes
/apiserver Génère le certificat pour l'accès à l'API Kubernetes
/apiserver-kubelet-client Génère le certificat pour permettre à l'API server de se connecter à kubelet
/front-proxy-ca Génère le certificat CA auto signé pour fournir les identités au proxy frontal (front proxy)
/front-proxy-client Génère le certificat pour le client du proxy frontal
/sa Génère une clef privée pour signer les jetons ainsi que la clef publique du compte service
kubeconfig Génère tous les fichiers kubeconfig nécessaires pour la création du control plane et du fichier kubeconfig admin
/admin Génère un fichier kubeconfig pour utilisation par l'administrateur et kubeadm
/kubelet Génère un fichier kubeconfig pour utilisation par kubelet seulement à des fins d'installation initiale
/controller-manager Génère un fichier fichier kubeconfig for the controller manager to use
/scheduler Génère un fichier kubeconfig pour utilisation par le scheduler
control-plane Génère tous les manifests de Pod statiques nécessaires à la création du control plane
/apiserver Génère le manifest de Pod statique de l'apiserver
/controller-manager Génère le manifest de Pod statique du kube-controller-manager
/scheduler Génère le manifest de Pod statique du kube-schedule
etcd Génère le manifest de Pod statique pour l'etcd local
/local Génère le manifest de Pod statique pour une instance etcd locale, à un seul noeud
upload-config Téléverse les configurations kubeadm et kubelet vers une ConfigMap
/kubeadm Téléverse la ClusterConfiguration de kubeadm vers une ConfigMap
/kubelet Téléverse la configuration kubelet vers une ConfigMap
upload-certs Téléverse les certificats vers kubeadm-certs
mark-control-plane Marque un noeud en tant que control-plane
bootstrap-token Génère les jetons d'installation utilisés pour faire joindre un noeud à un cluster
addon Installe les extensions requises pour l'exécution des tests de Conformance
/coredns Installe l'extension CoreDNS à un cluster Kubernetes
/kube-proxy Installe l'extension kube-proxy à un cluster Kubernetes
kubeadm init [flags]
Options
--apiserver-advertise-address string L'adresse IP que l'API Server utilisera pour s'annoncer. Si non spécifiée, l'interface réseau par défaut sera utilisée.
--apiserver-bind-port int32 Port d'écoute de l'API Server. (par default 6443)
--apiserver-cert-extra-sans strings Noms alternatifs (Subject Alternative Names ou encore SANs) optionnels, utilisés dans les certificats servis par l'API Server. Peuvent êtres des adresses IPs ou des noms DNS.
--cert-dir string Le répertoire où sauvegarder les certificats. (par défaut "/etc/kubernetes/pki")
--certificate-key string Clef utilisée pour chiffrer les certificats control-plane dans le Secret the kubeadm-certs.
--config string Chemin vers un fichier de configuration kubeadm.
--cri-socket string Chemin vers la socket CRI à laquelle la connexion doit s'effectuer. S'il n'est pas spécifié, kubeadm essaiera de le détecter; utiliser cette option seulement si vous avez plus d'un CRI installé ou si vous utilisez des sockets CRI non standard.
--dry-run N'effectue aucun changement; affiche seulement la sortie standard de ce qui serait effectué.
--feature-gates string Un ensemble de paires clef=valeur qui décrivent l'entrée de configuration pour des fonctionnalités diverses. Il n'y en a aucune dans cette version.
-h, --help aide pour l'initialisation (init)
--ignore-preflight-errors strings Une liste de contrôles dont les erreurs seront catégorisées comme "warnings" (avertissements). Par exemple : 'IsPrivilegedUser,Swap'. La valeur 'all' ignore les erreurs de tous les contrôles.
--image-repository string Choisis un container registry d'où télécharger les images du control plane. (par défaut "k8s.gcr.io")
--kubernetes-version string Choisis une version Kubernetes spécifique pour le control plane. (par défaut "stable-1")
--node-name string Spécifie le nom du noeud.
--pod-network-cidr string Spécifie l'intervalle des adresses IP pour le réseau des pods. Si fournie, le control plane allouera automatiquement les CIDRs pour chacun des noeuds.
--service-cidr string Utilise un intervalle différent pour les adresses IP des services prioritaires (VIPs). (par défaut "10.96.0.0/12")
--service-dns-domain string Utilise un domaine alternatif pour les services, par exemple : "myorg.internal". (par défaut "cluster.local")
--skip-certificate-key-print N'affiche pas la clef utilisée pour chiffrer les certificats du control-plane.
--skip-phases strings List des des phases à sauter
--skip-token-print N'affiche pas le jeton par défaut de l'installation qui a été généré lors de 'kubeadm init'.
--token string Le jeton à utiliser pour établir la confiance mutuelle entre les noeuds et les noeuds du control-plane. Le format correspond à la regexp : [a-z0-9]{6}\.[a-z0-9]{16} - par exemple : abcdef.0123456789abcdef
--token-ttl duration La durée au bout de laquelle le jeton sera automatiquement détruit (par exemple : 1s, 2m, 3h). Si réglée à '0', le jeton n'expirera jamais (par défaut 24h0m0s)
--upload-certs Téléverse les certificats du control-plane vers le Secret kubeadm-certs.
Options héritées depuis la commande parent
--rootfs string [EXPERIMENTALE] Le chemin vers la "vraie" racine du système de fichiers de l'hôte.
7.6.1.3 - kubeadm init
Cette commande initialise un noeud Kubernetes control-plane.
Utilisez cette commande afin de configurer le control plane Kubernetes
Synopsis
Utilisez cette commande afin de configurer le control plane Kubernetes
La commande "init" exécute les phases suivantes :
preflight Exécute les vérifications en amont
kubelet-start Sauvegarde les réglages kubelet et (re)démarre kubelet
certs Génération de certificats
/etcd-ca Génère le certificat CA auto signé pour fournir les identités à etcd
/apiserver-etcd-client Génère le certificat que l'apiserver utilisera pour communiquer avec etcd
/etcd-healthcheck-client Génère le certificat pour les sondes de vivacité (liveness) qui contrôlent etcd
/etcd-server Génère le certificat pour l'accès à etcd
/etcd-peer Génère le certificat pour que les noeuds etcd puissent communiquer ensemble
/ca Génère le certificat CA auto signé de Kubernetes pour fournir les identités aux autres composants Kubernetes
/apiserver Génère le certificat pour l'accès à l'API Kubernetes
/apiserver-kubelet-client Génère le certificat pour permettre à l'API server de se connecter à kubelet
/front-proxy-ca Génère le certificat CA auto signé pour fournir les identités au proxy frontal (front proxy)
/front-proxy-client Génère le certificat pour le client du proxy frontal
/sa Génère une clef privée pour signer les jetons ainsi que la clef publique du compte service
kubeconfig Génère tous les fichiers kubeconfig nécessaires pour la création du control plane et du fichier kubeconfig admin
/admin Génère un fichier kubeconfig pour utilisation par l'administrateur et kubeadm
/kubelet Génère un fichier kubeconfig pour utilisation par kubelet seulement à des fins d'installation initiale
/controller-manager Génère un fichier fichier kubeconfig for the controller manager to use
/scheduler Génère un fichier kubeconfig pour utilisation par le scheduler
control-plane Génère tous les manifests de Pod statiques nécessaires à la création du control plane
/apiserver Génère le manifest de Pod statique de l'apiserver
/controller-manager Génère le manifest de Pod statique du kube-controller-manager
/scheduler Génère le manifest de Pod statique du kube-schedule
etcd Génère le manifest de Pod statique pour l'etcd local
/local Génère le manifest de Pod statique pour une instance etcd locale, à un seul noeud
upload-config Téléverse les configurations kubeadm et kubelet vers une ConfigMap
/kubeadm Téléverse la ClusterConfiguration de kubeadm vers une ConfigMap
/kubelet Téléverse la configuration kubelet vers une ConfigMap
upload-certs Téléverse les certificats vers kubeadm-certs
mark-control-plane Marque un noeud en tant que control-plane
bootstrap-token Génère les jetons d'installation utilisés pour faire joindre un noeud à un cluster
addon Installe les extensions requises pour l'exécution des tests de Conformance
/coredns Installe l'extension CoreDNS à un cluster Kubernetes
/kube-proxy Installe l'extension kube-proxy à un cluster Kubernetes
kubeadm init [flags]
Options
--apiserver-advertise-address string L'adresse IP que l'API Server utilisera pour s'annoncer. Si non spécifiée, l'interface réseau par défaut sera utilisée.
--apiserver-bind-port int32 Port d'écoute de l'API Server. (par default 6443)
--apiserver-cert-extra-sans strings Noms alternatifs (Subject Alternative Names ou encore SANs) optionnels, utilisés dans les certificats servis par l'API Server. Peuvent êtres des adresses IPs ou des noms DNS.
--cert-dir string Le répertoire où sauvegarder les certificats. (par défaut "/etc/kubernetes/pki")
--certificate-key string Clef utilisée pour chiffrer les certificats control-plane dans le Secret the kubeadm-certs.
--config string Chemin vers un fichier de configuration kubeadm.
--cri-socket string Chemin vers la socket CRI à laquelle la connexion doit s'effectuer. S'il n'est pas spécifié, kubeadm essaiera de le détecter; utiliser cette option seulement si vous avez plus d'un CRI installé ou si vous utilisez des sockets CRI non standard.
--dry-run N'effectue aucun changement; affiche seulement la sortie standard de ce qui serait effectué.
--feature-gates string Un ensemble de paires clef=valeur qui décrivent l'entrée de configuration pour des fonctionnalités diverses. Il n'y en a aucune dans cette version.
-h, --help aide pour l'initialisation (init)
--ignore-preflight-errors strings Une liste de contrôles dont les erreurs seront catégorisées comme "warnings" (avertissements). Par exemple : 'IsPrivilegedUser,Swap'. La valeur 'all' ignore les erreurs de tous les contrôles.
--image-repository string Choisis un container registry d'où télécharger les images du control plane. (par défaut "k8s.gcr.io")
--kubernetes-version string Choisis une version Kubernetes spécifique pour le control plane. (par défaut "stable-1")
--node-name string Spécifie le nom du noeud.
--pod-network-cidr string Spécifie l'intervalle des adresses IP pour le réseau des pods. Si fournie, le control plane allouera automatiquement les CIDRs pour chacun des noeuds.
--service-cidr string Utilise un intervalle différent pour les adresses IP des services prioritaires (VIPs). (par défaut "10.96.0.0/12")
--service-dns-domain string Utilise un domaine alternatif pour les services, par exemple : "myorg.internal". (par défaut "cluster.local")
--skip-certificate-key-print N'affiche pas la clef utilisée pour chiffrer les certificats du control-plane.
--skip-phases strings List des des phases à sauter
--skip-token-print N'affiche pas le jeton par défaut de l'installation qui a été généré lors de 'kubeadm init'.
--token string Le jeton à utiliser pour établir la confiance mutuelle entre les noeuds et les noeuds du control-plane. Le format correspond à la regexp : [a-z0-9]{6}\.[a-z0-9]{16} - par exemple : abcdef.0123456789abcdef
--token-ttl duration La durée au bout de laquelle le jeton sera automatiquement détruit (par exemple : 1s, 2m, 3h). Si réglée à '0', le jeton n'expirera jamais (par défaut 24h0m0s)
--upload-certs Téléverse les certificats du control-plane vers le Secret kubeadm-certs.
Options héritées depuis la commande parent
--rootfs string [EXPERIMENTALE] Le chemin vers la "vraie" racine du système de fichiers de l'hôte.
Séquence d'initialisation
kubeadm init
assemble un noeud Kubernetes control-plane en effectuant les étapes suivantes :
-
Exécute une série de contrôles pour valider l'état du système avant d'y apporter des changements. Certaines validations peuvent émettre seulement des avertissements (warnings), d'autres peuvent générer des erreurs qui forceront l'interruption de kubeadm jusqu'à ce que le problème soit résolu ou jusqu'à ce que l'utilisateur spécifie
--ignore-preflight-errors=<list-des-erreurs>
. -
Génère une autorité de certification (CA) auto signée (ou utilise une existante si spécifiée) pour installer les identités de chaque composant du cluster. Si l'utilisateur a fourni son propre certificat et/ou clef de CA en le (la) copiant dans le répertoire des certificats, configuré avec
--cert-dir
(/etc/kubernetes/pki
par défaut) cette étape est sautée comme expliqué dans le document utiliser ses propres certificats. Les certificats de l'API Server auront des entrées SAN additionnelles pour chaque argument--apiserver-cert-extra-sans
. -
Ecrit les fichiers kubeconfig dans
/etc/kubernetes/
pour kubelet, le controller-manager et l'ordonnanceur (scheduler) qui seront utlisés pour les connexions à l'API server, chacun avec sa propre identité, ainsi qu'un fichier kubeconfig supplémentaire pour l'administration, nomméadmin.conf
. -
Génère des manifestes statiques de Pod pour l'API server, le controller manager et l'ordonnanceur. Au cas où aucun etcd externe n'est fourni, un manifeste statique de Pod pour etcd est généré.
Les manifestes statiques de Pod sont écrits dans
/etc/kubernetes/manifestes
; kubelet surveille ce répertoire afin que les Pods soient créés au démarrage.Dès lors que les pods de control-plane sont démarrés, la séquence de
kubeadm init
peut alors continuer. -
Applique les étiquettes (labels) et marques (taints) au noeud control-plane afin qu'aucune charge de travail additionnelle ne s'y exécute.
-
Génère le jeton que les noeuds additionnels peuvent utiliser pour s'enregistrer avec un control-plane. Il est possible que l'utilisateur fournisse un jeton en utilisant
--token
, comme décrit dans la documentation à propos du jeton kubeadm. -
Produit tous les fichiers de configuration requis pour autoriser les noeuds à rejoindre le cluster avec les jetons d'assemblage et le mécanisme d'assemblage TLS :
-
Ecrit une ConfigMap pour produire toute la configuration nécessaire pour rejoindre le cluster et installer les règles d'accès RBAC sous jacentes.
-
Permet aux jetons d'assemblage d'accéder à l'API CSR (Certificate Signing Request, requête de signature de certificat).
-
Configure l'acceptation automatique des nouvelles requêtes CSR.
Voir kubeadm join pour de l'information complémentaire.
-
-
Installe un serveur DNS (CoreDNS) et les modules de l'extension kube-proxy en utilisant l'API Server. Dans la version 1.11 (et au delà) de Kubernetes, CoreDNS est le serveur DNS par défaut. Pour installer kube-dns au lieu de CoreDNS, l'extension DNS doit être configurée dans la
ClusterConfiguration
de kubeadm. Pour plus d'information, se référer à la section ci-dessous intitulée :Utiliser kubeadm init avec un fichier de configuration
. Vous remarquerez que bien que le serveur DNS soit déployé, il ne sera pas programmé pour exécution avant que le CNI soit installé.
Utiliser les phases d'initialisation avec kubeadm
Kubeadm vous permet de créer un noeud de type control-plane en plusieurs phases. Dans 1.13 la commande kubeadm init phase
a été promue GA (disponibilité générale) alors que précédemment ce n'était qu'une commande alpha : kubeadm alpha phase
.
Pour voir la liste des phases et sous phases dans l'ordre, vous pouvez utiliser kubeadm init --help
. La liste sera affichée en haut de l'écran d'aide et chaque phase aura une description associée.
Bon à savoir : en appelant kubeadm init
toutes les phases et sous phases seront executées dans cet ordre.
Certaines phases ont des options uniques, si vous désirez consulter la liste de ces options, ajoutez --help
, par exemple :
sudo kubeadm init phase control-plane controller-manager --help
Vous pouvez aussi utiliser --help
pour voir la liste des sous-phases pour une phase parent :
sudo kubeadm init phase control-plane --help
kubeadm init
a aussi une option nommée --skip-phases
qui peut être utilisée pour passer outre. Cette option accepte une liste de noms de phases, qui peuvent être retrouvées à partir de la liste ordonée précédente.
Par exemple :
sudo kubeadm init phase control-plane all --config=configfile.yaml
sudo kubeadm init phase etcd local --config=configfile.yaml
# vous pouvez modifier les fichiers manifestes du control-plane et d'etcd
sudo kubeadm init --skip-phases=control-plane,etcd --config=configfile.yaml
Cet exemple écrirait les fichiers manifestes pour le control plane et etcd dans /etc/kubernetes/manifestes
à partir de la configuration dans configfile.yaml
. Cela permet de modifier les fichiers et d'ensuite sauter ces phases en utilisant --skip-phases
. En invoquant la dernière commande, vous créerez un noeud de type control plane avec les les fichiers manifestes personnalisés.
Utiliser kubeadm init avec un fichier de configuration
C'est possible de configurer kubeadm init
avec un fichier de configuration plutôt qu'avec des options en ligne de commande, et certaines fonctionnalités avancées sont d'ailleurs uniquement disponibles en tant qu'options du fichier de configuration. Ce fichier est passé à kubeadm avec l'option --config
.
Dans Kubernetes 1.11 et au delà, la configuration par défaut peut être affichée en utilisant la commande kubeadm config print.
Il est recommandé que vous migriez votre configuration v1alpha3
vers v1beta1
en utilisant
la commande kubeadm config migrate,
car le support de v1alpha3
sera supprimé dans Kubernetes 1.15.
Pour plus de détails à propos de chaque option de la configuration v1beta1
vous pouvez consulter la
référence de l'API.
Ajouter des paramètres kube-proxy
Pour de l'information à propos des paramètres kube-proxy dans la configuration kubeadm, se référer à : kube-proxy
Pour de l'information sur comment activer le mode IPVS avec kubeadm, se référer à : IPVS
Passer des options personnalisées aux composants du control plane
Pour de l'information sur comment passer des options aux composants du control plane, se référer à : control-plane-flags
Utiliser des images personnalisées
Par défaut, kubeadm télécharge les images depuis k8s.gcr.io
, à moins que la version demandée de Kubernetes soit une version Intégration Continue (CI). Dans ce cas, gcr.io/k8s-staging-ci-images
est utilisé.
Vous pouvez outrepasser ce comportement en utilisant kubeadm avec un fichier de configuration. Les personnalisations permises sont :
- fournir un
imageRepository
à utiliser à la place dek8s.gcr.io
. - régler
useHyperKubeImage
àtrue
pour utiliser l'image HyperKube. - fournir un
imageRepository
et unimageTag
pour etcd et l'extension (add-on) DNS.
Notez que le champ de configurtation kubernetesVersion
ou l'option ligne de commande --kubernetes-version
affectent la version des images.
Utiliser des certificats personnalisés
Par défaut, kubeadm génère tous les certificats requis pour que votre cluster fonctionne. Vous pouvez outrepasser ce comportement en fournissant vos propres certificats.
Pour ce faire, vous devez les placer dans le répertoire spécifié via l'option --cert-dir
ou spécifié via la propriété CertificatesDir
de votre fichier de configuration.
Par défaut, le répertoire est /etc/kubernetes/pki
.
S'il existe un certificat et une clef privée dans ce répertoire, alors kubeadm sautera l'étape de génération et les fichiers fournis seront utilisés.
Cela signifie que vous pouvez, par exemple, copier un CA (Certificate Authority) existant vers /etc/kubernetes/pki/ca.crt
et /etc/kubernetes/pki/ca.key
, et kubeadm utilisera ce CA pour signer le reste des certificats.
Mode CA externe
Il est aussi possible de fournir seulement le fichier ca.crt
sans le fichier
ca.key
(seulement dans le cas d'un fichier CA racine, pas pour d'autres paires de certificats).
Si tous les certificats et fichiers kubeconfig sont en place, kubeadm activera le mode "CA externe".
Kubeadm continuera sans clef CA locale.
Ou alors, vous pouvez utiliser l'outil controller-manager avec --controllers=csrsigner
en fournissant les emplacements du certificat CA et la clef.
Gérer le fichier kubeadm ad-hoc pour kubelet
Le paquet kubeadm vient avec de la configuration concernant comment kubelet doit se comporter.
Vous remarquerez que la commande CLI kubeadm
ne modifiera jamais ce fichier.
Ce fichier ad-hoc appartient au paquet deb/rpm de kubeadm.
Pour en savoir plus sur comment kubeadm gère kubelet, vous pouvez consulter cette page.
Utilisation de kubeadm avec des runtimes CRI
Depuis la version v1.6.0, Kubernetes a rendu possible par défaut l'utilisation de CRI, Container Runtime Interface.
Le runtime utilisé par défaut est Docker, activé à travers l'adaptateur fourni dockershim
, une implémentation CRI, à l'intérieur de kubelet
.
Parmi les autres runtimes CRI, on retrouvera :
Se référer aux instructions d'installation CRI pour plus d'information.
Après avoir installé kubeadm
et kubelet
, exécuter ces étapes additionnelles :
-
Installer l'adaptateur runtime sur chaque noeud, en suivant les instructions d'installation du projet mentionné ci-dessus.
-
Configurer kubelet pour utiliser le runtime CRI distant. Ne pas oublier de modifier
RUNTIME_ENDPOINT
en utilisant la valeur adéquate/var/run/{your_runtime}.sock
:
cat > /etc/systemd/system/kubelet.service.d/20-cri.conf <<EOF
[Service]
Environment="KUBELET_EXTRA_ARGS=--container-runtime=remote --container-runtime-endpoint=$RUNTIME_ENDPOINT"
EOF
systemctl daemon-reload
Maintenant kubelet
est prête à utiliser le runtime CRI spécifié, et vous pouvez reprendre la séquence de déploiement avec kubeadm init
et kubeadm join
pour déployer votre cluster Kubernetes.
Il est aussi possible de configurer --cri-socket
à kubeadm init
et kubeadm reset
lorsque vous utilisez une implémentation CRI externe.
Paramétrer le nom du noeud
Par défaut, kubeadm
donne un nom au noeud en utilisant l'adresse de la machine. Vous pouvez outrepasser ce réglage en utilisant l'option --node-name
.
Cette option se chargera de passer la valeur appropriée pour --hostname-override
à kubelet.
Faîtes attention car forcer un nom d'hôte peut interférer avec les fournisseurs de cloud.
Héberger soi même le control plane Kubernetes
A partir de la version 1.8, vous pouvez expérimentalement créer un control plane Kubernetes auto-hébergé (self-hosted) . Cela signifie que des composants clefs comme le serveur d'API, le controller manager et l'ordonnanceur sont démarrés en tant que pods DaemonSet, configurés via l'API Kubernetes plutôt qu'en tant que pods static configurés avec des fichiers statiques dans kubelet.
Pour créer un cluster auto-hébergé, se référer à la commande kubeadm alpha selfhosting
.
Avertissements
-
L'auto-hébergement dans la version 1.8 et au delà comporte de sérieuses limitations. En particulier, un cluster auto-hébergé ne peut pas survivre au redémarrage du noeud control plane sans intervention manuelle.
-
Un cluster auto-hébergé ne peut pas être mis à jour via la commande
kubeadm upgrade
. -
Par défaut, les Pods d'un control plane auto-hébergé dépendent des identifiants chargés depuis des volumes de type
hostPath
A part pour la création initiale, ces identifiants ne sont pas gérés par kubeadm. -
La partie auto-hébergée du control plane n'inclut pas etcd, qui fonctionne toujours en tant que Pod statique.
Procédé
Le procédé de démarrage auto-hébergé est documenté dans le document de conception de kubeadm.
En bref, kubeadm alpha selfhosting
fonctionne de la manière suivante :
-
Attend que le control plane statique soit démarré correctement. C'est la même chose que le procédé
kubeadm init
lorsque non auto-hébergé. -
Utilise les manifestes du Pod statique du control plane pour construire un ensemble de manifestes DaemonSet qui vont lancer le control plane auto-hébergé. Cela modifie aussi les manifestes si nécessaires, par example pour ajouter des nouveaux volumes pour des secrets.
-
Crée des DaemonSets dans le namespace
kube-system
et attend que les pods ainsi créés soient démarrés. -
Une fois que les Pods auto-hébergés sont opérationnels, les Pods statiques qui leurs sont associés sont supprimés et kubeadm installe ensuite le prochain composant. Cela déclenche l'arrêt par kubelet de ces Pods statiques.
-
Quand le control plane statique d'origine s'arrête, le nouveau control plane auto-hébergé est capable d'écouter sur les mêmes ports et devenir actif.
Utiliser kubeadm sans connexion internet
Pour utiliser kubeadm sans connexion internet, vous devez télécharger les images requises par le control plane à l'avance.
A partir de Kubernetes 1.11, vous pouvez lister et télécharger les images en utilisant les sous commandes à kubeadm config images
:
kubeadm config images list
kubeadm config images pull
A partir de Kubernetes 1.12, les images prefixées par k8s.gcr.io/kube-*
, k8s.gcr.io/etcd
et k8s.gcr.io/pause
ne nécessitent pas un suffix -${ARCH}
.
Automatiser kubeadm
Plutôt que copier sur chaque noeud le jeton que vous avez obtenu avec kubeadm init
, comme décrit dans
le tutoriel basique de kubeadm, vous pouvez paralléliser la distribution du jeton afin d'automatiser cette tâche.
Pour ce faire, vous devez connaître l'adresse IP que le noeud control plane obtiendra après son démarrage.
-
Générer un jeton. Ce jeton doit avoir correspondre à la chaîne suivante :
<6 caractères>.<16 caractères>
. Plus simplement, il doit correspondre à la regexp suivante :[a-z0-9]{6}\.[a-z0-9]{16}
.kubeadm peut générer un jeton pour vous :
kubeadm token generate
-
Démarrer en parallèle le noeud control plane et les noeuds worker nodes avec ce jeton. Lors de leurs démarrages, ils devraient pouvoir se trouver les uns les autres et former le cluster. L'option
--token
peut être utilisée aussi bien pourkubeadm init
que pourkubeadm join
.
Une fois que le cluster est correctement démarré, vous pouvez obtenir les identifiants admin depuis le noeud control plane depuis le fichier /etc/kubernetes/admin.conf
et les utiliser pour communiquer avec le cluster.
Vous remarquerez que ce type d'installation présente un niveau de sécurité inférieur puisqu'il ne permet pas la validation du hash du certificat racine avec --discovery-token-ca-cert-hash
(puisqu'il n'est pas généré quand les noeuds sont provisionnés). Pour plus d'information, se référer à kubeadm join.
A suivre
- kubeadm init phase pour mieux comprendre les phases
kubeadm init
- kubeadm join pour amorcer un noeud Kubernetes worker node Kubernetes et le faire joindre le cluster
- kubeadm upgrade pour mettre à jour un cluster Kubernetes vers une version plus récente
- kubeadm reset pour annuler les changements appliqués avec
kubeadm init
oukubeadm join
à un noeud
7.6.2 - kubefed
7.7 - CLI kubectl
7.7.1 - Aperçu de kubectl
Kubectl est un outil en ligne de commande pour contrôler des clusters Kubernetes. kubectl
recherche un fichier appelé config dans le répertoire $HOME/.kube. Vous pouvez spécifier d'autres fichiers [kubeconfig](https://kube
rnetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) en définissant la variable d'environnement KUBECONFIG ou en utilisant le paramètre --kubeconfig
.
Cet aperçu couvre la syntaxe kubectl
, décrit les opérations et fournit des exemples classiques. Pour des détails sur chaque commande, incluant toutes les options et sous-commandes autorisées, voir la documentation de référence de kubectl. Pour des instructions d'installation, voir installer kubectl.
Syntaxe
Utilisez la syntaxe suivante pour exécuter des commandes kubectl
depuis votre fenêtre de terminal :
kubectl [commande] [TYPE] [NOM] [flags]
où commande
, TYPE
, NOM
et flags
sont :
-
commande
: Indique l'opération que vous désirez exécuter sur une ou plusieurs ressources, par exemplecreate
,get
,describe
,delete
. -
TYPE
: Indique le type de ressource. Les types de ressources sont insensibles à la casse et vous pouvez utiliser les formes singulier, pluriel ou abrégé. Par exemple, les commandes suivantes produisent le même résultat :```shell $ kubectl get pod pod1 $ kubectl get pods pod1 $ kubectl get po pod1 ```
-
NOM
: Indique le nom de la ressource. Les noms sont sensibles à la casse. Si le nom est omis, des détails pour toutes les ressources sont affichés, par exemple$ kubectl get pods
.En effectuant une opération sur plusieurs ressources, vous pouvez soit indiquer chaque ressource par leur type et nom soit indiquer un ou plusieurs fichiers :
-
Pour indiquer des ressources par leur type et nom :
-
Pour regrouper des ressources si elles ont toutes le même type :
TYPE1 nom1 nom2 nom<#>
.
Example:$ kubectl get pod exemple-pod1 exemple-pod2
-
Pour indiquer plusieurs types de ressources individuellement :
TYPE1/nom1 TYPE1/nom2 TYPE2/nom3 TYPE<#>/nom<#>
.
Exemple:$ kubectl get pod/exemple-pod1 replicationcontroller/exemple-rc1
-
-
Pour indiquer des ressources avec un ou plusieurs fichiers :
-f fichier1 -f fichier2 -f fichier<#>
- Utilisez YAML plutôt que JSON, YAML tendant à être plus facile à utiliser, particulièrement pour des fichiers de configuration.
Exemple:$ kubectl get pod -f ./pod.yaml
- Utilisez YAML plutôt que JSON, YAML tendant à être plus facile à utiliser, particulièrement pour des fichiers de configuration.
-
-
flags
: Indique des flags optionnels. Par exemple, vous pouvez utiliser les flags-s
ou--server
pour indiquer l'adresse et le port de l'API server Kubernetes.
Si vous avez besoin d'aide, exécutez kubectl help
depuis la fenêtre de terminal.
Opérations
Le tableau suivant inclut une courte description et la syntaxe générale pour chaque opération kubectl
:
Opération | Syntaxe | Description |
---|---|---|
alpha |
kubectl alpha SOUS-COMMANDE [flags] |
Liste les commandes disponibles qui correspondent à des fonctionnalités alpha, qui ne sont pas activées par défaut dans les clusters Kubernetes. |
annotate |
kubectl annotate (-f FICHIER | TYPE NOM | TYPE/NOM) CLE_1=VAL_1 ... CLE_N=VAL_N [--overwrite] [--all] [--resource-version=version] [flags] |
Ajoute ou modifie les annotations d'une ou plusieurs ressources. |
api-resources |
kubectl api-resources [flags] |
Liste les ressources d'API disponibles. |
api-versions |
kubectl api-versions [flags] |
Liste les versions d'API disponibles. |
apply |
kubectl apply -f FICHIER [flags] |
Applique un changement de configuration à une ressource depuis un fichier ou stdin. |
attach |
kubectl attach POD -c CONTENEUR [-i] [-t] [flags] |
Attache à un conteneur en cours d'exécution soit pour voir la sortie standard soit pour interagir avec le conteneur (stdin). |
auth |
kubectl auth [flags] [options] |
Inspecte les autorisations. |
autoscale |
kubectl autoscale (-f FICHIER | TYPE NOM | TYPE/NOM) [--min=MINPODS] --max=MAXPODS [--cpu-percent=CPU] [flags] |
Scale automatiquement l'ensemble des pods gérés par un replication controller. |
certificate |
kubectl certificate SOUS-COMMANDE [options] |
Modifie les ressources de type certificat. |
cluster-info |
kubectl cluster-info [flags] |
Affiche les informations des endpoints du master et des services du cluster. |
completion |
kubectl completion SHELL [options] |
Affiche le code de complétion pour le shell spécifié (bash ou zsh). |
config |
kubectl config SOUS-COMMANDE [flags] |
Modifie les fichiers kubeconfig. Voir les sous-commandes individuelles pour plus de détails. |
convert |
kubectl convert -f FICHIER [options] |
Convertit des fichiers de configuration entre différentes versions d'API. Les formats YAML et JSON sont acceptés. |
cordon |
kubectl cordon NOEUD [options] |
Marque un nœud comme non programmable. |
cp |
kubectl cp <ficher-src> <fichier-dest> [options] |
Copie des fichiers et des répertoires vers et depuis des conteneurs. |
create |
kubectl create -f FICHIER [flags] |
Crée une ou plusieurs ressources depuis un fichier ou stdin. |
delete |
kubectl delete (-f FICHIER | TYPE [NOM | /NOM | -l label | --all]) [flags] |
Supprime des ressources soit depuis un fichier ou stdin, ou en indiquant des sélecteurs de label, des noms, des sélecteurs de ressources ou des ressources. |
describe |
kubectl describe (-f FICHIER | TYPE [PREFIXE_NOM | /NOM | -l label]) [flags] |
Affiche l'état détaillé d'une ou plusieurs ressources. |
diff |
kubectl diff -f FICHIER [flags] |
Diff un fichier ou stdin par rapport à la configuration en cours |
drain |
kubectl drain NOEUD [options] |
Vide un nœud en préparation de sa mise en maintenance. |
edit |
kubectl edit (-f FICHIER | TYPE NOM | TYPE/NOM) [flags] |
Édite et met à jour la définition d'une ou plusieurs ressources sur le serveur en utilisant l'éditeur par défaut. |
exec |
kubectl exec POD [-c CONTENEUR] [-i] [-t] [flags] [-- COMMANDE [args...]] |
Exécute une commande à l'intérieur d'un conteneur dans un pod. |
explain |
kubectl explain [--recursive=false] [flags] |
Obtient des informations sur différentes ressources. Par exemple pods, nœuds, services, etc. |
expose |
kubectl expose (-f FICHIER | TYPE NOM | TYPE/NOM) [--port=port] [--protocol=TCP|UDP] [--target-port=nombre-ou-nom] [--name=nom] [--external-ip=ip-externe-ou-service] [--type=type] [flags] |
Expose un replication controller, service ou pod comme un nouveau service Kubernetes. |
get |
kubectl get (-f FICHIER | TYPE [NOM | /NOM | -l label]) [--watch] [--sort-by=CHAMP] [[-o | --output]=FORMAT_AFFICHAGE] [flags] |
Liste une ou plusieurs ressources. |
kustomize |
kubectl kustomize <répertoire> [flags] [options] |
Liste un ensemble de ressources d'API généré à partir d'instructions d'un fichier kustomization.yaml. Le paramètre doit être le chemin d'un répertoire contenant ce fichier, ou l'URL d'un dépôt git incluant un suffixe de chemin par rapport à la racine du dépôt. |
label |
kubectl label (-f FICHIER | TYPE NOM | TYPE/NOM) CLE_1=VAL_1 ... CLE_N=VAL_N [--overwrite] [--all] [--resource-version=version] [flags] |
Ajoute ou met à jour les labels d'une ou plusieurs ressources. |
logs |
kubectl logs POD [-c CONTENEUR] [--follow] [flags] |
Affiche les logs d'un conteneur dans un pod. |
options |
kubectl options |
Liste des options globales, s'appliquant à toutes commandes. |
patch |
kubectl patch (-f FICHIER | TYPE NOM | TYPE/NOM) --patch PATCH [flags] |
Met à jour un ou plusieurs champs d'une resource en utilisant le processus de merge patch stratégique. |
plugin |
kubectl plugin [flags] [options] |
Fournit des utilitaires pour interagir avec des plugins. |
port-forward |
kubectl port-forward POD [PORT_LOCAL:]PORT_DISTANT [...[PORT_LOCAL_N:]PORT_DISTANT_N] [flags] |
Transfère un ou plusieurs ports locaux vers un pod. |
proxy |
kubectl proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix] [flags] |
Exécute un proxy vers un API server Kubernetes. |
replace |
kubectl replace -f FICHIER |
Remplace une ressource depuis un fichier ou stdin. |
rollout |
kubectl rollout SOUS-COMMANDE [options] |
Gère le rollout d'une ressource. Les types de ressources valides sont : deployments, daemonsets et statefulsets. |
run |
kubectl run NOM --image=image [--env="cle=valeur"] [--port=port] [--replicas=replicas] [--dry-run=server|client|none] [--overrides=inline-json] [flags] |
Exécute dans le cluster l'image indiquée. |
scale |
kubectl scale (-f FICHIER | TYPE NOM | TYPE/NOM) --replicas=QUANTITE [--resource-version=version] [--current-replicas=quantité] [flags] |
Met à jour la taille du replication controller indiqué. |
set |
kubectl set SOUS-COMMANDE [options] |
Configure les ressources de l'application. |
taint |
kubectl taint NOEUD NNOM CLE_1=VAL_1:EFFET_TAINT_1 ... CLE_N=VAL_N:EFFET_TAINT_N [options] |
Met à jour les marques (taints) d'un ou plusieurs nœuds. |
top |
kubectl top [flags] [options] |
Affiche l'utilisation des ressources (CPU/Mémoire/Stockage). |
uncordon |
kubectl uncordon NOEUD [options] |
Marque un noeud comme programmable. |
version |
kubectl version [--client] [flags] |
Affiche la version de Kubernetes du serveur et du client. |
wait |
kubectl wait ([-f FICHIER] | ressource.groupe/ressource.nom | ressource.groupe [(-l label | --all)]) [--for=delete|--for condition=available] [options] |
Expérimental : Attend un condition spécifique sur une ou plusieurs ressources. |
Rappelez-vous : Pour tout savoir sur les opérations, voir la documentation de référence de kubectl.
Types de ressources
Le tableau suivant inclut la liste de tous les types de ressources pris en charge et leurs alias abrégés.
(cette sortie peut être obtenue depuis kubectl api-resources
, et correspond à Kubernetes 1.13.3.)
Nom de la ressource | Noms abrégés | Groupe API | Par namespace | Genre de la ressource |
---|---|---|---|---|
bindings |
true | Binding | ||
componentstatuses |
cs |
false | ComponentStatus | |
configmaps |
cm |
true | ConfigMap | |
endpoints |
ep |
true | Endpoints | |
limitranges |
limits |
true | LimitRange | |
namespaces |
ns |
false | Namespace | |
nodes |
no |
false | Node | |
persistentvolumeclaims |
pvc |
true | PersistentVolumeClaim | |
persistentvolumes |
pv |
false | PersistentVolume | |
pods |
po |
true | Pod | |
podtemplates |
true | PodTemplate | ||
replicationcontrollers |
rc |
true | ReplicationController | |
resourcequotas |
quota |
true | ResourceQuota | |
secrets |
true | Secret | ||
serviceaccounts |
sa |
true | ServiceAccount | |
services |
svc |
true | Service | |
mutatingwebhookconfigurations |
admissionregistration.k8s.io | false | MutatingWebhookConfiguration | |
validatingwebhookconfigurations |
admissionregistration.k8s.io | false | ValidatingWebhookConfiguration | |
customresourcedefinitions |
crd , crds |
apiextensions.k8s.io | false | CustomResourceDefinition |
apiservices |
apiregistration.k8s.io | false | APIService | |
controllerrevisions |
apps | true | ControllerRevision | |
daemonsets |
ds |
apps | true | DaemonSet |
deployments |
deploy |
apps | true | Deployment |
replicasets |
rs |
apps | true | ReplicaSet |
statefulsets |
sts |
apps | true | StatefulSet |
tokenreviews |
authentication.k8s.io | false | TokenReview | |
localsubjectaccessreviews |
authorization.k8s.io | true | LocalSubjectAccessReview | |
selfsubjectaccessreviews |
authorization.k8s.io | false | SelfSubjectAccessReview | |
selfsubjectrulesreviews |
authorization.k8s.io | false | SelfSubjectRulesReview | |
subjectaccessreviews |
authorization.k8s.io | false | SubjectAccessReview | |
horizontalpodautoscalers |
hpa |
autoscaling | true | HorizontalPodAutoscaler |
cronjobs |
cj |
batch | true | CronJob |
jobs |
batch | true | Job | |
certificatesigningrequests |
csr |
certificates.k8s.io | false | CertificateSigningRequest |
leases |
coordination.k8s.io | true | Lease | |
events |
ev |
events.k8s.io | true | Event |
ingresses |
ing |
extensions | true | Ingress |
networkpolicies |
netpol |
networking.k8s.io | true | NetworkPolicy |
poddisruptionbudgets |
pdb |
policy | true | PodDisruptionBudget |
podsecuritypolicies |
psp |
policy | false | PodSecurityPolicy |
clusterrolebindings |
rbac.authorization.k8s.io | false | ClusterRoleBinding | |
clusterroles |
rbac.authorization.k8s.io | false | ClusterRole | |
rolebindings |
rbac.authorization.k8s.io | true | RoleBinding | |
roles |
rbac.authorization.k8s.io | true | Role | |
priorityclasses |
pc |
scheduling.k8s.io | false | PriorityClass |
csidrivers |
storage.k8s.io | false | CSIDriver | |
csinodes |
storage.k8s.io | false | CSINode | |
storageclasses |
sc |
storage.k8s.io | false | StorageClass |
volumeattachments |
storage.k8s.io | false | VolumeAttachment |
Options de sortie
Utilisez les sections suivantes pour savoir comment vous pouvez formater ou ordonner les sorties de certaines commandes. Pour savoir exactgement quelles commandes prennent en charge quelles options de sortie, voir la documentation de référence de kubectl.
Formater la sortie
Le format de sortie par défaut pour toutes les commandes kubectl
est le format texte lisible par l'utilisateur. Pour afficher des détails dans votre fenêtre de terminal dans un format spécifique, vous pouvez ajouter une des options -o
ou --output
à une des commandes kubectl
les prenant en charge.
Syntaxe
kubectl [commande] [TYPE] [NOM] -o <format_sortie>
Selon l'opération kubectl
, les formats de sortie suivants sont pris en charge :
Format de sortie | Description |
---|---|
-o custom-columns=<spec> |
Affiche un tableau en utilisant une liste de colonnes personnalisées séparées par des virgules. |
-o custom-columns-file=<fichier> |
Affiche un tableau en utilisant un modèle de colonnes personnalisées dans le fichier <fichier> . |
-o json |
Affiche un objet de l'API formaté en JSON. |
-o jsonpath=<modèle> |
Affiche les champs définis par une expression jsonpath. |
-o jsonpath-file=<ffichier> |
Affiche les champs définis par une expression jsonpath dans le fichier <fichier> . |
-o name |
Affiche uniquement le nom de la ressource et rien de plus. |
-o wide |
Affiche dans le format texte avec toute information supplémentaire. Pour les pods, le nom du nœud est inclus. |
-o yaml |
Affiche un objet de l'API formaté en YAML. |
Exemple
Dans cet exemple, la commande suivante affiche les détails d'un unique pod sous forme d'un objet formaté en YAML :
$ kubectl get pod web-pod-13je7 -o yaml
Souvenez-vous : Voir la documentation de référence de kubectl pour voir quels formats de sortie sont pris en charge par chaque commande.
Colonnes personnalisées
Pour définir des colonnes personnalisées et afficher uniquement les détails voulus dans un tableau, vous pouvez utiliser l'option custom-columns
. Vous pouvez choisir de définir les colonnes personnalisées soit en ligne soit dans un fichier modèle : -o custom-columns=<spec>
ou -o custom-columns-file=<fichier>
.
Exemples
En ligne :
$ kubectl get pods <nom-pod> -o custom-columns=NOM:.metadata.name,RSRC:.metadata.resourceVersion
Fichier modèle :
$ kubectl get pods <nom-pod> -o custom-columns-file=modele.txt
où le fichier modele.txt
contient :
NOM RSRC
metadata.name metadata.resourceVersion
Le résultat de ces commandes est :
NOM RSRC
submit-queue 610995
Colonnes côté serveur
kubectl
est capable de recevoir des informations de colonnes spécifiques d'objets depuis le serveur.
Cela veut dire que pour toute ressource donnée, le serveur va retourner les colonnes et lignes pour cette ressource, que le client pourra afficher.
Cela permet un affichage de sortie lisible par l'utilisateur cohérent entre les clients utilisés sur le même cluster, le serveur encapsulant les détails d'affichage.
Cette fonctionnalité est activée par défaut dans kubectl
version 1.11 et suivantes. Pour la désactiver, ajoutez l'option
--server-print=false
à la commande kubectl get
.
Exemples
Pour afficher les informations sur le status d'un pod, utilisez une commande similaire à :
kubectl get pods <nom-pod> --server-print=false
La sortie ressemble à :
NAME AGE
nom-pod 1m
Ordonner les listes d'objets
Pour afficher les objets dans une liste ordonnée dans une fenêtre de terminal, vous pouvez ajouter l'option --sort-by
à une commande kubectl
qui la prend en charge. Ordonnez vos objets en spécifiant n'importe quel champ numérique ou textuel avec l'option --sort-by
. Pour spécifier un champ, utilisez une expression jsonpath.
Syntaxe
kubectl [commande] [TYPE] [NOM] --sort-by=<exp_jsonpath>
Exemple
Pour afficher une liste de pods ordonnés par nom, exécutez :
$ kubectl get pods --sort-by=.metadata.name
Exemples : Opérations courantes
Utilisez les exemples suivants pour vous familiariser avec les opérations de kubectl
fréquemment utilisées :
kubectl apply
- Créer une ressource depuis un fichier ou stdin.
# Crée un service en utilisant la définition dans exemple-service.yaml.
$ kubectl apply -f exemple-service.yaml
# Crée un replication controller en utilisant la définition dans exemple-controller.yaml.
$ kubectl apply -f exemple-controller.yaml
# Crée les objets qui sont définis dans les fichiers .yaml, .yml ou .json du répertoire <répertoire>.
$ kubectl apply -f <répertoire>
kubectl get
- Liste une ou plusieurs ressources.
# Liste tous les pods dans le format de sortie texte.
$ kubectl get pods
# Liste tous les pods dans le format de sortie texte et inclut des informations additionnelles (comme le nom du nœud).
$ kubectl get pods -o wide
# Liste le replication controller ayant le nom donné dans le format de sortie texte.
# Astuce : Vous pouvez raccourcir et remplacer le type de ressource 'replicationcontroller' avec l'alias 'rc'.
$ kubectl get replicationcontroller <nom-rc>
# Liste ensemble tous les replication controller et les services dans le format de sortie texte.
$ kubectl get rc,services
# Liste tous les daemon sets dans le format de sortie texte.
kubectl get ds
# Liste tous les pods s'exécutant sur le nœud serveur01
$ kubectl get pods --field-selector=spec.nodeName=serveur01
kubectl describe
- Affiche l'état détaillé d'une ou plusieurs ressources, en incluant par défaut les ressources non initialisées.
# Affiche les détails du nœud ayant le nom <nom-nœud>.
$ kubectl describe nodes <nom-nœud>
# Affiche les détails du pod ayant le nom <nom-pod>.
$ kubectl describe pods/<nom-pod>
# Affiche les détails de tous les pods gérés par le replication controller dont le nom est <nom-rc>.
# Rappelez-vous : les noms des pods étant créés par un replication controller sont préfixés par le nom du replication controller.
$ kubectl describe pods <nom-rc>
# Décrit tous les pods
$ kubectl describe pods
kubectl get
est habituellement utilisée pour afficher une ou plusieurs ressources d'un même type. Elle propose un ensemble complet d'options permettant de personnaliser le format de sortie avec les options -o
ou --output
, par exemple.
Vous pouvez utiliser les options -w
ou --watch
pour initier l'écoute des modifications d'un objet particulier. La commande kubectl describe
est elle plutôt utilisée pour décrire les divers aspects d'une ressource voulue. Elle peut invoquer plusieurs appels d'API à l'API server pour construire une vue complète pour l'utilisateur. Par exemple, la commande kubectl describe node
retourne non seulement les informations sur les nœuds, mais aussi un résumé des pods s'exécutant dessus, les événements générés pour chaque nœud, etc.nœud
kubectl delete
- Supprime des ressources soit depuis un fichier, stdin, ou en spécifiant des sélecteurs de labels, des noms, des sélecteurs de ressource ou des ressources.
# Supprime un pod en utilisant le type et le nom spécifiés dans le fichier pod.yaml.
$ kubectl delete -f pod.yaml
# Supprime tous les pods et services ayant le label <clé-label>=<valeur-label>
$ kubectl delete pods,services -l <clé-label>=<valeur-label>
# Supprime tous les pods, en incluant les non initialisés.
$ kubectl delete pods --all
kubectl exec
- Exécute une commande depuis un conteneur d'un pod.
# Affiche la sortie de la commande 'date' depuis le pod <nom-pod>. Par défaut, la sortie se fait depuis le premier conteneur.
$ kubectl exec <nom-pod> -- date
# Affiche la sortie de la commande 'date' depuis le conteneur <nom-conteneur> du pod <nom-pod>.
$ kubectl exec <nom-pod> -c <nom-conteneur> -- date
# Obtient un TTY interactif et exécute /bin/bash depuis le pod <nom-pod>. Par défaut, la sortie se fait depuis le premier conteneur.
$ kubectl exec -ti <nom-pod> -- /bin/bash
kubectl logs
- Affiche les logs d'un conteneur dans un pod.
# Retourne un instantané des logs du pod <nom-pod>.
$ kubectl logs <nom-pod>
# Commence à streamer les logs du pod <nom-pod>. Ceci est similaire à la commande Linux 'tail -f'.
$ kubectl logs -f <nom-pod>
kubectl diff
- Affiche un diff des mises à jour proposées au cluster.
# Diff les ressources présentes dans "pod.json".
kubectl diff -f pod.json
# Diff les ressources présentes dans le fichier lu sur l'entrée standard.
cat service.yaml | kubectl diff -f -
Exemples : Créer et utiliser des plugins
Utilisez les exemples suivants pour vous familiariser avec l'écriture et l'utilisation de plugins kubectl
:
# créez un plugin simple dans n'importe quel langage et nommez
# l'exécutable de telle sorte qu'il commence par "kubectl-"
$ cat ./kubectl-hello
#!/bin/bash
# ce plugin affiche les mots "hello world"
echo "hello world"
# une fois votre plugin écrit, rendez-le exécutable
$ sudo chmod +x ./kubectl-hello
# et déplacez-le dans un répertoire de votre PATH
$ sudo mv ./kubectl-hello /usr/local/bin
# vous avez maintenant créé et "installé" un plugin kubectl.
# vous pouvez commencer à l'utiliser en l'invoquant depuis kubectl
# comme s'il s'agissait d'une commande ordinaire
$ kubectl hello
hello world
# vous pouvez "désinstaller" un plugin,
# simplement en le supprimant de votre PATH
$ sudo rm /usr/local/bin/kubectl-hello
Pour voir tous les plugins disponibles pour kubectl
, vous pouvez utiliser la sous-commande kubectl plugin list
:
$ kubectl plugin list
The following kubectl-compatible plugins are available:
/usr/local/bin/kubectl-hello
/usr/local/bin/kubectl-foo
/usr/local/bin/kubectl-bar
# cette commande peut aussi vous avertir de plugins qui ne sont pas exécutables,
# ou qui sont cachés par d'autres plugins, par exemple :
$ sudo chmod -x /usr/local/bin/kubectl-foo
$ kubectl plugin list
The following kubectl-compatible plugins are available:
/usr/local/bin/kubectl-hello
/usr/local/bin/kubectl-foo
- warning: /usr/local/bin/kubectl-foo identified as a plugin, but it is not executable
/usr/local/bin/kubectl-bar
error: one plugin warning was found
Vous pouvez voir les plugins comme un moyen de construire des fonctionnalités plus complexes au dessus des commandes kubectl existantes :
$ cat ./kubectl-whoami
#!/bin/bash
# ce plugin utilise la commande `kubectl config` pour afficher
# l'information sur l'utilisateur courant, en se basant sur
# le contexte couramment sélectionné
kubectl config view --template='{{ range .contexts }}{{ if eq .name "'$(kubectl config current-context)'" }}Current user: {{ printf "%s\n" .context.user }}{{ end }}{{ end }}'
Exécuter le plugin ci-dessus vous donne une sortie contenant l'utilisateur du contexte couramment sélectionné dans votre fichier KUBECONFIG :
# rendre le fichier exécutable executable
$ sudo chmod +x ./kubectl-whoami
# et le déplacer dans le PATH
$ sudo mv ./kubectl-whoami /usr/local/bin
$ kubectl whoami
Current user: plugins-user
Pour en savoir plus sur les plugins, examinez l'exemple de plugin CLI.
A suivre
Commencez à utiliser les commandes kubectl.
7.7.2 - Support de JSONPath
Kubectl prend en charge les modèles JSONPath.
Un modèle JSONPath est composé d'expressions JSONPath entourées par des accolades {}. Kubectl utilise les expressions JSONPath pour filtrer sur des champs spécifiques de l'objet JSON et formater la sortie. En plus de la syntaxe de modèle JSONPath originale, les fonctions et syntaxes suivantes sont valides :
- Utilisez des guillemets doubles pour marquer du texte dans les expressions JSONPath.
- Utilisez les opérateurs
range
etend
pour itérer sur des listes. - Utilisez des indices négatifs pour parcourir une liste à reculons. Les indices négatifs ne "bouclent pas" sur une liste et sont valides tant que
-index + longeurListe >= 0
.
-
L'opérateur
$
est optionnel, l'expression commençant toujours, par défaut, à la racine de l'objet. -
L'objet résultant est affiché via sa fonction String().
Étant donné l'entrée JSON :
{
"kind": "List",
"items":[
{
"kind":"None",
"metadata":{"name":"127.0.0.1"},
"status":{
"capacity":{"cpu":"4"},
"addresses":[{"type": "LegacyHostIP", "address":"127.0.0.1"}]
}
},
{
"kind":"None",
"metadata":{"name":"127.0.0.2"},
"status":{
"capacity":{"cpu":"8"},
"addresses":[
{"type": "LegacyHostIP", "address":"127.0.0.2"},
{"type": "another", "address":"127.0.0.3"}
]
}
}
],
"users":[
{
"name": "myself",
"user": {}
},
{
"name": "e2e",
"user": {"username": "admin", "password": "secret"}
}
]
}
Fonction | Description | Exemple | Résultat |
---|---|---|---|
text |
le texte en clair | le type est {.kind} |
le type est List |
@ |
l'objet courant | {@} |
identique à l'entrée |
. ou [] |
opérateur fils | {.kind} , {['kind']} ou {['name\.type']} |
List |
.. |
descente récursive | {..name} |
127.0.0.1 127.0.0.2 myself e2e |
* |
joker. Tous les objets | {.items[*].metadata.name} |
[127.0.0.1 127.0.0.2] |
[start:end:step] |
opérateur d'indice | {.users[0].name} |
myself |
[,] |
opérateur d'union | {.items[*]['metadata.name', 'status.capacity']} |
127.0.0.1 127.0.0.2 map[cpu:4] map[cpu:8] |
?() |
filtre | {.users[?(@.name=="e2e")].user.password} |
secret |
range , end |
itération de liste | {range .items[*]}[{.metadata.name}, {.status.capacity}] {end} |
[127.0.0.1, map[cpu:4]] [127.0.0.2, map[cpu:8]] |
'' |
protège chaîne interprétée | {range .items[*]}{.metadata.name}{'\t'}{end} |
127.0.0.1 127.0.0.2 |
Exemples utilisant kubectl
et des expressions JSONPath :
kubectl get pods -o json
kubectl get pods -o=jsonpath='{@}'
kubectl get pods -o=jsonpath='{.items[0]}'
kubectl get pods -o=jsonpath='{.items[0].metadata.name}'
kubectl get pods -o=jsonpath="{.items[*]['metadata.name', 'status.capacity']}"
kubectl get pods -o=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.startTime}{"\n"}{end}'
Sous Windows, vous devez utiliser des guillemets doubles autour des modèles JSONPath qui contiennent des espaces (et non des guillemets simples comme ci-dessus pour bash). Ceci entraîne que vous devez utiliser un guillemet simple ou un double guillemet échappé autour des chaînes litérales dans le modèle. Par exemple :
kubectl get pods -o=jsonpath="{range .items[*]}{.metadata.name}{'\t'}{.status.startTime}{'\n'}{end}"
kubectl get pods -o=jsonpath="{range .items[*]}{.metadata.name}{\"\t\"}{.status.startTime}{\"\n\"}{end}"
7.7.3 - Aide-mémoire kubectl
Voir aussi : Aperçu Kubectl et Guide JsonPath.
Cette page donne un aperçu de la commande kubectl
.
Aide-mémoire kubectl
Auto-complétion avec Kubectl
BASH
source <(kubectl completion bash) # active l'auto-complétion pour bash dans le shell courant, le paquet bash-completion devant être installé au préalable
echo "source <(kubectl completion bash)" >> ~/.bashrc # ajoute l'auto-complétion de manière permanente à votre shell bash
Vous pouvez de plus déclarer un alias pour kubectl
qui fonctionne aussi avec l'auto-complétion :
alias k=kubectl
complete -F __start_kubectl k
ZSH
source <(kubectl completion zsh) # active l'auto-complétion pour zsh dans le shell courant
echo "[[ $commands[kubectl] ]] && source <(kubectl completion zsh)" >> ~/.zshrc # ajoute l'auto-complétion de manière permanente à votre shell zsh
Contexte et configuration de Kubectl
Indique avec quel cluster Kubernetes kubectl
communique et modifie les informations de configuration. Voir la documentation Authentification multi-clusters avec kubeconfig pour des informations détaillées sur le fichier de configuration.
Information. Voir la documentation Authentification à travers des clusters avec kubeconfig
pour des informations détaillées sur le fichier de configuration.
kubectl config view # Affiche les paramètres fusionnés de kubeconfig
# Utilise plusieurs fichiers kubeconfig en même temps et affiche la configuration fusionnée
KUBECONFIG=~/.kube/config:~/.kube/kubconfig2
kubectl config view
# Affiche le mot de passe pour l'utilisateur e2e
kubectl config view -o jsonpath='{.users[?(@.name == "e2e")].user.password}'
kubectl config view -o jsonpath='{.users[].name}' # Affiche le premier utilisateur
kubectl config view -o jsonpath='{.users[*].name}' # Affiche une liste d'utilisateurs
kubectl config get-contexts # Affiche la liste des contextes
kubectl config current-context # Affiche le contexte courant (current-context)
kubectl config use-context my-cluster-name # Définit my-cluster-name comme contexte courant
# Ajoute un nouveau cluster à votre kubeconf, prenant en charge l'authentification de base (basic auth)
kubectl config set-credentials kubeuser/foo.kubernetes.com --username=kubeuser --password=kubepassword
# Enregistre de manière permanente le namespace pour toutes les commandes kubectl suivantes dans ce contexte
kubectl config set-context --current --namespace=ggckad-s2
# Définit et utilise un contexte qui utilise un nom d'utilisateur et un namespace spécifiques
kubectl config set-context gce --user=cluster-admin --namespace=foo \
&& kubectl config use-context gce
kubectl config unset users.foo # Supprime l'utilisateur foo
Apply
apply
gère des applications en utilisant des fichiers définissant des ressources Kubernetes. Elle crée et met à jour des ressources dans un cluster en exécutant kubectl apply
. C'est la manière recommandée de gérer des applications Kubernetes en production. Voir le Livre Kubectl.
Création d'objets
Les manifests Kubernetes peuvent être définis en YAML ou JSON. Les extensions de fichier .yaml
,
.yml
, et .json
peuvent être utilisés.
kubectl apply -f ./my-manifest.yaml # Crée une ou plusieurs ressources
kubectl apply -f ./my1.yaml -f ./my2.yaml # Crée depuis plusieurs fichiers
kubectl apply -f ./dir # Crée une ou plusieurs ressources depuis tous les manifests dans dir
kubectl apply -f https://git.io/vPieo # Crée une ou plusieurs ressources depuis une url
kubectl create deployment nginx --image=nginx # Démarre une instance unique de nginx
kubectl explain pods # Affiche la documentation pour les manifests pod
# Crée plusieurs objets YAML depuis l'entrée standard (stdin)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: busybox-sleep
spec:
containers:
- name: busybox
image: busybox
args:
- sleep
- "1000000"
---
apiVersion: v1
kind: Pod
metadata:
name: busybox-sleep-less
spec:
containers:
- name: busybox
image: busybox
args:
- sleep
- "1000"
EOF
# Crée un Secret contenant plusieurs clés
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
password: $(echo -n "s33msi4" | base64 -w0)
username: $(echo -n "jane" | base64 -w0)
EOF
Visualisation et Recherche de ressources
# Commandes Get avec un affichage basique
kubectl get services # Liste tous les services d'un namespace
kubectl get pods --all-namespaces # Liste tous les Pods de tous les namespaces
kubectl get pods -o wide # Liste tous les Pods du namespace courant, avec plus de détails
kubectl get deployment my-dep # Liste un déploiement particulier
kubectl get pods # Liste tous les Pods dans un namespace
kubectl get pod my-pod -o yaml # Affiche le YAML du Pod
# Commandes Describe avec un affichage verbeux
kubectl describe nodes my-node
kubectl describe pods my-pod
# Liste les services triés par nom
kubectl get services --sort-by=.metadata.name
# Liste les pods classés par nombre de redémarrages
kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'
# Affiche les volumes persistants classés par capacité de stockage
kubectl get pv --sort-by=.spec.capacity.storage
# Affiche la version des labels de tous les pods ayant un label app=cassandra
kubectl get pods --selector=app=cassandra -o \
jsonpath='{.items[*].metadata.labels.version}'
# Affiche tous les noeuds (en utilisant un sélecteur pour exclure ceux ayant un label
# nommé 'node-role.kubernetes.io/master')
kubectl get node --selector='!node-role.kubernetes.io/master'
# Affiche tous les pods en cours d'exécution (Running) dans le namespace
kubectl get pods --field-selector=status.phase=Running
# Affiche les IPs externes (ExternalIPs) de tous les noeuds
kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}'
# Liste les noms des pods appartenant à un ReplicationController particulier
# "jq" est une commande utile pour des transformations non prises en charge par jsonpath, il est disponible ici : https://stedolan.github.io/jq/
sel=${$(kubectl get rc my-rc --output=json | jq -j '.spec.selector | to_entries | .[] | "\(.key)=\(.value),"')%?}
echo $(kubectl get pods --selector=$sel --output=jsonpath={.items..metadata.name})
# Affiche les labels pour tous les pods (ou tout autre objet Kubernetes prenant en charge les labels)
kubectl get pods --show-labels
# Vérifie quels noeuds sont prêts
JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' \
&& kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True"
# Liste tous les Secrets actuellement utilisés par un pod
kubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq
# Liste les containerIDs des initContainer de tous les Pods
# Utile lors du nettoyage des conteneurs arrêtés, tout en évitant de retirer les initContainers.
kubectl get pods --all-namespaces -o jsonpath='{range .items[*].status.initContainerStatuses[*]}{.containerID}{"\n"}{end}' | cut -d/ -f3
# Liste les événements (Events) classés par timestamp
kubectl get events --sort-by=.metadata.creationTimestamp
# Compare l'état actuel du cluster à l'état du cluster si le manifeste était appliqué.
kubectl diff -f ./my-manifest.yaml
Mise à jour de ressources
Depuis la version 1.11, rolling-update
a été déprécié (voir CHANGELOG-1.11.md), utilisez plutôt rollout
.
kubectl set image deployment/frontend www=image:v2 # Rolling update du conteneur "www" du déploiement "frontend", par mise à jour de son image
kubectl rollout history deployment/frontend # Vérifie l'historique de déploiements incluant la révision
kubectl rollout undo deployment/frontend # Rollback du déploiement précédent
kubectl rollout undo deployment/frontend --to-revision=2 # Rollback à une version spécifique
kubectl rollout status -w deployment/frontend # Écoute (Watch) le status du rolling update du déploiement "frontend" jusqu'à ce qu'il se termine
kubectl rollout restart deployment/frontend # Rolling restart du déploiement "frontend"
cat pod.json | kubectl replace -f - # Remplace un pod, en utilisant un JSON passé en entrée standard
# Remplace de manière forcée (Force replace), supprime puis re-crée la ressource. Provoque une interruption de service.
kubectl replace --force -f ./pod.json
# Crée un service pour un nginx repliqué, qui rend le service sur le port 80 et se connecte aux conteneurs sur le port 8000
kubectl expose rc nginx --port=80 --target-port=8000
# Modifie la version (tag) de l'image du conteneur unique du pod à v4
kubectl get pod mypod -o yaml | sed 's/\(image: myimage\):.*$/\1:v4/' | kubectl replace -f -
kubectl label pods my-pod new-label=awesome # Ajoute un Label
kubectl annotate pods my-pod icon-url=http://goo.gl/XXBTWq # Ajoute une annotation
kubectl autoscale deployment foo --min=2 --max=10 # Mise à l'échelle automatique (Auto scale) d'un déploiement "foo"
Mise à jour partielle de ressources
# Mise à jour partielle d'un node
kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}' # Met à jour partiellement un noeud
# Met à jour l'image d'un conteneur ; spec.containers[*].name est requis car c'est une clé du merge
kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}'
# Met à jour l'image d'un conteneur en utilisant un patch json avec tableaux indexés
kubectl patch pod valid-pod --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"new image"}]'
# Désactive la livenessProbe d'un déploiement en utilisant un patch json avec tableaux indexés
kubectl patch deployment valid-deployment --type json -p='[{"op": "remove", "path": "/spec/template/spec/containers/0/livenessProbe"}]'
# Ajoute un nouvel élément à un tableau indexé
kubectl patch sa default --type='json' -p='[{"op": "add", "path": "/secrets/1", "value": {"name": "whatever" } }]'
Édition de ressources
Édite n'importe quelle ressource de l'API dans un éditeur.
kubectl edit svc/docker-registry # Édite le service nommé docker-registry
KUBE_EDITOR="nano" kubectl edit svc/docker-registry # Utilise un autre éditeur
Mise à l'échelle de ressources
kubectl scale --replicas=3 rs/foo # Scale un replicaset nommé 'foo' à 3
kubectl scale --replicas=3 -f foo.yaml # Scale une ressource spécifiée dans foo.yaml" à 3
kubectl scale --current-replicas=2 --replicas=3 deployment/mysql # Si la taille du déploiement nommé mysql est actuellement 2, scale mysql à 3
kubectl scale --replicas=5 rc/foo rc/bar rc/baz # Scale plusieurs contrôleurs de réplication
Suppression de ressources
kubectl delete -f ./pod.json # Supprime un pod en utilisant le type et le nom spécifiés dans pod.json
kubectl delete pod,service baz foo # Supprime les pods et services ayant les mêmes noms "baz" et "foo"
kubectl delete pods,services -l name=myLabel # Supprime les pods et services ayant le label name=myLabel
kubectl -n my-ns delete pod,svc --all # Supprime tous les pods et services dans le namespace my-ns
# Supprime tous les pods correspondants à pattern1 ou pattern2 avec awk
kubectl get pods -n mynamespace --no-headers=true | awk '/pattern1|pattern2/{print $1}' | xargs kubectl delete -n mynamespace pod
Interaction avec des Pods en cours d'exécution
kubectl logs my-pod # Affiche les logs du pod (stdout)
kubectl logs -l name=myLabel # Affiche les logs des pods ayant le label name=myLabel (stdout)
kubectl logs my-pod --previous # Affiche les logs du pod (stdout) pour une instance précédente du conteneur
kubectl logs my-pod -c my-container # Affiche les logs d'un conteneur particulier du pod (stdout, cas d'un pod multi-conteneurs)
kubectl logs -l name=myLabel -c my-container # Affiche les logs des pods avec le label name=myLabel (stdout, cas d'un pod multi-conteneurs)
kubectl logs my-pod -c my-container --previous # Affiche les logs d'un conteneur particulier du pod (stdout, cas d'un pod multi-conteneurs) pour une instance précédente du conteneur
kubectl logs -f my-pod # Fait défiler (stream) les logs du pod (stdout)
kubectl logs -f my-pod -c my-container # Fait défiler (stream) les logs d'un conteneur particulier du pod (stdout, cas d'un pod multi-conteneurs)
kubectl logs -f -l name=myLabel --all-containers # Fait défiler (stream) les logs de tous les pods ayant le label name=myLabel (stdout)
kubectl run -i --tty busybox --image=busybox -- sh # Exécute un pod comme un shell interactif
kubectl run nginx --image=nginx --restart=Never -n
mynamespace # Exécute le pod nginx dans un namespace spécifique
kubectl run nginx --image=nginx --restart=Never # Simule l'exécution du pod nginx et écrit sa spécification dans un fichier pod.yaml
--dry-run -o yaml > pod.yaml
kubectl attach my-pod -i # Attache à un conteneur en cours d'exécution
kubectl port-forward my-pod 5000:6000 # Écoute le port 5000 de la machine locale et forwarde vers le port 6000 de my-pod
kubectl exec my-pod -- ls / # Exécute une commande dans un pod existant (cas d'un seul conteneur)
kubectl exec my-pod -c my-container -- ls / # Exécute une commande dans un pod existant (cas multi-conteneurs)
kubectl top pod POD_NAME --containers # Affiche les métriques pour un pod donné et ses conteneurs
Interaction avec des Noeuds et Clusters
kubectl cordon mon-noeud # Marque mon-noeud comme non assignable (unschedulable)
kubectl drain mon-noeud # Draine mon-noeud en préparation d'une mise en maintenance
kubectl uncordon mon-noeud # Marque mon-noeud comme assignable
kubectl top node mon-noeud # Affiche les métriques pour un noeud donné
kubectl cluster-info # Affiche les adresses du master et des services
kubectl cluster-info dump # Affiche l'état courant du cluster sur stdout
kubectl cluster-info dump --output-directory=/path/to/cluster-state # Affiche l'état courant du cluster sur /path/to/cluster-state
# Si une teinte avec cette clé et cet effet existe déjà, sa valeur est remplacée comme spécifié.
kubectl taint nodes foo dedicated=special-user:NoSchedule
Types de ressources
Liste tous les types de ressources pris en charge avec leurs noms courts (shortnames), groupe d'API (API group), si elles sont cantonnées à un namespace (namespaced), et leur Genre (Kind):
kubectl api-resources
Autres opérations pour explorer les ressources de l'API :
kubectl api-resources --namespaced=true # Toutes les ressources cantonnées à un namespace
kubectl api-resources --namespaced=false # Toutes les ressources non cantonnées à un namespace
kubectl api-resources -o name # Toutes les ressources avec un affichage simple (uniquement le nom de la ressource)
kubectl api-resources -o wide # Toutes les ressources avec un affichage étendu (alias "wide")
kubectl api-resources --verbs=list,get # Toutes les ressources prenant en charge les verbes de requête "list" et "get"
kubectl api-resources --api-group=extensions # Toutes les ressources dans le groupe d'API "extensions"
Formattage de l'affichage
Pour afficher les détails sur votre terminal dans un format spécifique, utilisez l'option -o
(ou --output
) avec les commandes kubectl
qui la prend en charge.
Format d'affichage | Description |
---|---|
-o=custom-columns=<spec> |
Affiche un tableau en spécifiant une liste de colonnes séparées par des virgules |
-o=custom-columns-file=<filename> |
Affiche un tableau en utilisant les colonnes spécifiées dans le fichier <filename> |
-o=json |
Affiche un objet de l'API formaté en JSON |
-o=jsonpath=<template> |
Affiche les champs définis par une expression jsonpath |
-o=jsonpath-file=<filename> |
Affiche les champs définis par l'expression jsonpath dans le fichier <filename> |
-o=name |
Affiche seulement le nom de la ressource et rien de plus |
-o=wide |
Affiche dans le format texte avec toute information supplémentaire, et pour des pods, le nom du noeud est inclus |
-o=yaml |
Affiche un objet de l'API formaté en YAML |
Exemples utilisant -o=custom-columns
:
# Toutes les images s'exécutant dans un cluster
kubectl get pods -A -o=custom-columns='DATA:spec.containers[*].image'
# Toutes les images excepté "k8s.gcr.io/coredns:1.6.2"
kubectl get pods -A -o=custom-columns='DATA:spec.containers[?(@.image!="k8s.gcr.io/coredns:1.6.2")].image'
# Tous les champs dans metadata quel que soit leur nom
kubectl get pods -A -o=custom-columns='DATA:metadata.*'
Plus d'exemples dans la documentation de référence de kubectl.
Verbosité de l'affichage de Kubectl et débogage
La verbosité de Kubectl est contrôlée par une des options -v
ou --v
suivie d'un entier représentant le niveau de log. Les conventions générales de logging de Kubernetes et les niveaux de log associés sont décrits ici.
Verbosité | Description |
---|---|
--v=0 |
Le minimum qui doit toujours être affiché à un opérateur. |
--v=1 |
Un niveau de log par défaut raisonnable si vous n'avez pas besoin de verbosité. |
--v=2 |
Informations utiles sur l'état stable du service et messages de logs importants qui peuvent être corrélés à des changements significatifs dans le système. C'est le niveau de log par défaut recommandé pour la plupart des systèmes. |
--v=3 |
Informations étendues sur les changements. |
--v=4 |
Verbosité de Debug. |
--v=6 |
Affiche les ressources requêtées. |
--v=7 |
Affiche les entêtes des requêtes HTTP. |
--v=8 |
Affiche les contenus des requêtes HTTP. |
--v=9 |
Affiche les contenus des requêtes HTTP sans les tronquer. |
A suivre
-
En savoir plus sur l'Aperçu de kubectl.
-
Voir les options kubectl.
-
Voir aussi les Conventions d'usage de kubectl pour comprendre comment l'utiliser dans des scripts réutilisables.
-
Voir plus d'aides-mémoire kubectl.
7.7.5 - Conventions d'utilisation de kubectl
Conventions d'utilisation recommandées pour kubectl
.
Utiliser kubectl
dans des scripts réutilisables
Pour une sortie stable dans un script :
- Demandez un des formats de sortie orienté machine, comme
-o name
,-o json
,-o yaml
,-o go-template
ou-o jsonpath
. - Spécifiez complètement la version. Par exemple,
jobs.v1.batch/monjob
. Cela va assurer que kubectl n'utilise pas sa version par défaut, qui risque d'évoluer avec le temps. - Ne vous basez pas sur un contexte, des préférences ou tout autre état implicite.
Bonnes pratiques
kubectl run
Pour que kubectl run
satisfasse l'infrastructure as code :
- Taggez les images avec un tag spécifique à une version et n'utilisez pas ce tag pour une nouvelle version. Par exemple, utilisez
:v1234
,v1.2.3
,r03062016-1-4
, plutôt que:latest
(Pour plus d'informations, voir Bonnes pratiques pour la configuration). - Capturez le script pour une image fortement paramétrée.
- Passez à des fichiers de configuration enregistrés dans un système de contrôle de source pour des fonctionnalités désirées mais non exprimables avec des flags de
kubectl run
.
Vous pouvez utiliser l'option --dry-run
pour prévisualiser l'objet qui serait envoyé à votre cluster, sans réellement l'envoyer.
kubectl
sont dépréciés. Voir la documentation de Kubernetes v1.17 pour une liste de générateurs et comment ils étaient utilisés.
Générateurs
Vous pouvez générer les ressources suivantes avec une commande kubectl, kubectl create --dry-run -o yaml
:
clusterrole Crée un ClusterRole.
clusterrolebinding Crée un ClusterRoleBinding pour un ClusterRole particulier.
configmap Crée une configmap à partir d'un fichier local, un répertoire ou une valeur litérale.
cronjob Crée un cronjob avec le nom spécifié.
deployment Crée un deployment avec le nom spécifié.
job Crée un job avec le nom spécifié.
namespace Crée un namespace avec le nom spécifié.
poddisruptionbudget Crée un pod disruption budget avec le nom spécifié.
priorityclass Crée une priorityclass avec le nom spécifié.
quota Crée un quota avec le nom spécifié.
role Crée un role avec une unique règle.
rolebinding Crée un RoleBinding pour un Role ou ClusterRole particulier.
secret Crée un secret en utilisant la sous-commande spécifiée.
service Crée un service en utilisant la sous-commande spécifiée.
serviceaccount Crée un service account avec le nom spécifié.
kubectl apply
- Vous pouvez utiliser
kubectl apply
pour créer ou mettre à jour des ressources. Pour plus d'informations sur l'utilisation dekubectl apply
pour la mise à jour de ressources, voir le livre Kubectl.
7.7.6 - kubectl
Synopsis
kubectl contrôle le manager d'un cluster Kubernetes
Vous trouverez plus d'informations ici : https://kubernetes.io/fr/docs/reference/kubectl/overview/
kubectl [flags]
Options
--add-dir-header | |
Si vrai, ajoute le répertoire du fichier à l'entête | |
--alsologtostderr | |
log sur l'erreur standard en plus d'un fichier | |
--application-metrics-count-limit int Défaut : 100 | |
Nombre max de métriques d'applications à stocker (par conteneur) | |
--as chaîne | |
Nom d'utilisateur à utiliser pour l'opération | |
--as-group tableauDeChaînes | |
Groupe à utiliser pour l'opération, ce flag peut être répété pour spécifier plusieurs groupes | |
--azure-container-registry-config chaîne | |
Chemin du fichier contenant les informations de configuration du registre de conteneurs Azure | |
--boot-id-file string Défaut : "/proc/sys/kernel/random/boot_id" | |
Liste séparée par des virgules de fichiers dans lesquels rechercher le boot-id. Utilise le premier trouvé. | |
--cache-dir chaîne Défaut: "/home/karen/.kube/http-cache" | |
Répertoire de cache HTTP par défaut | |
--certificate-authority chaîne | |
Chemin vers un fichier cert pour l'autorité de certification | |
--client-certificate chaîne | |
Chemin vers un fichier de certificat client pour TLS | |
--client-key chaîne | |
Chemin vers un fichier de clé client pour TLS | |
--cloud-provider-gce-lb-src-cidrs cidrs Défaut: 130.211.0.0/22,209.85.152.0/22,209.85.204.0/22,35.191.0.0/16 | |
CIDRs ouverts dans le firewall GCE pour le proxy de trafic LB & health checks | |
--cluster chaîne | |
Le nom du cluster kubeconfig à utiliser | |
--container-hints chaîne Défaut : "/etc/cadvisor/container_hints.json" | |
location du fichier hints du conteneur | |
--containerd chaîne Défaut : "/run/containerd/containerd.sock" | |
Point de terminaison de containerd | |
--containerd-namespace chaîne Défaut : "k8s.io" | |
namespace de containerd | |
--context chaîne | |
Le nom du contexte kubeconfig à utiliser | |
--default-not-ready-toleration-seconds int Défaut: 300 | |
Indique les tolerationSeconds de la tolérance pour notReady:NoExecute qui sont ajoutées par défaut à tous les pods qui n'ont pas défini une telle tolérance | |
--default-unreachable-toleration-seconds int Défaut: 300 | |
Indique les tolerationSeconds de la tolérance pour unreachable:NoExecute qui sont ajoutées par défaut à tous les pods qui n'ont pas défini une telle tolérance | |
--disable-root-cgroup-stats | |
Désactive la collecte des stats du Cgroup racine | |
--docker chaîne Défaut : "unix:///var/run/docker.sock" | |
Point de terminaison docker | |
--docker-env-metadata-whitelist chaîne | |
une liste séparée par des virgules de variables d'environnement qui doivent être collectées pour les conteneurs docker | |
--docker-only | |
Remonte uniquement les stats Docker en plus des stats racine | |
--docker-root chaîne Défaut : "/var/lib/docker" | |
DÉPRÉCIÉ : la racine de docker est lue depuis docker info (ceci est une solution de secours, défaut : /var/lib/docker) | |
--docker-tls | |
utiliser TLS pour se connecter à docker | |
--docker-tls-ca chaîne Défaut : "ca.pem" | |
chemin vers CA de confiance | |
--docker-tls-cert chaîne Défaut : "cert.pem" | |
chemin vers le certificat client | |
--docker-tls-key chaîne Défaut : "key.pem" | |
chemin vers la clef privée | |
--enable-load-reader | |
Activer le lecteur de la charge CPU | |
--event-storage-age-limit chaîne Défaut : "default=0" | |
Durée maximale pendant laquelle stocker les événements (par type). La valeur est une liste séparée par des virgules de clefs/valeurs, où les clefs sont des types d'événements (par ex: creation, oom) ou "default" et la valeur est la durée. La valeur par défaut est appliquée à tous les types d'événements non spécifiés | |
--event-storage-event-limit chaîne Défaut : "default=0" | |
Nombre max d'événements à stocker (par type). La valeur est une liste séparée par des virgules de clefs/valeurs, où les clefs sont les types d'événements (par ex: creation, oom) ou "default" et la valeur est un entier. La valeur par défaut est appliquée à tous les types d'événements non spécifiés | |
--global-housekeeping-interval durée Défaut : 1m0s | |
Intevalle entre ménages globaux | |
-h, --help | |
aide pour kubectl | |
--housekeeping-interval durée Défaut : 10s | |
Intervalle entre ménages des conteneurs | |
--insecure-skip-tls-verify | |
Si vrai, la validité du certificat du serveur ne sera pas vérifiée. Ceci rend vos connexions HTTPS non sécurisées | |
--kubeconfig chaîne | |
Chemin du fichier kubeconfig à utiliser pour les requêtes du CLI | |
--log-backtrace-at traceLocation Défaut: :0 | |
lorsque les logs arrivent à la ligne fichier:N, émet une stack trace | |
--log-cadvisor-usage | |
Activer les logs d'usage du conteneur cAdvisor | |
--log-dir chaîne | |
Si non vide, écrit les fichiers de log dans ce répertoire | |
--log-file chaîne | |
Si non vide, utilise ce fichier de log | |
--log-file-max-size uint Défaut : 1800 | |
Définit la taille maximale d'un fichier de log. L'unité est le mega-octet. Si la valeur est 0, la taille de fichier maximale est illimitée. | |
--log-flush-frequency durée Défaut: 5s | |
Nombre de secondes maximum entre flushs des logs | |
--logtostderr Défaut: true | |
log sur l'erreur standard plutôt que dans un fichier | |
--machine-id-file chaîne Défaut : "/etc/machine-id,/var/lib/dbus/machine-id" | |
liste séparée par des virgules de fichiers dans lesquels rechercher le machine-id. Utiliser le premier trouvé. | |
--match-server-version | |
La version du serveur doit correspondre à la version du client | |
-n, --namespace chaîne | |
Si présent, la portée de namespace pour la requête du CLI | |
--password chaîne | |
Mot de passe pour l'authentification de base au serveur d'API | |
--profile chaîne Défaut: "none" | |
Nom du profil à capturer. Parmi (none|cpu|heap|goroutine|threadcreate|block|mutex) | |
--profile-output chaîne Défaut: "profile.pprof" | |
Nom du fichier dans lequel écrire le profil | |
--request-timeout chaîne Défaut: "0" | |
La durée à attendre avant d'abandonner une requête au serveur. Les valeurs non égales à zéro doivent contenir une unité de temps correspondante (ex 1s, 2m, 3h). Une valeur à zéro indique de ne pas abandonner les requêtes | |
-s, --server chaîne | |
L'adresse et le port de l'API server Kubernetes | |
--skip-headers | |
Si vrai, n'affiche pas les entêtes dans les messages de log | |
--skip-log-headers | |
Si vrai, évite les entêtes lors de l'ouverture des fichiers de log | |
--stderrthreshold sévérité Défaut: 2 | |
logs à cette sévérité et au dessus de ce seuil vont dans stderr | |
--storage-driver-buffer-duration durée Défaut : 1m0s | |
Les écritures dans le driver de stockage seront bufferisés pour cette durée, et seront envoyés aux backends non-mémoire en une seule transaction | |
--storage-driver-db chaîne Défaut : "cadvisor" | |
nom de la base de données | |
--storage-driver-host chaîne Défaut : "localhost:8086" | |
hôte:port de la base de données | |
--storage-driver-password chaîne Défaut : "root" | |
Mot de passe de la base de données | |
--storage-driver-secure | |
utiliser une connexion sécurisée avec la base de données | |
--storage-driver-table chaîne Défaut : "stats" | |
Nom de la table dans la base de données | |
--storage-driver-user chaîne Défaut : "root" | |
nom d'utilisateur de la base de données | |
--token chaîne | |
Bearer token pour l'authentification auprès de l'API server | |
--update-machine-info-interval durée Défaut : 5m0s | |
Intevalle entre mises à jour des infos machine. | |
--user chaîne | |
Le nom de l'utilisateur kubeconfig à utiliser | |
--username chaîne | |
Nom d'utilisateur pour l'authentification de base au serveur d'API | |
-v, --v Niveau | |
Niveau de verbosité des logs | |
--version version[=true] | |
Affiche les informations de version et quitte | |
--vmodule moduleSpec | |
Liste de settings pattern=N séparés par des virgules pour le logging filtré par fichiers |
See Also
- kubectl alpha - Commandes pour fonctionnalités alpha
- kubectl annotate - Met à jour les annotations d'une ressource
- kubectl api-resources - Affiche les ressources de l'API prises en charge sur le serveur
- kubectl api-versions - Affiche les versions de l'API prises en charge sur le serveur, sous la forme "groupe/version"
- kubectl apply - Applique une configuration à une ressource depuis un fichier ou stdin
- kubectl attach - Attache à un conteneur en cours d'exécution
- kubectl auth - Inspecte les autorisations
- kubectl autoscale - Auto-scale un Deployment, ReplicaSet, ou ReplicationController
- kubectl certificate - Modifie des ressources certificat
- kubectl cluster-info - Affiche les informations du cluster
- kubectl completion - Génère le code de complétion pour le shell spécifié (bash ou zsh)
- kubectl config - Modifie les fichiers kubeconfig
- kubectl convert - Convertit des fichiers de config entre différentes versions d'API
- kubectl cordon - Marque un nœud comme non assignable (unschedulable)
- kubectl cp - Copie des fichiers et répertoires depuis et vers des conteneurs
- kubectl create - Crée une ressource depuis un fichier ou stdin
- kubectl delete - Supprime des ressources par fichiers ou stdin, par ressource et nom, ou par ressource et sélecteur de label
- kubectl describe - Affiche les informations d'une ressource spécifique ou d'un groupe de ressources
- kubectl diff - Différence entre la version live et la version désirée
- kubectl drain - Draine un nœud en préparation d'une mise en maintenance
- kubectl edit - Édite une ressource du serveur
- kubectl exec - Exécute une commande dans un conteneur
- kubectl explain - Documentation sur les ressources
- kubectl expose - Prend un replication controller, service, deployment ou pod et l'expose comme un nouveau Service Kubernetes
- kubectl get - Affiche une ou plusieurs ressources
- kubectl kustomize - Construit une cible kustomization à partir d'un répertoire ou d'une URL distante.
- kubectl label - Met à jour les labels d'une ressource
- kubectl logs - Affiche les logs d'un conteneur dans un pod
- kubectl options - Affiche la liste des flags hérités par toutes les commandes
- kubectl patch - Met à jour un ou plusieurs champs d'une ressource par merge patch stratégique
- kubectl plugin - Fournit des utilitaires pour interagir avec des plugins
- kubectl port-forward - Redirige un ou plusieurs ports vers un pod
- kubectl proxy - Exécute un proxy vers l'API server Kubernetes
- kubectl replace - Remplace une ressource par fichier ou stdin
- kubectl rollout - Gère le rollout d'une ressource
- kubectl run - Exécute une image donnée dans le cluster
- kubectl scale - Définit une nouvelle taille pour un Deployment, ReplicaSet ou Replication Controller
- kubectl set - Définit des fonctionnalités spécifiques sur des objets
- kubectl taint - Met à jour les marques (taints) sur un ou plusieurs nœuds
- kubectl top - Affiche l'utilisation de ressources matérielles (CPU/Memory/Storage)
- kubectl uncordon - Marque un nœud comme assignable (schedulable)
- kubectl version - Affiche les informations de version du client et du serveur
- kubectl wait - Expérimental : Attend une condition particulière sur une ou plusieurs ressources
7.8 - Référence sur les outils en ligne de commande
8 - Contribuer à la documentation Kubernetes
Si vous souhaitez contribuer à la documentation ou au site Web de Kubernetes, nous serons ravis de vous aider! Tout le monde peut contribuer, que vous soyez nouveau dans le projet ou que vous y travailliez depuis longtemps, et que vous vous identifiez vous-même en tant que développeur, utilisateur final ou quelqu'un qui ne supporte tout simplement pas les fautes de frappe.
Pour vous impliquer de plusieurs façons dans la communauté Kubernetes ou d’en savoir plus sur nous, visitez le Site de la communauté Kubernetes. Pour plus d'informations sur le guide de style de la documentation Kubernetes, reportez-vous à la section style guide.
Types de contributeurs
- Un membre de l'organisation Kubernetes qui a signé le CLA et contribué un peu de temps et d'efforts au projet. Voir Adhésion à la communauté pour des critères spécifiques d'adhésion.
- Un SIG Docs relecteur est un membre de l'organisation Kubernetes qui
a exprimé son intérêt pour l'examen des Pull Requests de la documentation et qui a été ajouté au groupe GitHub approprié et aux fichiers
OWNERS
dans le dépôt GitHub, par un approbateur SIG Docs. - Un SIG Docs approbateur est un membre en règle qui a démontré un engagement continu envers le projet. Un approbateur peut fusionner des Pull Requests et publier du contenu au nom de l'organisation Kubernetes. Les approbateurs peuvent également représenter les documents SIG dans la communauté plus large de Kubernetes. Certaines des tâches d’un approbateur SIG Docs, telles que la coordination d’une publication, nécessitent un temps considérable.
Façons de contribuer
Cette liste est divisée en tâches accessibles à tous, ou juste aux membres de l'organisation Kubernetes, ou encore en tâches requérant un haut niveau d'autorisation et de familiarité avec les processus SIG Docs. Contribuer de manière constante au fil du temps peut vous aider à comprendre certaines des décisions relatives à l’outillage et à l’organisation qui ont déjà été prises.
Il ne s'agit pas d'une liste exhaustive des manières dont vous pouvez contribuer à la documentation de Kubernetes, mais cela devrait vous aider à démarrer.
- N'importe qui
- Remplir des rapports d'anomalie reproductibles
- Membre
- Améliorer la documentation existante
- Proposer des idées d'améliorations sur Slack ou sur la liste de diffusion SIG docs
- Améliorer l'accessibilité de la documentation
- Fournir des commentaires non contraignants sur les PRs
- Écrire un article de blog ou une étude de cas
- Relecteur
- Documenter les nouvelles fonctionnalités
- Trier et classer les problèmes
- Relire des PRs
- Créez des diagrammes, des ressources graphiques et des vidéos / capture vidéo d'écran incorporables
- Localisation
- Contribuer à d'autres dépôts en tant que représentant de la documentation
- Éditer des chaînes pour l'utilisateur dans le code
- Améliorer les commentaires dans le code, Godoc
- Approbateur
- Publier le contenu des contributeurs en approuvant et en fusionnant les PRs
- Participer à une équipe de publication de Kubernetes en tant que représentant de la documentation
- Proposer des améliorations au guide de style
- Proposer des améliorations aux tests de documentation
- Proposer des améliorations au site Web de Kubernetes ou à d'autres outils
8.1 - Commencez à contribuer
Si vous souhaitez commencer à contribuer à la documentation de Kubernetes, cette page et les rubriques associées peuvent vous aider à démarrer. Vous n'avez pas besoin d'être un développeur ou un rédacteur technique pour avoir un impact important sur la documentation et l'expérience utilisateur de Kubernetes ! Tout ce dont vous avez besoin pour les sujets de cette page est un compte GitHub et un navigateur web.
Si vous recherchez des informations sur la façon de commencer à contribuer aux référentiels de code Kubernetes, reportez-vous à la section sur les directives de la communauté Kubernetes.
Les bases de notre documentation
La documentation de Kubernetes est écrite en Markdown puis traitée et déployée à l’aide de Hugo.
Le code source est sur GitHub: https://github.com/kubernetes/website.
La majeure partie de la documentation anglaise est stockée dans /content/en/docs/
.
Une partie de la documentation de référence est automatiquement générée à partir de scripts du répertoire update-imported-docs/
.
Vous pouvez trier les demandes, modifier le contenu et passer en revue les modifications des autres, le tout à partir du site Web de GitHub. Vous pouvez également utiliser l'historique intégré et les outils de recherche de GitHub.
Toutes les tâches ne peuvent pas être effectuées dans l’interface utilisateur GitHub, mais elles sont décrites dans les guides de contribution intermédiaire et avancé.
Participer à SIG Docs
La documentation de Kubernetes est gérée par un groupe d'intérêt spécial (Special Interest Group (SIG)) appelé SIG Docs. Nous communiquons via un canal Slack, une liste de diffusion et des réunions vidéo hebdomadaires. Les nouveaux participants sont les bienvenus. Pour plus d'informations, voir Participer au SIG-docs.
Guides de style
Nous maintenons un guide de style avec des informations sur les choix de la communauté SIG Docs concernant la grammaire, la syntaxe, le format des sources et les conventions typographiques. Avant de faire votre première contribution, parcourez le guide de style et utilisez-le lorsque vous avez des questions.
Les modifications apportées au guide de style sont effectuées par SIG Docs en tant que groupe. Pour proposer un changement ou un ajout, ajoutez-le à l'ordre du jour pour une réunion à venir sur les documents SIG et assister à la réunion pour participer à la discussion. Voir le sujet contribution avancée pour plus d'informations.
Modèle de page
Nous utilisons des modèles de page pour contrôler la présentation de nos pages de documentation. Assurez-vous de comprendre le fonctionnement de ces modèles en consultant Utilisation de modèles de page.
Shortcodes Hugo
La documentation de Kubernetes est convertie de Markdown à HTML avec Hugo. Nous utilisons les shortcodes standard Hugo, ainsi que quelques-uns qui sont personnalisés dans la documentation Kubernetes. Voyez "Shortcodes Hugo personnalisés" pour savoir comment les utiliser.
Multilingue
La source de la documentation est disponible en plusieurs langues dans /content/
.
Chaque langue a son propre dossier avec un code à deux lettres déterminé par le standard ISO 639-1.
Par exemple, la source de la documentation anglaise est stockée dans /content/en/docs/
.
Pour plus d'informations sur la contribution à la documentation dans plusieurs langues, consultez "Traduire le contenu" dans le guide de contribution intermédiaire.
Si vous souhaitez démarrer une nouvelle traduction, voir "Traduction".
Créer des demandes recevables
Toute personne possédant un compte GitHub peut soumettre un problème (rapport de bogue) à la documentation de Kubernetes. Si vous voyez quelque chose qui ne va pas, même si vous ne savez pas comment le réparer, ouvrez un ticket. L'exception à cette règle est un petit bug, comme une faute de frappe, que vous souhaitez réparer vous-même. Dans ce cas, vous pouvez plutôt le réparer sans déposer un bogue d'abord.
Comment ouvrir un ticket
-
Sur une page existante
Si vous voyez un problème dans une page existante de la documentation Kubernetes, allez au bas de la page et cliquez sur le bouton Create an Issue. Si vous n'êtes pas actuellement connecté à GitHub, connectez-vous. Un formulaire de ticket GitHub apparaît avec du contenu pré-rempli.
À l’aide de Markdown, renseignez autant de détails que possible. Aux endroits où vous voyez des crochets vides (
[ ]
), mettre unx
entre les crochets qui représente le choix approprié. Si vous avez une solution proposée pour résoudre le problème, ajoutez-la. -
Demander une nouvelle page
Si vous pensez que du contenu est manquant, mais que vous ne savez pas où il doit aller ou si vous pensez qu'il ne correspond pas aux pages existantes, vous pouvez toujours ouvrir un ticket. Vous pouvez soit choisir une page existante à proximité du lieu où le nouveau contenu doit aller et classer le problème à partir de cette page, soit aller directement à https://github.com/kubernetes/website/issues/new/ et déposer le problème à partir de là.
Comment créer de bons tickets
Pour nous assurer que nous comprenons votre problème et pouvons y donner suite, gardez à l’esprit ces directives:
-
Utilisez le modèle de ticket et renseignez autant de détails que possible.
-
Expliquez clairement l’impact spécifique du problème sur les utilisateurs.
-
Limiter la portée d'un problème à une unité de travail raisonnable. Pour les problèmes de grande envergure, décomposez-les en problèmes plus petits.
Par exemple, "Corriger les docs de sécurité" n'est pas une question pouvant donner lieu à une action, mais "Ajouter des détails au thème 'Restreindre l'accès au réseau'" pourrait l'être.
-
Si la demande concerne un autre problème ou une pull request, vous pouvez y faire référence soit par son URL complète, soit par le problème ou par un numéro de demande d'extraction précédé du caractère "#". Par exemple,
Introduced by #987654
. -
Soyez respectueux et restez constructif. Par exemple, "La documentation sur X est nulle" n'est ni utile ni constructif. Le Code de conduite s'applique également aux interactions sur les dépôts Kubernetes GitHub.
Participer aux discussions SIG Docs
L'équipe SIG Docs communique à l'aide des mécanismes suivants:
- Rejoindre l'instance Slack de Kubernetes, puis rejoignez le canal
#sig-docs
, où nous discutons des problèmes de documentation en temps réel. Présentez-vous quand vous arrivez! - Rejoignez la liste de diffusion
kubernetes-sig-docs
, où des discussions plus larges ont lieu et où les décisions officielles sont enregistrées. - Participer à l'hebdomadaire SIG Docs, une réunion vidéo, qui est annoncée sur le canal Slack et la liste de diffusion. Actuellement, ces réunions ont lieu sur Zoom. Vous devez donc télécharger le logiciel Zoom ou rejoindre la conférence par téléphone.
- Pour les utilisateurs francophones, vous pouvez également rejoindre le canal Slack
#kubernetes-docs-fr
, où nous discutons des traductions en Français de la documentation de Kubernetes.
Améliorer le contenu existant
Pour améliorer le contenu existant, vous déposez une pull request (PR) après avoir créé un fork. Ces deux termes sont spécifiques à GitHub. Pour les besoins de cette rubrique, vous n'avez pas besoin de tout savoir à leur sujet, car vous pouvez tout faire à l'aide de votre navigateur Web. Quand vous passerez au Guide des contributeurs docs intermédiaires, vous aurez besoin de plus de connaissances en terminologie Git.
Signer le CLA
Avant de pouvoir apporter du code ou de la documentation à Kubernetes, vous devez lire le Guide du contributeur et signer le Contributor License Agreement (CLA). Ne vous inquiétez pas, cela ne prend pas longtemps !
Trouvez quelque chose sur lequel travailler
Si vous voyez quelque chose que vous souhaitez réparer immédiatement, suivez simplement les instructions ci-dessous. Vous n'avez pas besoin d'ouvrir un ticket (bien que vous puissiez aussi).
Si vous souhaitez commencer par trouver un problème existant sur lequel travailler, allez à https://github.com/kubernetes/website/issues et chercher des problèmes avec le label good first issue
(vous pouvez utiliser ce raccourci).
Lisez tous les commentaires et assurez-vous qu’il n’y a pas de pull request existante pour ce même problème et que personne n’a laissé de commentaire indiquant qu’ils travaillent sur le problème récemment (une durée de 3 jours est une bonne règle).
Laissez un commentaire indiquant que vous souhaitez travailler sur la question.
Choisissez quelle branche Git utiliser
L'aspect le plus important de la soumission d'une pull request c'est choisir la branche sur laquelle baser votre travail. Utilisez ces directives pour prendre la décision:
- Utilisez
master
pour résoudre les problèmes de contenu déjà publié ou pour améliorer le contenu déjà existant.- Utiliser une branche de publication (tel que
dev-release-1.23
pour le release-1.23 release) pour documenter les fonctionnalités ou modifications à venir pour une version à venir non encore publiée.
- Utiliser une branche de publication (tel que
- Utilisez une branche de fonctionnalités approuvée par SIG Docs pour collaborer à de grandes améliorations ou modifications de la documentation existante, y compris la réorganisation du contenu ou des modifications apportées à l'apparence du site Web.
Si vous ne savez toujours pas quelle branche choisir, demandez #sig-docs
sur Slack ou assistez à une réunion hebdomadaire de documents SIG pour obtenir des précisions.
Soumettre une pull request
Suivez ces étapes pour soumettre une pull request afin d'améliorer la documentation de Kubernetes.
-
Sur la page où vous voyez le problème, cliquez sur l'icône en forme de crayon en haut à gauche. Une nouvelle page apparaît avec un texte d'aide.
-
Cliquez sur le premier bouton bleu, qui a le texte Edit <page name>.
Si vous n'avez jamais créé de fork du dépôt de documentation Kubernetes, vous êtes invité à le faire. Créez le fork sous votre nom d'utilisateur GitHub, plutôt que celui d'une autre organisation dont vous pourriez être membre. Le fork a généralement une URL telle que
https://github.com/<nom d'utilisateur>/website
, à moins que vous n'ayez déjà un dépôt avec un nom en conflit (website).La raison pour laquelle vous êtes invité à créer un fork est que vous n'avez pas le droit de pousser une branche directement vers le dépôt Kubernetes officiel.
-
L'éditeur GitHub Markdown apparaît avec le fichier source Markdown chargé. Faites vos changements. Sous l'éditeur, remplissez le formulaire Propose file change. Le premier champ est le résumé de votre message de validation et ne doit pas dépasser 50 caractères. Le deuxième champ est facultatif, mais peut inclure plus de détails si nécessaire.
Note: Ne pas inclure de références à d’autres demandes GitHub ou pull requests dans votre message de commit. Vous pouvez les ajouter ultérieurement à la description de la demande d'extraction.Cliquez sur Propose file change. La modification est enregistrée en tant que commit dans une nouvelle branche de votre fork, qui porte automatiquement le nom suivant:
patch-1
. -
L’écran suivant récapitule les modifications que vous avez apportées en comparant votre nouvelle branche (les boîtes de sélection head fork et compare) à l'état actuel de base fork et base branche (
master
sur le dépôtkubernetes/website
par défaut). Vous pouvez modifier n'importe quelle boîte de sélection, mais ne le faites pas maintenant. Jetez un coup d’œil à la visionneuse de différences en bas de l’écran et, si tout se présente bien, cliquez sur Create pull request.Note: Si vous ne voulez pas créer la pull request maintenant, vous pouvez le faire plus tard, en accédant à l'URL principale du référentiel de site Web Kubernetes ou du référentiel de votre fork. Le site Web GitHub vous invitera à créer la pull request s'il détecte que vous avez poussé une nouvelle branche vers votre fork. -
L'écran Open a pull request apparaît. Le sujet de la pull request est identique au message du commit, mais vous pouvez le modifier si nécessaire. Le corps est rempli par le reste du message du commit (s'il est présent) et par un modèle. Lisez le modèle et remplissez les informations demandées, puis supprimez le texte supplémentaire. Laissez la case à cocher sélectionnée Allow edits from maintainers. Cliquez sur Create pull request.
Toutes nos félicitations ! Votre pull request est disponible dans Pull requests.
Après quelques minutes, vous pouvez prévisualiser le site Web contenant les modifications apportées par votre PR. Aller sur l'onglet Conversation de votre PR et cliquez sur le lien Details pour le déploiement
deploy/netlify
, près du bas de la page. Il s'ouvrira dans la même fenêtre. -
Attendez la revue. En général, les relecteurs sont suggérés par le
k8s-ci-robot
. Si un relecteur vous demande d’apporter des modifications, vous pouvez aller à l'onglet Files changed et cliquez sur l'icône en forme de crayon sur les fichiers modifiés par la pull request. Lorsque vous enregistrez le fichier modifié, un nouveau commit est créé dans la branche surveillée par la pull request. -
Si votre modification est acceptée, un relecteur fusionnera votre pull request, et le changement sera visible sur le site Web de Kubernetes quelques minutes plus tard.
Ce n’est qu’un des différents moyens de soumettre une pull request. Si vous êtes déjà un utilisateur expérimenté de Git et GitHub, vous pouvez utiliser une interface graphique locale ou un client Git en ligne de commande au lieu d'utiliser l'interface utilisateur de GitHub. Quelques notions de base sur l’utilisation du client Git en ligne de commande sont abordées dans la section intermédiaire du guide des contributeurs.
Relecture des pull requests de documentation
Les personnes qui ne sont pas encore des approbateurs ou des relecteurs peuvent quand même relire des pull requests. Leurs avis ne font pas autorité, ce qui signifie que ces avis seuls ne causeront pas une fusion de la pull request. Cependant, cela peut toujours être utile. Même si vous ne laissez aucun commentaire, vous pourrez avoir une idée des conventions des pull requests, de l'étiquette des interactions entre les différents membres et ainsi vous habituer au processus.
-
Allez à https://github.com/kubernetes/website/pulls. Vous verrez une liste de toutes les pull requests ouvertes visant site web Kubernetes et la documentation.
-
Par défaut, le seul filtre appliqué est
open
, donc vous ne voyez pas les pull requests qui ont déjà été fermées ou fusionnées. C'est une bonne idée d'appliquer le filtrecncf-cla: yes
, et pour votre premier examen, c'est une bonne idée d'ajoutersize/S
ousize/XS
. Le labelsize
est appliqué automatiquement en fonction du nombre de lignes de code que la PR modifie. Vous pouvez appliquer des filtres en utilisation les boites de sélection en haut de la page, ou utilisez directement ce raccourci pour voir seulement les petites PRs. Tous les filtres sont combinés (opérateurAND
), de sorte que vous ne pouvez pas recherchersize/XS
etsize/S
dans la même requête. -
Allez à l'onglet Files changed. Parcourez les modifications introduites dans la PR et, le cas échéant, les problèmes liés. Si vous constatez un problème ou des améliorations à apporter, passez la souris sur la ligne et cliquez sur le symbole
+
qui apparaît.Vous pouvez taper un commentaire et choisir soit Add single comment ou Start a review. En règle générale, il est préférable de commencer une revue, car elle vous permet de laisser plusieurs commentaires et d’avertir le propriétaire de la PR uniquement lorsque vous avez terminé la revue, plutôt qu'envoyer une notification distincte pour chaque commentaire.
-
Lorsque vous avez terminé, cliquez sur Review changes en haut de la page. Vous pouvez résumer votre avis et choisir de commenter, approuver ou demander des modifications. Les nouveaux contributeurs doivent toujours choisir Comment.
Merci d'avoir commenté une pull request !
Lorsque vous débutez dans le projet, il est judicieux de demander votre avis sur votre pull request.
Le canal Slack #sig-docs
est un excellent endroit pour faire cela.
Écrire un article dans le blog
Tout le monde peut écrire un article et le soumettre pour examen. Les articles ne doivent pas être de nature commerciale et doivent comporter un contenu qui s’appliquera de manière large à la communauté Kubernetes.
Pour soumettre un article, vous pouvez soit le soumettre en utilisant le Formulaire de soumission de blog Kubernetes, soit en suivant les étapes ci-dessous :
- Signez le CLA si vous ne l'avez pas encore fait.
- Consultez le format Markdown pour les articles de blog existants dans le dépôt du site web.
- Rédigez votre article dans l'éditeur de texte de votre choix.
- Sur le même lien à partir de l'étape 2, cliquez sur le bouton Create new file. Collez votre contenu dans l'éditeur. Nommez le fichier pour qu'il corresponde au titre proposé de l'article, mais ne mettez pas la date dans le nom du fichier. Les réviseurs de blog travailleront avec vous sur le nom de fichier final et la date de publication du blog.
- Lorsque vous enregistrez le fichier, GitHub vous guidera à travers le processus d'une pull request.
- Un critique de publication de blog examinera votre soumission et travaillera avec vous sur les commentaires et les détails finaux. Lorsque l'article du blog est approuvé, la publication du blog est planifiée.
Soumettre une étude de cas
Des études de cas montrent comment les entreprises utilisent Kubernetes pour résoudre des problèmes concrets. Elles sont écrites en collaboration avec l'équipe marketing de Kubernetes, qui est gérée par la CNCF.
Regardez la source des études de cas existantes. Utilisez le Formulaire de soumission d'étude de cas Kubernetes pour soumettre votre proposition.
A suivre
Si vous êtes à l'aise avec toutes les tâches décrites dans cette rubrique et que vous souhaitez vous engager plus profondément dans l'équipe de documentation de Kubernetes, lisez le guide de contribution de la documentation intermédiaire.
8.2 - Contributions avancées
Cette page suppose que vous avez lu et maîtrisé les sujets suivants : Commencez à contribuer et Contribution Intermédiaire et êtes prêts à apprendre plus de façons de contribuer. Vous devez utiliser Git et d'autres outils pour certaines de ces tâches.
Soyez le trieur de PR pendant une semaine
Les approbateurs SIG Docs peuvent être trieurs de Pull Request (PR).
Les approbateurs SIG Docs sont ajoutés au PR Wrangler rotation scheduler pour les rotations hebdomadaires. Les fonctions de trieur de PR incluent:
- Faire une revue quotidienne des nouvelles pull requests.
- Aidez les nouveaux contributeurs à signer le CLA et fermez toutes les PR où le CLA n'a pas été signé depuis deux semaines. Les auteurs de PR peuvent rouvrir la PR après avoir signé le CLA, c’est donc un moyen à faible risque de s’assurer que rien n’est merged sans un CLA signé.
- Fournir des informations sur les modifications proposées, notamment en facilitant les examens techniques des membres d'autres SIGs.
- Faire un merge des PRs quand elles sont prêtes, ou fermer celles qui ne devraient pas être acceptées.
- Triez et étiquetez les tickets entrants (Github Issues) chaque jour. Consultez Contributions Intermédiaires pour obtenir des instructions sur la manière dont SIG Docs utilise les métadonnées.
Requêtes Github utiles pour les trieurs
Les requêtes suivantes sont utiles lors des opérations de triage.
Après avoir utilisé ces trois requêtes, la liste restante de PRs devant être examinées est généralement petite.
Ces requêtes excluent spécifiquement les PRs de localisation, et n'incluent que la branche master
(sauf la derniere).
- Pas de CLA, non éligible au merge: Rappelez au contributeur de signer le CLA. S’ils ont déjà été rappelés à la fois par le bot et par un humain, fermez la PR et rappelez-leur qu'ils peuvent l'ouvrir après avoir signé le CLA. Nous ne pouvons même pas passer en revue les PR dont les auteurs n'ont pas signé le CLA !
- A besoin de LGTM: Si cela nécessite une révision technique, contactez l'un des réviseurs proposés par le bot. Si cela nécessite une révision de la documentation ou une édition, vous pouvez soit suggérer des modifications, soit ajouter un commit d'édition à la PR pour la faire avancer.
- A des LGTM, a besoin de docs approval: Voyez si vous pouvez comprendre ce qui doit se passer pour que la PR soit mergée.
- Not against master: Si c'est basé sur une branche
dev-
, c'est pour une release prochaine. Assurez vous que le release meister est au courant. Si elle se base sur une branche obsolète, aidez l'auteur de la PR à comprendre comment choisir la meilleure branche.
Proposer des améliorations
Les membres SIG Docs peuvent proposer des améliorations.
Après avoir contribué à la documentation de Kubernetes pendant un certain temps, vous pouvez avoir des idées pour améliorer le guide de style, les outils utilisés pour construire la documentation, le style du site, les processus de révision et faire un merge de pull requests, ou d'autres aspects de la documentation.
Pour une transparence maximale, ces types de propositions doivent être discutées lors d’une réunion SIG Docs ou sur la liste de diffusion kubernetes-sig-docs.
En outre, il peut être vraiment utile de situer le fonctionnement actuel et de déterminer les raisons pour lesquelles des décisions antérieures ont été prises avant de proposer des changements radicaux.
Le moyen le plus rapide d’obtenir des réponses aux questions sur le fonctionnement actuel de la documentation est de le demander dans le canal #sig-docs
sur le Slack officiel kubernetes.slack.com
Une fois que la discussion a eu lieu et que le SIG est d'accord sur le résultat souhaité, vous pouvez travailler sur les modifications proposées de la manière la plus appropriée. Par exemple, une mise à jour du guide de style ou du fonctionnement du site Web peut impliquer l’ouverture d’une pull request, une modification liée aux tests de documentation peut impliquer de travailler avec sig-testing.
Coordonner la documentation pour une version de Kubernetes
Les approbateurs SIG Docs peuvent coordonner les tâches liées à la documentation pour une release de Kubernetes.
Chaque release de Kubernetes est coordonnée par une équipe de personnes participant au sig-release Special Interest Group (SIG). Les autres membres de l'équipe de publication pour une release donnée incluent un responsable général de la publication, ainsi que des représentants de sig-pm, de sig-testing et d'autres. Pour en savoir plus sur les processus de release de Kubernetes, reportez-vous à la section https://github.com/kubernetes/sig-release.
Le représentant de SIG Docs pour une release donnée coordonne les tâches suivantes:
- Surveillez le feature-tracking spreadsheet pour les fonctionnalités nouvelles ou modifiées ayant un impact sur la documentation. Si la documentation pour une fonctionnalité donnée ne sera pas prête pour la release, la fonctionnalité peut ne pas être autorisée à entrer dans la release.
- Assistez régulièrement aux réunions de sig-release et donnez des mises à jour sur l'état de la documentation pour la release.
- Consultez et copiez la documentation de la fonctionnalité rédigée par le SIG responsable de la mise en œuvre de la fonctionnalité.
- Mergez les pull requests liées à la release et maintenir la branche de fonctionnalité Git pour la version.
- Encadrez d'autres contributeurs SIG Docs qui souhaitent apprendre à jouer ce rôle à l'avenir. Ceci est connu comme "l'observation" (shadowing en anglais).
- Publiez les modifications de la documentation relatives à la version lorsque les artefacts de la version sont publiés.
La coordination d'une publication est généralement un engagement de 3 à 4 mois et les tâches sont alternées entre les approbateurs SIG Docs.
Parrainez un nouveau contributeur
Les relecteurs SIG Docs peuvent parrainer de nouveaux contributeurs.
Après que les nouveaux contributeurs aient soumis avec succès 5 pull requests significatives vers un ou plusieurs dépôts Kubernetes, ils/elles sont éligibles pour postuler à l'adhésion dans l'organisation Kubernetes. L'adhésion des contributeurs doit être soutenue par deux sponsors qui sont déjà des réviseurs.
Les nouveaux contributeurs docs peuvent demander des sponsors dans le canal #sig-docs sur le Slack Kubernetes ou sur la mailing list SIG Docs. Si vous vous sentez confiant dans le travail des candidats, vous vous portez volontaire pour les parrainer. Lorsqu’ils soumettent leur demande d’adhésion, répondez-y avec un "+1" et indiquez les raisons pour lesquelles vous estimez que les demandeurs sont des candidat(e)s valables pour devenir membre de l’organisation Kubernetes.
8.3 - Aperçu du style de documentation
Les rubriques de cette section fournissent des informations sur le style d'écriture, la mise en forme et l'organisation du contenu, ainsi que sur l'utilisation des personnalisations Hugo spécifiques à la documentation Kubernetes.
8.3.1 - Documentation Style Guide
Cette page donne des directives de style d'écriture pour la documentation de Kubernetes. Ce sont des lignes directrices, pas des règles. Faites preuve de discernement et n'hésitez pas à proposer des modifications à ce document dans le cadre d'une pull request.
Pour plus d'informations sur la création de nouveau contenu pour les documents Kubernetes, suivez les instructions surl'utilisation des templates et création d'une pull request de documentation.
Language
La documentation de Kubernetes utilise l'anglais américain comme langue de référence.
Normes de formatage de la documentation
Utilisez le camel case pour les objets d'API
Lorsque vous faites référence à un objet API, utilisez les mêmes lettres majuscules et minuscules que celles utilisées dans le nom d'objet réel. Typiquement, les noms des objets de l'API utilisent le camel case.
Ne divisez pas le nom de l'objet API en mots séparés. Par exemple, utilisez PodTemplateList, et pas Pod Template List.
Référez-vous aux objets de l'API sans dire "objet", à moins que l'omission de "objet" n'entraîne une construction maladroite.
À faire | À éviter |
---|---|
Le Pod dispose de deux conteneurs. | La pod a deux conteneurs. |
Le Deployment est responsable de ce qui suit ... | L'objet Déployment est responsable de ... |
Une PodList est une liste de Pod. | Une Pod List est une liste de pods. |
Les deux ContainerPorts ... | Les deux objets ContainerPort ... |
Les deux objets ContainerStateTerminated ... | Les deux ContainerStateTerminateds ... |
Use angle brackets for placeholders
Use angle brackets for placeholders. Tell the reader what a placeholder represents.
-
Affiche des informations sur un Pod :
kubectl describe pod <pod-name>
where
<pod-name>
is the name of one of your Pods.
Use bold for user interface elements
À faire | À éviter |
---|---|
Cliquez sur Fork. | Cliquez sur "Fork". |
Sélectionnez Other. | Sélectionnez 'Other'. |
Utiliser l'italique pour définir ou introduire de nouveaux termes.
À faire | À éviter |
---|---|
Un cluster est un ensemble de nœuds ... | Un "cluster" est un ensemble de nœuds ... |
Ces composantes forment le control plane. | Ces composantes forment le control plane. |
Utiliser un style de code pour les noms de fichiers, les répertoires et les chemins d'accès
À faire | À éviter |
---|---|
Open the envars.yaml file. | Open the envars.yaml file. |
Aller dans le répertoire /docs/tutorials . | Go to the /docs/tutorials directory. |
Open the /_data/concepts.yaml file. | Open the /_data/concepts.yaml file. |
Utiliser la norme internationale pour la ponctuation entre guillemets
À faire | À éviter |
---|---|
events are recorded with an associated "stage". | events are recorded with an associated "stage." |
The copy is called a "fork". | The copy is called a "fork." |
Inline code formatting
Use code style for inline code and commands
For inline code in an HTML document, use the <code>
tag. In a Markdown document, use the backtick (`).
À faire | À éviter |
---|---|
The kubectl run command creates a Deployment. | The "kubectl run" command creates a Deployment. |
For declarative management, use kubectl apply . | For declarative management, use "kubectl apply". |
Enclose code samples with triple backticks. (```) | Enclose code samples with any other syntax. |
Utiliser le style de code pour les noms de champs d'objets
À faire | À éviter |
---|---|
Set the value of the replicas field in the configuration file. | Définissez la valeur du champ "replicas" dans le fichier de configuration. |
The value of the exec field is an ExecAction object. | La valeur du champ "exec" est un objet ExecAction. |
Utiliser le style normal pour les chaînes de caractères et les valeurs de champs entiers
Pour les valeurs de champ de type chaîne de caractères ou entier, utilisez un style normal sans guillemets.
À faire | À éviter |
---|---|
Set the value of imagePullPolicy to Always. |
Set the value of imagePullPolicy to "Always". |
Set the value of image to nginx:1.8. |
Set the value of image to nginx:1.8 . |
Set the value of the replicas field to 2. |
Set the value of the replicas field to 2 . |
Code snippet formatting
Ne pas inclure l'invite de commande
À faire | À éviter |
---|---|
kubectl get pods | $ kubectl get pods |
Séparer les commandes de la sortie
Vérifiez que le Pod fonctionne sur le nœud que vous avez choisi :
kubectl get pods --output=wide
La sortie est similaire à celle-ci :
NAME READY STATUS RESTARTS AGE IP NODE
nginx 1/1 Running 0 13s 10.200.0.4 worker0
Versioning Kubernetes examples
Code examples and configuration examples that include version information should be consistent with the accompanying text.
If the information is version specific, the Kubernetes version needs to be defined in the prerequisites
section of the Task template or the [Tutorial template] (/docs/contribute/style/page-templates/#tutorial-template).
Once the page is saved, the prerequisites
section is shown as Before you begin.
Pour spécifier la version de Kubernetes pour une tâche ou une page de tutoriel, incluez min-kubernetes-server-version
dans l'entête de la page.
Si l'exemple YAML se trouve dans un fichier autonome, recherchez et passez en revue les sujets qui l'incluent comme référence. Vérifiez que toutes les rubriques utilisant le YAML autonome ont les informations de version appropriées définies. Si un fichier YAML autonome n'est référencé à partir d'aucun sujet, pensez à le supprimer au lieu de le mettre à jour.
Par exemple, si vous écrivez un tutoriel pertinent pour Kubernetes version 1.8, la première partie de votre fichier de démarque doit ressembler à ceci :
---
title: <your tutorial title here>
min-kubernetes-server-version: v1.8
---
Dans les exemples de code et de configuration, n'incluez pas de commentaires sur les versions alternatives. Veillez à ne pas inclure d'énoncés incorrects dans vos exemples sous forme de commentaires, tels que :
apiVersion: v1 # earlier versions use...
kind: Pod
...
Liste de mots Kubernetes.io
Une liste de termes et de mots spécifiques à Kubernetes à utiliser de manière cohérente sur le site.
Term | Usage |
---|---|
Kubernetes | Kubernetes a toujours une majuscule. |
Docker | Docker a toujours une majuscule. |
SIG Docs | SIG Docs plutôt que SIG-DOCS ou d'autres variantes. |
Shortcodes
Hugo Shortcodes help create different rhetorical appeal levels. Notre documentation prend en charge trois shortcodes différents dans cette catégorie : Note {{< note >}}, Mise en garde {{< caution >}}, et Avertissement {{< warning >}}.
-
Entourez le texte d'un raccourci d'ouverture et de fermeture.
-
Utilisez la syntaxe suivante pour appliquer un style :
{{< note >}} Il n'est pas nécessaire d'inclure un préfixe ; le shortcode fournit automatiquement (Note:, Caution:, etc.). {{< /note >}}
La sortie est :
Note
Utilisez {{< note *//>}} pour mettre en surbrillance un conseil ou une information qu'il peut être utile de connaître.
Par exemple :
{{</* note >}}
Vous pouvez _toujours_ utiliser Markdown à l'intérieur de ces légendes.
{{< /note >}}
La sortie est :
Mise en garde
Utilisez {{< caution *//>}} pour attirer l'attention sur une information importante afin d'éviter les pièges.
Par exemple :
{{</* caution >}}
Le style de légende ne s'applique qu'à la ligne directement au-dessus de la balise.
{{< /caution >}}
La sortie est :
Avertissement
Utilisez {{< warning *//>}} pour indiquer un danger ou une information cruciale à suivre.
Par exemple :
{{</* warning >}}
Méfiez-vous.
{{< /warning >}}
La sortie est :
Katacoda Embedded Live Environment
Ce bouton permet aux utilisateurs d'exécuter Minikube dans leur navigateur en utilisant le Katacoda Terminal. Il abaisse le seuil d'entrée en permettant aux utilisateurs d'utiliser Minikube en un seul clic au lieu de passer par l'ensemble du processus d'installation Minikube et Kubectl localement.
The Embedded Live Environment is configured to run minikube start
and lets users complete tutorials in the same window as the documentation.
For example:
{{< kat-button >}}
La sortie est :
Common Shortcode Issues
Ordered Lists
Un Shortcode interrompra les listes numérotées à moins que vous ne mettiez une indentation de 4 espaces avant l'avis et l'étiquette.
Par exemple :
1. Préchauffer le four à 350˚F
1. Préparer la pâte et la verser dans un moule à charnière.
{{< note >}}**Note:** Graisser la casserole pour de meilleurs résultats.{{< /note >}}
1. Cuire au four de 20 à 25 minutes ou jusqu'à ce que ce soit pris.
La sortie est :
-
Préchauffer le four à 350˚F
-
Préparer la pâte et la verser dans un moule à charnière.
Note: Graisser la casserole pour de meilleurs résultats. -
Cuire au four de 20 à 25 minutes ou jusqu'à ce que ce soit pris.
Expressions Includes
Les Shortcodes dans les expressions d'include brisera la compilation du site. Vous devez les insérer dans le document parent, avant et après avoir appelé l'include. Par exemple :
{{< note >}}
{{< include "task-tutorial-prereqs.md" >}}
{{< /note >}}
Meilleures pratiques en matière de contenu
Cette section contient des suggestions de pratiques exemplaires pour un contenu clair, concis et cohérent.
Utiliser le présent
À faire | À éviter |
---|---|
Cette commande lance un proxy. | Cette commande lancera un proxy. |
Exception : Utilisez le futur ou le passé s'il est nécessaire pour transmettre le sens correct.
Utiliser la voix active
À faire | À éviter |
---|---|
Vous pouvez explorer l'API à l'aide d'un navigateur. | L'API peut être explorée à l'aide d'un navigateur. |
Le fichier YAML spécifie le nombre de répliques. | Le nombre de répliques est spécifié dans le fichier YAML. |
Exception : Utilisez la voix passive si la voix active conduit à une construction maladroite.
Utiliser un langage simple et direct
Utilisez un langage simple et direct. Évitez d'utiliser des expressions inutiles, comme "s'il vous plaît".
À faire | À éviter |
---|---|
Pour créer un ReplicaSet, ... | Afin de créer un ReplicaSet, ... |
Voir le fichier de configuration. | Veuillez consulter le fichier de configuration. |
Voir les Pods. | Avec cette prochaine commande, nous allons voir les Pods. |
S'adresser au lecteur en tant que "vous"
À faire | À éviter |
---|---|
Vous pouvez créer un déploiement en ... | Nous allons créer un déploiement en ... |
Dans l'édition précédente, vous pouvez voir... | Dans la sortie précédente, on peut voir ... |
Évitez les phrases latines
Préférez les termes français aux abréviations latines.
À faire | À éviter |
---|---|
Par exemple, ... | e.g., ... |
C'est à dire, ... | i.e., ... |
Exception : Utilisez "etc." pour et cetera.
Tendances à éviter
Évitez d'utiliser "nous"
L'utilisation du "nous" dans une phrase peut prêter à confusion, car le lecteur pourrait ne pas savoir s'ils font partie du "nous" que vous décrivez.
À faire | À éviter |
---|---|
La version 1.4 comprend ... | Dans la version 1.4, nous avons ajouté ... |
Kubernetes offre une nouvelle fonctionnalité pour ... | Nous proposons une nouvelle fonctionnalité ... |
Cette page vous apprend à utiliser les Pods. | Dans cette page, nous allons en savoir plus sur les Pods. |
Évitez le jargon et les expressions idiomatiques
Certains lecteurs parlent le français comme seconde langue. Évitez le jargon et les expressions idiomatiques pour les aider à mieux comprendre.
À faire | À éviter |
---|---|
En interne, ... | Sous le capot, ... |
Créer un nouveau cluster. | Monter un nouveau cluster. |
Évitez les déclarations sur l'avenir
Évitez de faire des promesses ou de donner des conseils sur l'avenir. Si vous avez besoin de parler d'une fonctionnalité alpha, placez le texte sous un titre qui l'identifie comme une fonctionnalité alpha.
Évitez les déclarations qui seront bientôt périmées
Évitez les mots comme "actuellement" et "nouveau". Une caractéristique qui est nouvelle aujourd'hui pourrait ne pas être considérée comme nouvelle dans quelques mois.
À faire | À éviter |
---|---|
Dans la version 1.4, ... | Dans la version actuelle, ... |
La fonction de fédération offre ... | La nouvelle fonctionnalité de la Fédération offre ... |
A suivre
- En savoir plus sur writing a new topic.
- En savoir plus sur using page templates.
- En savoir plus sur staging your changes
- En savoir plus sur creating a pull request.
8.3.2 - Rédiger une nouveau sujet
Cette page montre comment créer un nouveau sujet pour la documentation Kubernetes.
Pré-requis
Créez un fork du dépôt de la documentation de Kubernetes comme décrit dans Commencez à contribuer.
Choisir un type de page
Alors que vous vous préparez à écrire un nouveau sujet, pensez au type de page qui convient le mieux à votre contenu :
Concept | Une page de concept explique certains aspects de Kubernetes. Par exemple, une page conceptuelle pourrait décrire l'objet Kubernetes `Déploiement` et expliquer le rôle qu'il joue en tant qu'application pendant son déploiement, sa mise à l'échelle, ou sa mise à jour. Généralement, les pages conceptuelles n'incluent pas de séquences d'étapes, mais fournissent plutôt des liens vers des tâches ou des tutoriels. Pour un exemple de sujet de concept, voir Noeuds. |
Tâche | Une page de tâches montre comment faire une seule chose. L'idée est de donner aux lecteurs une séquence d'étapes qu'ils peuvent suivre en lisant la page. Une page de tâches peut être courte ou longue, à condition qu'elle reste concentrée sur un domaine. Dans une page de tâches, il est acceptable de mélanger de brèves explications avec les étapes à effectuer, mais si vous avez besoin de fournir une longue explication, vous devriez le faire dans un sujet de concept. Les tâches et les concepts connexes devraient être reliés les uns aux autres. Pour un exemple d'une courte page de tâches, consultez Configurer un pod en utilisant un volume pour le stockage . Pour un exemple de page de tâches plus longue, voir Configure Liveness and Readiness Probes |
Tutoriel | Une page de tutoriel montre comment atteindre un objectif qui relie plusieurs fonctionnalités de Kubernetes. Un tutoriel peut fournir plusieurs séquences d'étapes que les lecteurs peuvent suivre en lisant la page. Ou il peut fournir des explications sur des éléments de code connexes. Par exemple, un tutoriel pourrait fournir un aperçu d'un exemple de code. Un tutoriel peut inclure de brèves explications sur les caractéristiques de Kubernetes qui sont liées entre elles, mais devrait comporter des liens vers des sujets de concepts connexes pour une explication approfondie des caractéristiques individuelles. |
Utilisez un modèle pour chaque nouvelle page. Chaque type de page a un template que vous pouvez utiliser lorsque vous écrivez votre sujet. L'utilisation de templates permet d'assurer la cohérence entre les sujets d'un type donné.
Choisir un titre et un nom de fichier
Choisissez un titre qui contient les mots-clés que vous voulez que les moteurs de recherche trouvent.
Créez un nom de fichier qui utilise les mots de votre titre séparés par des tirets.
Par exemple, le sujet avec titre Using an HTTP Proxy to Access the Kubernetes API has filename http-proxy-access-api.md
.
Vous n'avez pas besoin de mettre "kubernetes" dans le nom du fichier, car "kubernetes" est déjà dans l'URL du sujet, par exemple :
/docs/tasks/access-kubernetes-api/http-proxy-access-api/
Ajout du titre du sujet à l'entête
Dans votre sujet, insérez un champ title
dans l'entête frontmatter.
L'entête est le bloc YAML qui se trouve entre les lignes à trois tirets en haut de la page.
En voici un exemple :
---
title: Using an HTTP Proxy to Access the Kubernetes API
---
Choisir un répertoire
En fonction de votre type de page, placez votre nouveau fichier dans un sous-répertoire de l'un d'entre eux :
- /content/en/docs/tasks/
- /content/en/docs/tutorials/
- /content/en/docs/concepts/
Vous pouvez placer votre fichier dans un sous-répertoire existant ou en créer un nouveau.
Placer votre sujet dans la table des matières
La table des matières est construite dynamiquement en utilisant la structure de répertoire de la source de documentation.
Les répertoires de niveau supérieur sous /content/fr/docs/
créent une navigation de niveau supérieur, et les sous-répertoires ont chacun des entrées dans la table des matières.
Chaque sous-répertoire possède un fichier _index.md
, qui représente la page d'accueil du contenu d'un sous-répertoire donné.
Le _index.md
n'a pas besoin d'un template.
Il peut contenir une vue d'ensemble du contenu des rubriques du sous-répertoire.
Les autres fichiers d'un répertoire sont triés par ordre alphabétique par défaut.
Ce n'est presque jamais le meilleur ordre.
Pour contrôler le tri relatif des sujets dans un sous-répertoire, définissez la clé weight:
front-matter sur un entier.
Généralement, nous utilisons des multiples de 10, pour tenir compte de l'ajout de sujets plus tard.
Par exemple, un sujet ayant un poids de 10
sera précédé d'un sujet ayant un poids de 20
.
Intégrer du code dans votre sujet
Si vous voulez inclure du code dans votre sujet, vous pouvez incorporer le code dans votre fichier directement à l'aide de l'option de syntaxe de bloc de code de markdown. Ceci est recommandé dans les cas suivants (liste non exhaustive) :
- Le code indique la sortie d'une commande telle que
kubectl get deploy mydeployment -o json | jq '.status'
. - Le code n'est pas assez générique pour que les utilisateurs puissent l'essayer. Par exemple, vous pouvez intégrer le fichier YAML pour créer un Pod qui dépend d'une implementation Flexvolume spécifique.
- Le code est un exemple incomplet parce qu'il a pour but de mettre en évidence une partie d'un fichier plus volumineux. Par exemple, lorsque vous décrivez des façons de personnaliser l'attribut PodSecurityPolicy pour certaines raisons, vous pouvez fournir un court snippet directement dans le fichier.
- Le code n'est pas destiné à être testé par les utilisateurs pour d'autres raisons.
Par exemple, lorsque vous décrivez comment un nouvel attribut doit être ajouté à une ressource à l'aide de la commande
kubectl edit
, vous pouvez fournir un court exemple qui inclut seulement l'attribut à ajouter.
Inclure le code d'un autre fichier
Une autre façon d'inclure du code dans votre sujet est de créer un nouveau fichier d'exemple complet (ou un groupe de fichiers d'exemple), puis de référencer l'exemple de votre sujet. Utilisez cette méthode pour inclure des exemples de fichiers YAML lorsque l'échantillon est générique et réutilisable, et que vous voulez favoriser leur utilisation.
Lors de l'ajout d'un nouveau fichier d'exemple autonome, tel qu'un fichier YAML, placez le code dans l'un des sous-répertoires <LANG>/examples/
où <LANG>
est la langue utilisé dans votre page.
Dans votre fichier, utilisez le shortcode codenew
:
{{< codenew file="<RELPATH>/my-example-yaml>" >}}
où <RELPATH>
est le chemin vers le fichier à inclure, relatif au répertoire examples
.
Le shortcode Hugo suivant fait référence à un fichier YAML situé sur /content/en/examples/pods/storage/gce-volume.yaml
.
{{< codenew file="pods/storage/gce-volume.yaml" >}}
<
et avant les caractères >
.
Voir le code de cette page pour un exemple.
Montrer comment créer un objet API à partir d'un fichier de configuration
Si vous avez besoin de démontrer comment créer un objet API basé sur un fichier de configuration, placez le fichier de configuration dans l'un des sous-répertoires sous <LANG>/examples
.
Dans votre sujet, affichez cette commande :
kubectl create -f https://k8s.io/examples/pods/storage/gce-volume.yaml
<LANG>/examples
, assurez-vous que le fichier est également inclus dans le fichier <LANG>/examples_test.go
.
La CI pour le site Web exécute automatiquement ce scénario de test lorsque des PRs sont soumises pour s'assurer que tous les exemples réussissent les tests.
Pour un exemple d'un sujet qui utilise cette technique, voir Running a Single-Instance Stateful Application.
Ajouter des images à un sujet
Placez les fichiers images dans le répertoire /images
.
Le format d'image préféré est SVG.
A suivre
- En savoir plus sur l'utilisation des templates de pages.
- En savoir plus sur le staging de vos changements.
- En savoir plus sur la création d'une pull request.
8.3.3 - Utilisation des modèles de page
Lorsque vous ajoutez de nouveaux sujets, appliquez-leur l'un des templates suivants. Ceci standardise l'expérience utilisateur d'une page donnée.
Les templates de page sont dans le répertoire layouts/partials/templates
du dépôt kubernetes/website
.
Concept template
Une page de concept explique certains aspects de Kubernetes.
Par exemple, une page conceptuelle peut décrire l'objet Kubernetes Deployment
et expliquer le rôle qu'il joue en tant qu'application une fois qu'il est déployé, dimensionné et mis à jour.
Généralement, les pages conceptuelles n'incluent pas de séquences d'étapes, mais fournissent plutôt des liens vers des tâches ou des tutoriels.
Pour écrire une nouvelle page concept, créez un fichier Markdown dans un sous-répertoire du répertoire /content/fr/docs/concepts
, avec les caractéristiques suivantes :
-
Dans l'entête YAML de la page, définissez
content_type: concept
. -
Dans le corps de la page, définissez les variables
capture
requises et les variables optionnelles que vous voulez inclure :Variable Required? overview yes body yes whatsnext no Le corps de la page ressemblera à ceci (supprimez toutes les captures optionnelles dont vous n'avez pas besoin) :
{{% capture overview %}} {{% /capture %}} {{% capture body %}} {{% /capture %}} {{% capture whatsnext %}} {{% /capture %}}
-
Remplissez chaque section de contenu. Suivez ces lignes directrices :
- Organiser le contenu avec les rubriques H2 et H3.
- Pour
overview
, définir le contexte du sujet à l'aide d'un seul paragraphe. - Pour
body
, expliquer le concept. - Pour
whatsnext
, fournir une liste à puces de sujets (5 au maximum) pour en apprendre davantage sur le concept.
Annotations est un exemple publié du template de concept. Cette page utilise également le modèle de concept.
Template de tâche
Une page de tâches montre comment faire une seule chose, généralement en donnant une courte séquence d'étapes. Les pages de tâches ont une explication minimale, mais fournissent souvent des liens vers des sujets conceptuels qui fournissent un contexte et des connaissances connexes.
Pour écrire une nouvelle page de tâches, créez un fichier Markdown dans un sous-répertoire du répertoire /content/fr/docs/tasks
, avec les caractéristiques suivantes :
-
Dans l'entête YAML de la page, définissez
content_type: task
. -
Dans le corps de la page, définissez les variables
capture
requises et les variables optionnelles que vous voulez inclure :Variable Required? overview yes prerequisites yes steps no discussion no whatsnext no Le corps de la page ressemblera à ceci (supprimez toutes les captures optionnelles dont vous n'avez pas besoin) :
{{% capture overview %}} {{% /capture %}} {{% capture prerequisites %}} {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} {{% /capture %}} {{% capture steps %}} {{% /capture %}} {{% capture discussion %}} {{% /capture %}} {{% capture whatsnext %}} {{% /capture %}}
-
Dans chaque section, écrivez votre contenu. Suivez les directives suivantes :
- Utilisez un minimum d'en-têtes H2 (avec deux caractères
#
en tête de liste). Les sections elles-mêmes sont intitulées automatiquement par le modèle. - Pour
overview
, utilisez un paragraphe pour définir le contexte de l'ensemble du sujet. - Pour
prerequisites
, utiliser des listes à puces dans la mesure du possible. Commencez à ajouter des prérequis supplémentaires sous la baliseinclude
. Les conditions préalables par défaut incluent un cluster Kubernetes en cours d'exécution. - Pour
steps
, utiliser des listes numérotées. - Pour la discussion, utilisez le contenu normal pour développer l'information couverte dans la section
steps
. - Pour
whatsnext
, donnez une liste de 5 sujets au maximum qui peuvent être intéressant à lire ensuite.
- Utilisez un minimum d'en-têtes H2 (avec deux caractères
Voici un exemple de sujet publié qui utilise le template de tasks Using an HTTP proxy to access the Kubernetes API.
Tutorial template
Une page de tutoriel montre comment atteindre un objectif qui est plus grand qu'une seule tâche. Typiquement, une page de tutoriel comporte plusieurs sections, chacune d'entre elles ayant une séquence d'étapes. Par exemple, un tutoriel pourrait fournir un aperçu d'un exemple de code qui illustre une certaine caractéristique de Kubernetes. Les didacticiels peuvent inclure des explications au niveau de la surface, mais devraient être reliés à des sujets connexes sur les concepts pour des explications approfondies.
Pour écrire une nouvelle page de tutoriel, créez un fichier Markdown dans un sous-répertoire du répertoire /content/fr/docs/tutorials
, avec les caractéristiques suivantes :
-
Dans l'entête YAML de la page, définissez
content_type: tutorial
. -
Dans le corps de la page, définissez les variables
capture
requises et les variables optionnelles que vous voulez inclure :Variable Required? overview yes prerequisites yes objectives yes lessoncontent yes cleanup no whatsnext no Le corps de la page ressemblera à ceci (supprimez toutes les captures optionnelles dont vous n'avez pas besoin) :
{{% capture overview %}} {{% /capture %}} {{% capture prerequisites %}} {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} {{% /capture %}} {{% capture objectives %}} {{% /capture %}} {{% capture lessoncontent %}} {{% /capture %}} {{% capture cleanup %}} {{% /capture %}} {{% capture whatsnext %}} {{% /capture %}}
-
Dans chaque section, écrivez votre contenu. Suivez les directives suivantes :
- Utilisez un minimum d'en-têtes H2 (avec deux caractères
#
en tête de liste). Les sections elles-mêmes sont intitulées automatiquement par le template. - Pour
overview
, utiliser un paragraphe pour définir le contexte de l'ensemble du sujet. - Pour
prerequisites
, utiliser des listes à puces dans la mesure du possible. Ajoutez des prérequis supplémentaires en dessous de ceux inclus par défaut. - Pour
objectives
, utiliser des listes à puces. - Pour
lessoncontent
, utiliser un mélange de listes numérotées et de contenu narratif, le cas échéant. - Pour
cleanup
, utiliser des listes numérotées pour décrire les étapes de nettoyage de l'état du cluster une fois la tâche terminée. - Pour
whatsnext
, Donnez une liste de 5 sujets au maximum qu'il serait intéressant à lire ensuite.
- Utilisez un minimum d'en-têtes H2 (avec deux caractères
Voici un exemple de sujet publié qui utilise le modèle de tutoriel Running a Stateless Application Using a Deployment.
A suivre
- En savoir plus sur le style guide
- En savoir plus sur l'organisation des contenus
8.3.4 - Organisation du contenu
Ce site utilise Hugo. Dans Hugo, l'organisation du contenu est un concept de base.
hugo server --navigateToChanged
pour les sessions d'édition de contenu.
Listes de pages
Ordre des pages
Le menu latéral de la documentation, le navigateur de la page de documentation, etc. sont listés selon l'ordre de tri par défaut de Hugo, qui trie par poids (à partir de 1), par date (la plus récente en premier), et enfin par titre du lien.
Si vous voulez déplacer une page ou une section vers le haut, placez un poids dans l'entête de la page :
title: My Page
weight: 10
Menu principal de la documentation
Le menu principal Documentation
est construit à partir des sections ci-dessous docs/
avec le drapeau main_menu
placé dans l'entête du fichier de contenu de la section `_index.md' :
main_menu: true
Notez que le titre du lien est récupéré à partir du linkTitle
de la page, donc si vous voulez qu'il soit différent du titre, changez-le dans le fichier du contenu cible :
main_menu: true
title: Page Title
linkTitle: Title used in links
_index.md
dans le dossier de la section.
Menu latéral de documentation
Le menu latéral de la barre de documentation est construit à partir de l'arborescence de la section courante commençant sous docs/
.
Il affichera toutes les sections et leurs pages.
Si vous ne voulez pas lister une section ou une page, mettez l'option toc_hide
à true
dans l'entête :
toc_hide: true
Lorsque vous naviguez vers une section contenant du contenu, la section ou la page spécifique (par exemple _index.md
) est affichée.
Sinon, la première page à l'intérieur de cette section est affichée.
Navigateur de documentation
Le navigateur de page sur la page d'accueil de la documentation est construit en utilisant toutes les sections et pages qui sont directement sous la section docs
.
Si vous ne voulez pas lister une section ou une page, mettez l'option toc_hide
à true
dans la partie avant :
toc_hide: true
Menu principal
Les liens du site dans le menu en haut à droite -- et aussi dans le pied de page -- sont construits par des recherches de pages.
C'est pour s'assurer que la page existe réellement.
Ainsi, si la section case-studies
n'existe pas dans un site (langue), le lien n'apparaitra pas.
Paquets de pages
In addition to standalone content pages (Markdown files), Hugo supports Page Bundles.
One example is Custom Hugo Shortcodes. On considère qu'il s'agit d'un "paquet de feuilles". Tout ce qui se trouve sous le répertoire, y compris le fichier `index.md', fera partie du paquet. Cela inclut également les liens relatifs aux pages, les images qui peuvent être traitées, etc :
en/docs/home/contribute/includes
├── example1.md
├── example2.md
├── index.md
└── podtemplate.json
Un autre exemple largement utilisé est celui du paquet includes
.
Il définit headless : true
dans l'entête, ce qui signifie qu'il n'obtient pas son propre URL.
Il n'est utilisé que dans d'autres pages.
en/includes
├── default-storage-class-prereqs.md
├── federated-task-tutorial-prereqs.md
├── index.md
├── partner-script.js
├── partner-style.css
├── task-tutorial-prereqs.md
├── user-guide-content-moved.md
└── user-guide-migration-notice.md
Quelques notes importantes sur les fichiers dans les paquets :
- Pour les paquets traduits, tous les fichiers non contenus manquants seront hérités des fichiers de langue anglaise. Cela permet d'éviter les doublons.
- Tous les fichiers d'un bundle sont ce que Hugo appelle
Resources
et vous pouvez fournir des métadonnées par langue, comme les paramètres et le titre, même s'il ne prend pas en charge les entêtes (fichiers YAML etc.). Voir Page Resources Metadata. - La valeur que vous obtenez de
.RelPermalink
d'unResource
est relative à la page. Voir Permalinks.
Styles
La source SASS
des feuilles de style pour ce site est stockée sous src/sass
et peut être construite avec make sass
(notez que Hugo aura bientôt le support SASS
, voir https://github.com/gohugoio/hugo/issues/4243.
A suivre
8.3.5 - Hugo Shortcodes personnalisés
Cette page explique les shortcodes Hugo personnalisés pouvant être utilisés dans la documentation de Kubernetes Markdown.
En savoir plus sur shortcodes dans la documentation Hugo.
Etat de la fonctionnalité
Dans une page de Markdown (fichier .md
) de ce site, vous pouvez ajouter un code court pour afficher la version et l'état de la fonction documentée.
Feature state demo
Ci-dessous se trouve une démo de l'extrait d'état de la fonctionnalité, qui affiche la fonctionnalité comme stable dans Kubernetes version 1.10.
{{< feature-state for_k8s_version="v1.10" state="stable" >}}
Rend à :
Kubernetes v1.10 [stable]
Les valeurs valides pour state
sont :
- alpha
- beta
- deprecated
- stable
Feature state code
La version de Kubernetes affichée par défaut est celle de la page ou du site.
Ceci peut être modifié en passant le paramètre for_k8s_version
shortcode.
{{< feature-state for_k8s_version="v1.10" state="stable" >}}
Rend à :
Kubernetes v1.10 [stable]
Alpha feature
{{< feature-state feature-state state="alpha" >}}
Rend à :
Kubernetes v1.23 [alpha]
Beta feature
{{< feature-state feature-state state="beta" >}}
Rend à :
Kubernetes v1.23 [beta]
Stable feature
{{< feature-state feature-state state="stable" >}}
Rend à :
Kubernetes v1.23 [stable]
Deprecated feature
{{< feature-state feature-state state="deprecated" >}}
Rend à :
Kubernetes v1.23 [deprecated]
Glossaire
Vous pouvez faire référence à des termes du glossaire avec une inclusion qui met à jour et remplace automatiquement le contenu avec les liens pertinents de notre glossaire. When the term is moused-over by someone using the online documentation, the glossary entry displays a tooltip.
The raw data for glossary terms is stored at https://github.com/kubernetes/website/tree/master/content/en/docs/reference/glossary, with a content file for each glossary term.
Démonstration du glossaire
Par exemple, le snippet suivant est rendu à cluster avec une infobulle :
{{< glossary_tooltip text="cluster" term_id="cluster" >}}
Tabs
Dans une page de démarque (fichier .md
) de ce site, vous pouvez ajouter un jeu d'onglets pour afficher plusieurs saveurs d'une solution donnée.
The tabs
shortcode takes these parameters:
name
: Le nom tel qu'il apparaît sur l'onglet.codelang
: Si vous fournissez un contenu interne au shortcodetab
, vous pouvez indiquer à Hugo quel langage de code utiliser pour activer la coloration syntaxique.include
: Le fichier à inclure dans l'onglet. Si l'onglet vit dans un Hugo leaf bundle, le fichier -- qui peut être n'importe quel type MIME supporté par Hugo -- est recherché dans le bundle lui-même. Si ce n'est pas le cas, la page de contenu qui doit être incluse est recherchée par rapport à la page en cours. Notez qu'avec leinclude
, vous n'avez pas de contenu interne de shortcode et devez utiliser la syntaxe de fermeture automatique. Par exemple,{{< tab name="Content File #1" include="example1" />}}
. La langue doit être spécifiée souscodelang
ou la langue est prise en compte en fonction du nom du fichier. Les fichiers non contenus sont mis en surbrillance par défaut.- Si votre contenu interne est Markdown, vous devez utiliser le délimiteur
%
pour entourer l'onglet. Par exemple,{{% tab name="Tab 1" %}}This is **markdown**{{% /tab %}}
- Vous pouvez combiner les variations mentionnées ci-dessus dans un ensemble d'onglets.
Ci-dessous se trouve une démo du raccourci des onglets.
tabs
doit être unique dans une page de contenu.
Tabs demo: Code highlighting
{{< tabs name="tab_with_code" >}}
{{{< tab name="Tab 1" codelang="bash" >}}
echo "This is tab 1."
{{< /tab >}}
{{< tab name="Tab 2" codelang="go" >}}
println "This is tab 2."
{{< /tab >}}}
{{< /tabs >}}
Rend à:
echo "This is tab 1."
println "This is tab 2."
Tabs demo: Inline Markdown and HTML
{{< tabs name="tab_with_md" >}}
{{% tab name="Markdown" %}}
This is **some markdown.**
{{< note >}}
It can even contain shortcodes.
{{< /note >}}
{{% /tab %}}
{{< tab name="HTML" >}}
<div>
<h3>Plain HTML</h3>
<p>This is some <i>plain</i> HTML.</p>
</div>
{{< /tab >}}
{{< /tabs >}}
Rend à:
This is some markdown.
Plain HTML
This is some plain HTML.
Tabs demo: File include
{{< tabs name="tab_with_file_include" >}}
{{< tab name="Content File #1" include="example1" />}}
{{< tab name="Content File #2" include="example2" />}}
{{< tab name="JSON File" include="podtemplate" />}}
{{< /tabs >}}
Rend à:
Ceci est un fichier de contenu exemple à l'intérieur du paquet de feuilles includes.
Ceci est un autre exemple fichier de contenu à l'intérieur du paquet de feuilles includes.
{
"apiVersion": "v1",
"kind": "PodTemplate",
"metadata": {
"name": "nginx"
},
"template": {
"metadata": {
"labels": {
"name": "nginx"
},
"generateName": "nginx-"
},
"spec": {
"containers": [{
"name": "nginx",
"image": "dockerfile/nginx",
"ports": [{"containerPort": 80}]
}]
}
}
}
A suivre
- En savoir plus sur Hugo.
- En savoir plus sur écrire un nouveau sujet.
- En savoir plus sur l'utilisation des page templates.
- En savoir plus sur staging your changes
- En savoir plus sur créer une pull request.
8.4 - Vue d'ensemble des documents de référence
Une grande partie de la documentation de référence de Kubernetes est générée à partir du code source de Kubernetes, à l'aide de scripts. Les rubriques de cette section expliquent comment générer ce type de contenu.
8.4.1 - Génération de documentation de référence pour l'API Kubernetes
Cette page montre comment mettre à jour les documents de référence générés automatiquement pour l'API Kubernetes.
Pré-requis
Vous devez avoir ces outils installés:
Votre variable d'environnement $GOPATH doit être définie et l'emplacement de etcd
doit être dans votre variable d'environnement $PATH.
Vous devez savoir comment créer une pull request dans un dépôt GitHub. Généralement, cela implique la création d'un fork du dépôt. Pour plus d'informations, voir Créer une Pull Request de documentation et GitHub Standard Fork & Pull Request Workflow.
Généralités
La mise à jour de la documentation de référence de l'API Kubernetes est un processus en deux étapes:
-
Générez une spécification OpenAPI à partir du code source de Kubernetes. Les outils pour cette étape sont kubernetes/kubernetes/hack.
-
Générez un fichier HTML à partir de la spécification OpenAPI. Les outils pour cette étape sont à kubernetes-incubator/reference-docs.
Obtenir trois dépôts
Si vous ne possédez pas déjà le dépôt kubernetes/kubernetes
, téléchargez-le maintenant:
mkdir $GOPATH/src
cd $GOPATH/src
go get github.com/kubernetes/kubernetes
Déterminez le dépôt de base de votre clone de kubernetes/kubernetes.
Par exemple, si vous avez suivi l’étape précédente pour obtenir le dépôt, votre dépôt de base est $GOPATH/src/github.com/kubernetes/kubernetes
.
Les étapes restantes se réfèrent à votre répertoire de base en tant que <k8s-base>
.
Si vous ne possédez pas déjà le dépôt kubernetes/website
, obtenez-le maintenant:
mkdir $GOPATH/src
cd $GOPATH/src
go get github.com/kubernetes/website
Déterminez le répertoire de base de votre dépôt kubernetes/website.
Par exemple, si vous avez suivi l’étape précédente pour obtenir le dépôt, votre répertoire de base est $GOPATH/src/github.com/kubernetes/website
.
Les étapes restantes se réfèrent à votre répertoire de base en tant que <web-base>
.
Si vous n'avez pas déjà le dépôt kubernetes-incubator/reference-docs
, obtenez-le maintenant:
mkdir $GOPATH/src
cd $GOPATH/src
go get github.com/kubernetes-incubator/reference-docs
Déterminez le répertoire de base de votre dépôt kubernetes-incubator/reference-docs.
Par exemple, si vous avez suivi l’étape précédente pour obtenir le dépôt, votre répertoire de base est $GOPATH/src/github.com/kubernetes-incubator/reference-docs
.
Les étapes restantes se réfèrent à votre répertoire de base en tant que <rdocs-base>
.
Modification du code source de Kubernetes
La documentation de référence de l'API Kubernetes est générée automatiquement à partir d'une spécification OpenAPI, générée à partir du code source de Kubernetes. Si vous souhaitez modifier la documentation de référence, la première étape consiste à modifier un ou plusieurs commentaires dans le code source de Kubernetes.
Modification des commentaires dans le code source
Voici un exemple d'édition d'un commentaire dans le code source de Kubernetes.
Dans votre dépôt local kubernetes/kubernetes
, vérifiez la branche master et assurez-vous qu'elle est à jour:
cd <k8s-base>
git checkout master
git pull https://github.com/kubernetes/kubernetes master
Supposons que ce fichier source dans la branche principale ait la typo "atmost":
kubernetes/kubernetes/staging/src/k8s.io/api/apps/v1/types.go
Dans votre environnement local, ouvrez types.go
et remplacez "atmost" par "at most".
Vérifiez que vous avez modifié le fichier:
git status
La sortie montre que vous êtes sur la branche master et que le fichier source types.go
a été modifié:
On branch master
...
modified: staging/src/k8s.io/api/apps/v1/types.go
Valider votre fichier édité
Exécutez git add
et git commit
pour valider les modifications que vous avez apportées jusqu'à présent.
Dans l'étape suivante, vous ferez un deuxième commit.
Il est important de séparer vos modifications en deux commits.
Génération de la spécification OpenAPI et des fichiers associés
Allez sur <k8s-base>
et exécutez ces scripts:
hack/update-generated-swagger-docs.sh
hack/update-swagger-spec.sh
hack/update-openapi-spec.sh
hack/update-generated-protobuf.sh
Exécutez git status
pour voir ce qui a été généré.
On branch master
...
modified: api/openapi-spec/swagger.json
modified: staging/src/k8s.io/api/apps/v1/generated.proto
modified: staging/src/k8s.io/api/apps/v1/types.go
modified: staging/src/k8s.io/api/apps/v1/types_swagger_doc_generated.go
Voir le contenu de api/openapi-spec/swagger.json
pour vous assurer que la faute de frappe est corrigée.
Par exemple, vous pouvez exécuter git diff -a api/openapi-spec/swagger.json
.
Ceci est important, car swagger.json
sera l’entrée de la seconde étape du processus de génération de doc.
Exécutez git add
et git commit
pour valider vos modifications.
Vous avez maintenant deux validations: une avec le fichier types.go
édité et une avec les spécifications OpenAPI générées et les fichiers associés.
Gardez ces deux commits séparés.
C'est-à-dire, ne faites pas un squash de vos commits.
Soumettez vos modifications en tant que pull request à la branche principale du dépôt kubernetes/kubernetes. Surveillez votre pull request, et répondre aux commentaires des relecteurs au besoin. Continuez à surveiller votre pull request jusqu'à ce qu'il ait été mergé.
PR 57758 est un exemple de demande d'extraction qui corrige une faute de frappe dans le code source de Kubernetes.
staging
du dépôt kubernetes/kubernetes
.
Mais dans votre cas, le répertoire staging
pourrait ne pas être l’endroit où trouver la source faisant autorité.
Pour vous guider, consultez les fichiers README
dans le dépôt kubernetes/kubernetes et dans le dépôt kubernetes/apiserver.
Cherry picking votre commit dans une branche release
Dans la section précédente, vous avez modifié un fichier dans la branche principale, puis exécuté des scripts pour générer une spécification OpenAPI et les fichiers associés.
Vous avez ensuite soumis vos modifications dans une demande d'extraction à la branche maître du dépôt kubernetes/kubernetes
.
Supposons maintenant que vous souhaitiez faire un backport de votre modification dans une branche de publication.
Par exemple, supposons que la branche principale soit utilisée pour développer Kubernetes version 1.10 et que vous souhaitiez faire un backport de votre modification dans la branche de la version 1.9.
Rappelez-vous que votre pull request a deux commits: un pour l'édition types.go
et un pour les fichiers générés par des scripts.
La prochaine étape consiste à proposer un cherry pick de votre premier commit dans la branche release-1.9.
L'idée est de cherry pick le commit qui a édité types.go
, mais pas le commit qui a pour résultat l'exécution des scripts.
Pour les instructions, voir Proposer un Cherry Pick.
Quand vous avez une pull request en place pour cherry picking votre seul commit dans la branche release-1.9, l’étape suivante consiste à exécuter ces scripts dans la branche release-1.9 de votre environnement local.
hack/update-generated-swagger-docs.sh
hack/update-swagger-spec.sh
hack/update-openapi-spec.sh
hack/update-generated-protobuf.sh
hack/update-api-reference-docs.sh
Maintenant, ajoutez un commit à votre cherry-pick pull request qui contient la spécification OpenAPI récemment générée et les fichiers associés. Surveillez votre pull request jusqu'à ce qu'elle soit mergée dans la branche release-1.9.
À ce stade, la branche master et la branche release-1.9 ont votre fichier types.go
mis à jour et un ensemble de fichiers générés qui reflètent les modifications apportées à types.go
.
Notez que la spécification OpenAPI générée et les autres fichiers générés dans la branche release-1.9 ne sont pas nécessairement identiques aux fichiers générés dans la branche master.
Les fichiers générés dans la branche release-1.9 contiennent des éléments API uniquement à partir de Kubernetes 1.9.
Les fichiers générés dans la branche maître peuvent contenir des éléments de l'API qui ne sont pas dans la version 1.9, mais sont en cours de développement pour la version 1.10.
Génération des documents de référence publiés
La section précédente a montré comment modifier un fichier source, puis générer plusieurs fichiers, y compris api/openapi-spec/swagger.json
dans le dépôt kubernetes/kubernetes
.
Cette section montre comment générer la documentation de référence de l'API Kubernetes publiée, qui est générée par les outils de kubernetes-incubator/reference-docs.
Ces outils prennent le fichier api/openapi-spec/swagger.json
comme entrée.
Modification du Makefile dans kubernetes-incubator/reference-docs
Aller à <rdocs-base>
, et ouvrez Makefile
pour l'édition:
Définissez K8SROOT
dans le répertoire de base de votre dépôt local kubernetes/kubernetes
.
Définissez WEBROOT
sur le répertoire de base de votre référentiel kubernetes/website
.
Définissez MINOR_VERSION
sur la version mineure de la documentation que vous souhaitez créer.
Par exemple, si vous souhaitez créer des documents pour Kubernetes 1.9, définissez MINOR_VERSION
sur 9.
Enregistrez et fermez Makefile
.
Copier la spécification OpenAPI
Le code de génération de document nécessite une copie locale de la spécification OpenAPI pour l'API Kubernetes.
Allez sur <k8s-base>
et vérifiez la branche qui a la spécification OpenAPI que vous voulez utiliser.
Par exemple, si vous souhaitez générer des documents pour Kubernetes 1.9, consultez la branche release-1.9.
Retournez à <rdocs-base>
.
Entrez la commande suivante pour copier la spécification OpenAPI à partir du dépôt kubernetes/kubernetes
vers un répertoire local:
make updateapispec
La sortie montre que le fichier a été copié:
cp ~/src/github.com/kubernetes/kubernetes/api/openapi-spec/swagger.json gen-apidocs/generators/openapi-spec/swagger.json
Construire l'image brodocs
Le code de génération de doc nécessite l'image Docker pwittrock/brodocs.
Cette commande crée l’image Docker pwittrock/brodocs
.
Il essaie également de transmettre l’image à DockerHub, mais c’est acceptable si cette étape échoue.
Tant que vous avez l'image localement, la génération de code peut réussir.
make brodocs
Vérifiez que vous avez l'image brodocs:
docker images
La sortie affiche pwittrock / brodocs
comme l'une des images disponibles:
REPOSITORY TAG IMAGE ID CREATED SIZE
pwittrock/brodocs latest 999d34a50d56 5 weeks ago 714MB
Exécuter le code de génération de doc
Générez et exécutez le code de génération de doc. Vous devrez peut-être exécuter la commande en tant que root:
cd <rdocs-base>
make api
Localiser les fichiers générés
Ces deux fichiers sont le résultat d’une construction réussie. Vérifiez qu'ils existent:
<rdocs-base>/gen-apidocs/generators/build/index.html
<rdocs-base>/gen-apidocs/generators/build/navData.js
Copier les documents générés dans le dépôt kubernetes/website
Les sections précédentes ont montré comment modifier un fichier source Kubernetes, générer une spécification OpenAPI, puis générer une documentation de référence pour la publication.
Cette section explique comment copier les documents générés sur le dépôt kubernetes/website.
Les fichiers dans le dépôt kubernetes/website
sont publiés sur le site web kubernetes.io.
En particulier, le fichier généré index.html
est publié ici.
Entrez la commande suivante pour copier les fichiers générés dans votre dépôt local kubernetes/website
:
make copyapi
Allez à la base de votre dépôt local kubernetes/kubernetes
, et regardez quels fichiers ont été modifiés:
cd <web-base>
git status
La sortie montre les fichiers modifiés:
On branch master
...
modified: docs/reference/generated/kubernetes-api/v1.9/index.html
Dans cet exemple, un seul fichier a été modifié.
Rappelez-vous que vous avez généré les deux index.html
et navData.js
.
Mais apparemment le généré navata.js
n'est pas différent du navData.js
c'était déjà dans le dépôt kubernetes/website
.
Dans <web-base>
executez git add
et git commit
pour enregistrer le commit du changement.
Soumettez vos modifications en tant que pull request au dépôt kubernetes/website. Surveillez votre pull request, et répondez aux commentaires des relecteurs au besoin. Continuez à surveiller votre pull request jusqu'à ce qu'elle ait été mergée.
Quelques minutes après que votre pull request soit fusionnée, vos modifications seront visibles dans la documentation de référence publiée.
A suivre
8.4.2 - Génération de la documentation de référence pour l'API de fédération Kubernetes
Cette page montre comment générer automatiquement des pages de référence pour l'API de fédération Kubernetes.
Pré-requis
-
Vous devez avoir Git installé.
-
Vous devez avoir Golang version 1.9.1 ou ultérieur installé, et votre variable d'environnement
$GOPATH
doit être définie. -
Vous devez avoir Docker installé.
-
Vous devez savoir comment créer une pull request sur un dépôt GitHub. Généralement, cela implique la création d'un fork du dépôt. Pour plus d'informations, voir Création d'une pull request de documentation.
Exécution du script update-federation-api-docs.sh
Si vous ne possédez pas déjà le code source de la fédération Kubernetes, procurez-vous-le maintenant:
mkdir $GOPATH/src
cd $GOPATH/src
go get github.com/kubernetes/federation
Déterminez le répertoire de base de votre dépôt local kubernetes/federation.
Par exemple, si vous avez suivi l'étape précédente pour obtenir le code source de la fédération, votre répertoire de base est $GOPATH/src/github.com/kubernetes/federation
.
Les étapes restantes se réfèrent à votre répertoire de base en tant que <fed-base>
.
Exécutez le script de génération de documentation:
cd <fed-base>
hack/update-federation-api-reference-docs.sh
Le script exécute le k8s.gcr.io/gen-swagger-docs image pour générer cet ensemble de documents de référence:
- /docs/api-reference/extensions/v1beta1/operations.html
- /docs/api-reference/extensions/v1beta1/definitions.html
- /docs/api-reference/v1/operations.html
- /docs/api-reference/v1/definitions.html
Les fichiers générés ne sont pas publiés automatiquement. Ils doivent être copiés manuellement sur dépôt kubernetes/website.
Ces fichiers sont publiés à kubernetes.io/docs/reference:
- Federation API v1 Operations
- Federation API v1 Definitions
- Federation API extensions/v1beta1 Operations
- Federation API extensions/v1beta1 Definitions
A suivre
8.4.3 - Génération de pages de référence pour les composants et les outils Kubernetes
Cette page montre comment utiliser l'outil update-importer-docs
pour générer une documentation de référence pour les outils et les composants des dépôts Kubernetes et Federation.
Pré-requis
-
Vous avez besoin d'une machine qui exécute Linux ou macOS.
-
Ces logiciels doivent être installés:
-
Golang version 1.13 ou ultérieure
-
Votre variable d'environnement
$GOPATH
doit être définie. -
Vous devez savoir comment créer une pull request sur un dépôt GitHub. Cela implique généralement la création d’un fork d'un dépôt. Pour plus d'informations, consultez Créer une Pull Request de documentation.
Obtenir deux dépôts
Si vous n'avez pas déjà le dépôt kubernetes/website
, obtenez le maintenant:
mkdir $GOPATH/src
cd $GOPATH/src
go get github.com/kubernetes/website
Déterminez le répertoire de base de votre clone du dépôt kubernetes/website.
Par exemple, si vous avez suivi l’étape précédente pour obtenir le dépôt, votre répertoire de base est $GOPATH/src/github.com/kubernetes/website
.
Les étapes restantes se réfèrent à votre répertoire de base en tant que <web-base>
.
Si vous envisagez d’apporter des modifications aux documents de référence et si vous ne disposez pas déjà du dépôt kubernetes/kubernetes
, obtenez-le maintenant:
mkdir $GOPATH/src
cd $GOPATH/src
go get github.com/kubernetes/kubernetes
Déterminez le répertoire de base de votre clone du dépôt kubernetes/kubernetes.
Par exemple, si vous avez suivi l’étape précédente pour obtenir le dépôt, votre répertoire de base est $GOPATH/src/github.com/kubernetes/kubernetes
.
Les étapes restantes se réfèrent à votre répertoire de base en tant que <k8s-base>
.
kubernetes/kubernetes
.
Lorsque vous exécutez la commande update-imported-docs
, il clone automatiquement le dépôt kubernetes/kubernetes
.
Modification du code source de Kubernetes
La documentation de référence pour les composants et les outils Kubernetes est générée automatiquement à partir du code source de Kubernetes.
Si vous souhaitez modifier la documentation de référence, commencez par modifier un ou plusieurs commentaires dans le code source de Kubernetes.
Faites le changement dans votre dépôt local kubernetes/kubernetes
, puis soumettez une pull request sur la branche master github.com/kubernetes/kubernetes.
PR 56942 est un exemple de pull request qui modifie les commentaires dans le code source de Kubernetes.
Surveillez votre pull request, et répondez aux commentaires des relecteurs.
Continuez à surveiller votre pull request jusqu'à ce qu'elle soit mergée dans la branche master du dépot kubernetes/kubernetes
.
Selectionnez vos commits dans une branche release
Vos commits sont sur la branche master, qui est utilisée pour le développement sur la prochaine sortie de Kubernetes. Si vous souhaitez que vos commits apparaissent dans la documentation d'une version Kubernetes déjà publiée, vous devez proposer que vos commits soit sélectionnée dans la branche de publication.
Par exemple, supposons que la branche master est utilisée pour développer Kubernetes 1.10, et vous voulez transférer vos commits sur la branche release-1.9. Pour savoir comment faire cela, consultez Propose a Cherry Pick.
Surveillez votre pull request cherry-pick jusqu'à ce qu'elle soit mergée dans la branche release.
Vue générale de update-imported-docs
L'outil update-importer-docs
se trouve dans le répertoire kubernetes/website/update-importer-docs/
.
L'outil effectue les étapes suivantes:
- Effectuez un clone des différents dépots spéciés dans le fichier de configuration.
Afin de générer des documents de référence, les dépôts clonés par défaut sont:
kubernetes-incubator/reference-docs
etkubernetes/federation
. - Effectuez les commandes dans les dépôts clonés pour préparer le générateur de documentation et génerer les fichiers Markdown.
- Copiez les fichiers markdown générés dans un copie locale du dépôt
kubernetes/website
. Les fichiers doivent être mis dans les dossiers spécifiés dans le fichier de configuration.
Quand les fichiers Markdown sont dans votre clone local du dépot kubernetes/website
, vous pouvez les soumettre dans une pull request vers kubernetes/website
.
Personnaliser le fichier de configuration
Ouvrez <web-base>/update-importer-docs/reference.yml
pour le modifier.
Ne modifiez pas le contenu de l'entrée generate-command
sauf si vous comprenez ce qu'elle fait et devez modifier la branche de release spécifiée.
repos:
- name: reference-docs
remote: https://github.com/kubernetes-incubator/reference-docs.git
# Ceci et la commande generate ci-dessous nécessitent une modification lorsque les branches de référence-docs sont correctement définies
branch: master
generate-command: |
cd $GOPATH
git clone https://github.com/kubernetes/kubernetes.git src/k8s.io/kubernetes
cd src/k8s.io/kubernetes
git checkout release-1.11
make generated_files
cp -L -R vendor $GOPATH/src
rm -r vendor
cd $GOPATH
go get -v github.com/kubernetes-incubator/reference-docs/gen-compdocs
cd src/github.com/kubernetes-incubator/reference-docs/
make comp
Dans reference.yml, les attributs files
est une liste d'objets ayant des attributs src
et dst
.
L'attribut src
spécifie l'emplacement d'un fichier Markdown généré, et l'attribut dst
spécifie où copier ce fichier dans le dépôt local kubernetes/website
.
Par exemple:
repos:
- name: reference-docs
remote: https://github.com/kubernetes-incubator/reference-docs.git
files:
- src: gen-compdocs/build/kube-apiserver.md
dst: content/en/docs/reference/command-line-tools-reference/kube-apiserver.md
...
Notez que lorsqu'il y a beaucoup de fichiers à copier du même répertoire source dans le même répertoire de destination, vous pouvez utiliser des caractères génériques dans la valeur donnée à src
et vous pouvez simplement fournir le nom du répertoire comme valeur pour dst
.
Par exemple:
files:
- src: gen-compdocs/build/kubeadm*.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/
Exécution de l'outil update-importer-docs
Après avoir revu et/ou personnalisé le fichier reference.yaml
, vous pouvez exécuter l'outil update-imports-docs
:
cd <web-base>/update-imported-docs
./update-imported-docs reference.yml
Ajouter et valider des modifications dans kubernetes/website
Répertoriez les fichiers générés et copiés dans le dépôt kubernetes/website
:
cd <web-base>
git status
La sortie affiche les fichiers nouveaux et modifiés. Par exemple, la sortie pourrait ressembler à ceci:
...
modified: content/en/docs/reference/command-line-tools-reference/cloud-controller-manager.md
modified: content/en/docs/reference/command-line-tools-reference/federation-apiserver.md
modified: content/en/docs/reference/command-line-tools-reference/federation-controller-manager.md
modified: content/en/docs/reference/command-line-tools-reference/kube-apiserver.md
modified: content/en/docs/reference/command-line-tools-reference/kube-controller-manager.md
modified: content/en/docs/reference/command-line-tools-reference/kube-proxy.md
modified: content/en/docs/reference/command-line-tools-reference/kube-scheduler.md
...
Exécutez git add
et git commit
pour faire un commit de ces fichiers.
Créer une pull request
Créez une pull request vers le dépôt kubernetes/website
.
Consultez votre pull request et répondez aux corrections suggérées par les rélecteurs jusqu'à ce que la pull request soit acceptée et mergée.
Quelques minutes après le merge votre pull request, vos références mises à jour seront visibles dans la documentation publiée.
A suivre
8.5 - Participez au SIG Docs
SIG Docs est l'un des groupes d'intérêts spéciaux au sein du projet Kubernetes, axé sur la rédaction, la mise à jour et la maintenance de la documentation de Kubernetes dans son ensemble. Pour plus d'informations sur le SIG consultez le dépôt GitHub de la communauté.
SIG Docs accueille le contenu et les critiques de tous les contributeurs. Tout le monde peut ouvrir une pull request (PR), et tout le monde est invité à déposer des questions sur le contenu ou à commenter les pull requests ouvertes.
Dans SIG Docs, vous pouvez aussi devenir un membre, relecteur, ou approbateur. Ces rôles nécessitent un plus grand accès et impliquent certaines responsabilités pour approuver et valider les changements. Voir appartenance à la communauté pour plus d'informations sur le fonctionnement de l'adhésion au sein de la communauté Kubernetes. Le reste de ce document décrit certaines fonctions uniques de ces rôles au sein du SIG Docs, responsable de la gestion de l’un des aspects les plus accessibles du public de Kubernetes: le site Web et la documentation de Kubernetes.
Rôles et responsabilités
Lorsqu'une pull request est mergée à la branche utilisée pour publier le contenu (actuellement master
), ce contenu est publié et disponible dans le monde entier.
Pour nous assurer que la qualité de notre contenu publié est élevée, nous limitons aux approbateurs SIG Docs le droit de merger des pull requests.
Voici comment ce processus fonctionne.
- Lorsqu'une pull request a les deux labels
lgtm
etapprove
et n'a pas de labelhold
, la pull request est mergée automatiquement. - Les membres de l'organisation Kubernetes et les approbateurs SIG Docs peuvent ajouter des commentaires à une pull request ou empêcher le merge automatique d'une pull request donnée (en ajoutant un commentaire
/hold
ou en retirant un commentaire/lgtm
). - Tout membre de Kubernetes peut ajouter le label
lgtm
, en ajoutant un commentaire/lgtm
. - Seul un approbateur membre de SIG Docs peut causer le merge d'une pull request en ajoutant un commentaire
/approve
. Certains approbateurs remplissent également des rôles spécifiques supplémentaires, tels que PR Wrangler or président(e) du SIG Docs.
Pour plus d'informations sur les attentes et les différences entre les rôles de membre de l'organisation Kubernetes et d'approbateurs SIG Docs, voir Types de contributeur. Les sections suivantes couvrent plus de détails sur ces rôles et leur fonctionnement dans SIG-Docs.
N'importe qui
Tout le monde peut ouvrir un ticket sur n'importe quelle partie de Kubernetes, y compris la documentation.
Toute personne ayant signé le CLA peut ouvrir une Pull Request. Si vous ne pouvez pas signer le CLA, le projet Kubernetes ne peut pas accepter votre contribution.
Membres
Tout membre de l'organisation Kubernetes peut faire une revue d'une pull request, et les membres de l’équipe SIG Docs demandent fréquemment aux membres d’autres SIG d'effectuer des révisions de documents pour des raisons de précision technique.
SIG Docs accueille également des critiques et des commentaires indépendamment du statut de membre d'une personne dans l'organisation Kubernetes.
Vous pouvez indiquer votre approbation en ajoutant un commentaire de /lgtm
à une pull request.
Si vous n'êtes pas membre de l'organisation Kubernetes, votre /lgtm
n'a aucun effet sur les systèmes automatisés.
Tout membre de l’organisation Kubernetes peut ajouter un commentaire / hold
pour empêcher la pull request d'être mergée.
Tout membre peut également supprimer un commentaire /hold
pour merger une PR s'il a déjà les deux commentaires /lgtm
et /approve
appliqué par les personnes appropriées.
Devenir membre
Après avoir soumis avec succès au moins 5 pull requests significatives, vous pouvez demander l'adhésion dans l'organisation Kubernetes. Suivez ces étapes:
-
Trouvez deux relecteurs ou approbateurs pour parrainer votre adhésion.
Demander un parrainage dans le canal #sig-docs sur l'instance de Kubernetes Slack ou sur la mailing list SIG Docs.
Note: N'envoyez pas de courrier électronique direct ou de message direct Slack à un membre individuel de SIG Docs. -
Ouvrez un ticket Github dans le dépôt
kubernetes/org
pour adhérer à l'organisation. Remplissez le modèle en suivant les directives de l'Adhésion à la communauté. -
Informez vos sponsors du ticket Github, soit en les mentionnant dans le ticket Github (en ajoutant un commentaire avec
@<Github-username>
) ou en leur envoyant directement le lien, afin qu’ils puissent ajouter un vote+ 1
. -
Lorsque votre adhésion est approuvée, le membre de l'équipe d'administration github affecté à votre demande met à jour le ticket Github pour indiquer son approbation, puis ferme le ticket Github. Félicitations, vous êtes maintenant membre!
Si, pour une raison quelconque, votre demande d'adhésion n'est pas acceptée immédiatement, le comité des membres fournit des informations ou des mesures à prendre avant de présenter une nouvelle demande.
Relecteurs
Les relecteurs sont membres du groupe Github @kubernetes/sig-docs-pr-reviews. Voir Equipes et groupes au sein de SIG Docs.
Les relecteurs examinent les Pull Request de documentation et font des commentaires sur les changements proposés.
L'automatisation assigne des relecteurs aux pull requests, et les contributeurs peuvent demander une revue d'un relecteur spécifique en laissant un commentaire tel que: /assign [@_github_handle]
.
Pour indiquer qu'une pull request est techniquement exacte et ne nécessite aucune modification supplémentaire, un examinateur ajoute un commentaire /lgtm
à la Pull Request.
Si le relecteur affecté n'a pas encore revu le contenu, un autre relecteur peut intervenir.
En outre, vous pouvez affecter des relecteurs techniques et attendre qu'ils fournissent des /lgtm
.
Pour un changement trivial ou ne nécessitant aucun examen technique, l'approbateur SIG Docs peut fournir le /lgtm
aussi.
Un commentaire /approve
d'un relecteur est ignoré par l'automatisation.
Pour en savoir plus sur comment devenir un relecteur SIG Docs et sur les responsabilités et l’engagement de temps que cela implique, voir Devenir relecteur ou approbateur.
Devenir relecteur
Lorsque vous remplissez les conditions requises, vous pouvez devenir un relecteur SIG Docs. Les relecteurs d'autres SIG doivent demander séparément le statut de relecteur dans le SIG Docs.
Pour postuler, ouvrez une pull request et ajoutez vous à la section reviewers
du fichier top-level OWNERS dans le dépôt kubernetes/website
.
Affectez la PR à un ou plusieurs approbateurs SIG Docs.
Si votre pull request est approuvée, vous êtes maintenant un relecteur SIG Docs. K8s-ci-robot vous assignera et vous suggérera en tant que relecteur pour les nouvelles Pull Requests.
Si vous êtes approuvé, demandez qu’un approbateur SIG Docs en cours vous ajoute au groupe Github @kubernetes/sig-docs-pr-reviews.
Seuls les membres du groupe Github kubernetes-website-admins
peuvent ajouter de nouveaux membres à un groupe Github.
Approbateurs
Les approbateurs sont membres du groupe Github @kubernetes/sig-docs-maintainers. Voir Equipes et groupes au sein de SIG Docs.
Les approbateurs ont la capacité de merger une PR, et ainsi, publier du contenu sur le site Web de Kubernetes.
Pour approuver une PR, un approbateur laisse un commentaire /approve
sur la PR.
Si quelqu'un qui n'est pas un approbateur laisse le commentaire d'approbation, l'automatisation l'ignore.
Si la PR a déjà un /lgtm
, ou si l'approbateur fait également des commentaires avec /lgtm
, la PR est mergée automatiquement.
Un approbateur SIG Docs ne doit laisser qu'un /lgtm
sur un changement qui ne nécessite pas de relecture supplémentaire.
Pour en savoir plus sur comment devenir un approbateur SIG Docs et sur les responsabilités et l’engagement de temps que cela implique, voir Devenir relecteur ou approbateur.
Devenir approbateur
Lorsque vous remplissez les conditions requises, vous pouvez devenir un approbateur SIG Docs. Les approbateurs appartenant à d'autres SIG doivent demander séparément le statut d'approbateur dans SIG Docs.
Pour postuler, ouvrez une pull request pour vous ajouter à la section approvers
du fichier top-level OWNERS dans le dépot kubernetes/website
.
Affectez la PR à un ou plusieurs approbateurs SIG Docs.
Si votre Pull Request est approuvée, vous êtes à présent approbateur SIG Docs. Le K8s-ci-robot vous assignera et vous suggérera en tant que relecteur pour les nouvelles Pull Requests.
Si vous êtes approuvé, demandez qu’un approbateur SIG Docs en cours vous ajoute au groupe Github @kubernetes/sig-docs-maintainers.
Seuls les membres du groupe Github kubernetes-website-admins
peuvent ajouter de nouveaux membres à un groupe Github.
Devenir un administrateur de site Web
Les membres du groupe GitHub kubernetes-website-admins
peuvent gérer l’appartenance au groupe Github et disposer de tous les droits administratifs sur les paramètres du dépôt, y compris la possibilité d'ajouter, de supprimer et de debugger des Webhooks.
Tous les approbateurs SIG Docs n'ont pas besoin de ce niveau d'accès.
Si vous pensez avoir besoin de ce niveau d’accès, adressez-vous à un administrateur de site Web existant ou posez la question dans le canal Slack #sig-docs.
Auxiliaires de traitement des Pull Requests
Les approbateurs SIG Docs sont ajoutés au calendrier de rotations des auxiliaires de traitement des PullRequests pour les rotations hebdomadaires. Tous les approbateurs SIG Docs devraient participer à cette rotation. Voir Soyez l'auxiliaire des PR pendant une semaine pour plus de détails.
Présidence du SIG Docs
Chaque SIG, y compris SIG Docs, sélectionne un ou plusieurs membres du SIG qui assumeront les fonctions de président(e). Ce sont des points de contact entre SIG Docs et d’autres parties de l’organisation Kubernetes. Ils nécessitent une connaissance approfondie de la structure du projet Kubernetes dans son ensemble et du fonctionnement de SIG Docs au sein de celui-ci. Voir Direction pour la liste actuelle des président(e)s.
Equipes SIG Docs et automatisation
L'automatisation dans SIG Docs repose sur deux mécanismes différents: Groupes Github et fichiers OWNERS.
Groupes Github
Le groupe SIG Docs définit deux équipes sur Github:
Chacun peut être référencé avec son @name
dans Github, commentez pour communiquer avec tous les membres de ce groupe.
Ces équipes peuvent avoir des membres en commun. Pour l'affectation des tickets, des pull requests, et aider la validation des PR, l'automatisation utilise les informations des fichiers OWNERS.
OWNERS files et front-matter
Le projet Kubernetes utilise un outil d'automatisation appelé prow pour l'automatisation liée aux Github issues et aux pull requests. Le dépôt du site web Kubernetes utilise deux plugins prow:
- blunderbuss
- approve
Ces deux plugins utilisent les fichiers OWNERS et OWNERS_ALIASES à la racine du dépôt Github kubernetes/website
pour contrôler comment prow fonctionne.
Un fichier OWNERS contient une liste de personnes qui sont des relecteurs et des approbateurs SIG Docs. Les fichiers OWNERS existent aussi dans les sous-dossiers, et peuvent ignorer qui peut agir en tant que relecteur ou approbateur des fichiers de ce sous-répertoire et de ses descendants. Pour plus d'informations sur les fichiers OWNERS en général, voir OWNERS.
En outre, un fichier Markdown individuel peut répertorier les relecteurs et les approbateurs dans l'entête, soit en répertoriant les noms d’utilisateur ou les groupes de Github.
La combinaison des fichiers OWNERS
et des entêtes dans les fichiers Markdown déterminent les suggestions automatiques de relecteurs dans la PullRequest.
A suivre
Pour plus d'informations sur la contribution à la documentation Kubernetes, voir:
8.6 - Traduction de la documentation Kubernetes
La documentation de Kubernetes est disponible dans plusieurs langues. Nous vous encourageons à ajouter de nouvelles traductions!
Commencer
Les traductions doivent avoir certains pré-requis pour le workflow (comment traduire) et la sortie (quoi traduire) avant de publier.
Pour ajouter une nouvelle localisation de la documentation de Kubernetes, vous devrez mettre à jour le site web en modifiant le paramètre site configuration et directory structure. Alors vous pouvez commencer la traduction de documents!
Indiquez à Kubernetes SIG Docs que vous souhaitez créer une traduction! Rejoignez le canal Slack SIG Docs. Nous sommes heureux de vous aider à démarrer et à répondre à toutes vos questions.
Toutes les équipes de traduction doivent être autonomes avec leurs propres ressources. Nous sommes heureux d'accueillir votre travail, mais nous ne pouvons pas le traduire pour vous.
Fork et cloner le dépôt
D'abord, créez votre fork du dépôt kubernetes/website.
Ensuite, clonez ce dépôt et mettez vous dedans (avec une commande cd
):
git clone https://github.com/kubernetes/website
cd website
Les contributeurs de k/website
doivent créer un fork à partir duquel les pull requests seront ouvertes.
Pour les localisations, nous demandons en outre que :
- Les approbateurs d'équipe ouvrent des branches de développement directement à partir de https://github.com/kubernetes/website.
- Les contributeurs à la localisation travaillent à partir de forks, avec des branches basées sur la branche de développement actuelle.
Cela s'explique par le fait que les projets de localisation sont des efforts de collaboration sur des branches à long terme, similaires aux branches de développement pour le cycle de release de Kubernetes. Pour plus d'informations sur les pull request de localisation, voir "branching strategy".
Trouvez votre code de langue à deux lettres
Consultez la norme ISO 639-1 pour le code de pays en deux lettres de votre localisation.
Par exemple, le code à deux lettres pour l'allemand est de
.
de
) as an example.
Modifier la configuration du site
Le site web de Kubernetes utilise Hugo comme son web framework.
La configuration Hugo du site Web se trouve dans le fichier config.toml
.
Pour prendre en charge une nouvelle localisation, vous devrez modifier config.toml
.
Ajoutez un bloc de configuration pour la nouvelle langue dans config.toml
, sous le bloc [languages]
existant.
Le bloc allemand, par exemple, ressemble à :
[languages.de]
title = "Kubernetes"
description = "Produktionsreife Container-Verwaltung"
languageName = "Deutsch"
contentDir = "content/de"
weight = 3
Lors de l'attribution d'un paramètre de weight
à votre bloc, trouvez le bloc de langue ayant le weight
le plus élevé et ajoutez 1 à cette valeur.
Pour plus d'informations sur le support multilingue de Hugo, voir "Multilingual Mode".
Ajouter un nouveau répertoire de localisation
Ajoutez un sous-répertoire spécifique à la langue dans le répertoire content
du dépôt.
Par exemple, le code à deux lettres pour l'allemand est "de" :
mkdir content/de
Ajouter un README localisé
Pour guider les autres contributeurs à la localisation, ajoutez un nouveau README-**.md
au plus haut niveau de k/website, où **
est le code de langue à deux lettres.
Par exemple, un fichier README allemand serait README-de.md
.
Fournir des conseils aux contributeurs à la localisation dans le fichier localisé README-**.md
.
Incluez les mêmes informations que celles contenues dans README.md
ainsi que :
- Un point de contact pour le projet de localisation
- Toute information spécifique à la localisation
Après avoir créé le fichier README localisé, ajoutez un lien vers le fichier à partir du fichier anglais principal, [README.md
's Localizing Kubernetes Documentation] et incluez les coordonnées des personnes-ressources en anglais.
Vous pouvez fournir un identifiant GitHub, une adresse e-mail, Slack channel, ou toute autre méthode de contact.
Translating documents
Localiser toute la documentation de Kubernetes est une tâche énorme. Il n'y a pas de mal à commencer petit et progresser avec le temps.
Au minimum, toutes les localisations doivent inclure :
Description | URLs |
---|---|
Home | All heading and subheading URLs |
Setup | All heading and subheading URLs |
Tutorials | Kubernetes Basics, Hello Minikube |
Site strings | All site strings in a new localized TOML file |
Les documents traduits doivent résider dans leur propre sous-répertoire content/**/
, mais sinon suivre le même chemin URL que la source anglaise.
Par exemple, pour préparer le tutoriel Kubernetes Basics à traduire en allemand, créez un sous-dossier sous le dossier `content/de/' et copiez la source anglaise :
mkdir -p content/de/docs/tutorials
cp content/en/docs/tutorials/kubernetes-basics.md content/de/docs/tutorials/kubernetes-basics.md
Pour un exemple de demande liée à la localisation pull request, this pull request au Kubernetes website repo a ajouté la localisation coréenne aux documents Kubernetes.
Fichiers sources
Les localisations doivent utiliser les fichiers anglais de la version la plus récente comme source. La version la plus récente est v1.23.
Pour trouver les fichiers sources de la version la plus récente :
- Accédez au dépôt du site web de Kubernetes à l'adresse suivante https://github.com/kubernetes/website.
- Sélectionnez la branche `release-1.X' pour la version la plus récente.
La dernière version est v1.23, donc la branche de la release la plus récente est release-1.23
.
Chaînes de sites en i18n/
Les localisations doivent inclure le contenu des éléments suivants i18n/en.toml
dans un nouveau fichier spécifique à la langue.
Prenons l'allemand comme exemple : i18n/de.toml
.
Ajouter un nouveau fichier de localisation dans i18n/
. Par exemple, avec l'allemand (de) :
cp i18n/en.toml i18n/de.toml
Traduisez ensuite la valeur de chaque chaîne de caractères :
[docs_label_i_am]
other = "ICH BIN..."
La localisation des chaînes de caractères du site vous permet de personnaliser le texte et les fonctionnalités du site : par exemple, le texte du copyright légal dans le pied de page de chaque page.
Logistique de projet
Contactez les responsables du SIG Docs
Contactez l'un des présidents du Kubernetes SIG Docs lorsque vous démarrez une nouvelle localisation.
Mainteneurs
Chaque traduction doit fournir ses propres responsables. Les responsables peuvent appartenir à une ou plusieurs organisations. Dans la mesure du possible, les pull requests de traduction doivent être approuvées par un relecteur d'une organisation différente de celle du traducteur.
Une traduction doit avoir un minimum de deux mainteneurs. (Il n'est pas possible de relire et d'approuver son propre travail.)
Gestion des branches
Étant donné que les projets de traduction sont des efforts hautement collaboratifs, nous encourageons les équipes à travailler à partir d’une branche de développement partagée.
Pour collaborer sur une branche de développement:
-
A team member opens a development branch, usually by opening a new pull request against a source branch on https://github.com/kubernetes/website.
Nous recommandons le schéma de nommage de branche suivant :
dev-<source version>-<language code>.<team milestone>
Par exemple, un approbateur d'une équipe de localisation allemande ouvre la branche développement
dev-1.12-de.1
directement contre le dépôt k/website, basé sur la branche source pour Kubernetes v1.12. -
Les contributeurs individuels ouvrent des branches de fonctionnalités basées sur la branche de développement.
Par exemple, un contributeur allemand ouvre une pull request avec les modifications suivantes
kubernetes:dev-1.12-de.1
surusername:local-branch-name
. -
Les approbateurs examinent et mergent les branches de fonctionnalités dans la branche de développement.
-
Périodiquement, un approbateur fusionne la branche de développement à sa branche source.
Répétez les étapes 1 à 4 au besoin jusqu'à ce que la localisation soit terminée.
Par exemple, les branches de développement allemandes suivantes le seraient : dev-1.12-de.2
, dev-1.12-de.3
, etc.
Les équipes doivent fusionner le contenu localisé dans la même branche de publication d'où provient le contenu. Par exemple, une direction du développement provenant de release-1.23 doit se fonder sur release-1.23.
Un approbateur doit maintenir une branche de développement en la tenant à jour avec sa branche source et en résolvant les conflits entre les branches. Plus une branche de développement reste ouverte longtemps, plus elle nécessite généralement de maintenance. Envisagez de merger périodiquement les branches de développement et d’en ouvrir de nouvelles, plutôt que de conserver une branche de développement extrêmement ancienne.
Seuls les approbateurs peuvent accepter les pull requests, mais n'importe qui peut en ouvrir une avec une nouvelle branche de développement. Aucune autorisation spéciale n'est requise.
Pour plus d'informations sur le travail à partir de forks ou directement à partir du dépôt, voir "fork and clone the repo".
Upstream contributions
SIG Docs souhaite la bienvenue aux contributions et corrections upstream à la source anglaise.
A suivre
Une fois qu'une traduction répond aux exigences de logistique et à une couverture admissible, le SIG docs se chargera des taches suivantes:
- Activer la sélection de la langue sur le site Web
- Publier la disponibilité de la traduction via les canaux de la Cloud Native Computing Foundation, y compris sur le blog de Kubernetes.