Tâches
Cette section de la documentation de Kubernetes contient différentes pages montrant
comment effectuer des tâches individuelles. Une page montre comment effectuer qu'une
seule chose, généralement en donnant une courte séquence d'étapes.
Si vous souhaitez écrire une nouvelle page, consultez
Créer une Pull Request pour la documentation.
1 - Outils d'installation
1.1 - Installer et configurer kubectl
Installation et configuration de 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://dl.k8s.io/release/$(curl -Ls https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl
Pour télécharger une version spécifique, remplacez $(curl -s https://dl.k8s.io/release/stable.txt)
avec la version spécifique.
Par exemple, pour télécharger la version 1.29.2 sur Linux, tapez :
curl -LO https://dl.k8s.io/release/v1.29.2/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/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://dl.k8s.io/release/$(curl -Ls https://dl.k8s.io/release/stable.txt)/bin/darwin/amd64/kubectl
Pour télécharger une version spécifique, remplacez $(curl -Ls https://dl.k8s.io/release/stable.txt)
avec la version spécifique.
Par exemple, pour télécharger la version 1.29.2 sur macOS, tapez :
curl -LO https://dl.k8s.io/release/v1.29.2/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 1.29.2 depuis ce lien.
Ou si vous avez curl
installé, utilisez cette commande:
curl -LO https://dl.k8s.io/release/v1.29.2/bin/windows/amd64/kubectl.exe
Pour connaître la dernière version stable (par exemple, en scripting), jetez un coup d'oeil à https://dl.k8s.io/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
Note: Docker Desktop pour Windows ajoute sa propre version de
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 un DownloadLocation
, 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
2. Testez pour vous assurer que la version que vous avez installée est à jour:
```
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:
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 -o default -F __start_kubectl k' >>~/.bashrc
Note: bash-completion source tous les scripts de completion dans /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.
Attention: macOS inclut Bash 3.2 par défaut. Le script de complétion kubectl nécessite Bash 4.1+ et ne fonctionne pas avec Bash 3.2. Une des solutions possibles est d'installer une version plus récente de Bash sous macOS (voir instructions
ici). Les instructions ci-dessous ne fonctionnent que si vous utilisez Bash 4.1+.
Installer bash-completion
Note: Comme mentionné, ces instructions supposent que vous utilisez Bash 4.1+, ce qui signifie que vous installerez bash-completion v2 (contrairement à Bash 3.2 et bash-completion v1, auquel cas la complétion pour kubectl ne fonctionnera pas).
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 -o default -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.
Note: L'installation Homebrew de bash-complétion v2 source tous les fichiers du répertoire 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
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
• VirtualBox
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.
Avertissement: Le pilote VM
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.
Avertissement: Le pilote 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) :
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
• VirtualBox
• VMware Fusion
Installer Minikube
La façon la plus simple d'installer Minikube sur macOS est d'utiliser Homebrew:
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
• VirtualBox
Note: Hyper-V peut fonctionner sur trois versions de Windows 10: Windows 10 Entreprise, Windows 10 Professionnel et Windows 10 Éducation.
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) :
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 :
Note: Pour définir le
--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 :
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 :
Tout nettoyer pour recommencer à zéro
Si vous avez déjà installé minikube, exécutez :
Si cette commande renvoie une erreur :
Vous devez supprimer les fichiers de configuration :
A suivre
2 - Administration d'un cluster
2.1 - Administration avec kubeadm
2.2 - Gestion de la mémoire du CPU et des ressources d'API
2.3 - Installation d'un fournisseur de politiques de réseau
2.4 - Déclarer une politique réseau (NetworkPolicy)
Ce document vous aide à utiliser l'API NetworkPolicy de Kubernetes pour déclarer des politiques réseau qui gouvernent la communication entre les pods.
Note: Cette section renvoie à des projets tiers qui fournissent des fonctionnalités requises par Kubernetes. Les auteurs du projet Kubernetes ne sont pas responsables de ces projets, classés par ordre alphabétique. Pour ajouter un projet à cette liste, lisez le
guide avant de soumettre une modification.
Plus d'informations.
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.8.
Pour consulter la version, entrez
kubectl version
.
Assurez-vous d'avoir configuré un fournisseur de réseau qui supporte les politiques réseau. De nombreux fournisseurs de réseau prennent en charge les NetworkPolicy, notamment :
Créer un Deployment nginx
et l'exposer via un Service
Pour comprendre comment fonctionne les politiques réseau dans Kubernetes, commencez par créer un déploiement nginx
.
kubectl create deployment nginx --image=nginx
deployment.apps/nginx created
Exposez le déploiement via un service appelé nginx
.
kubectl expose deployment nginx --port=80
service/nginx exposed
Les commandes ci-dessus créent un déploiement avec un Pod nginx et exposent le déploiement via un service nommé nginx
. Le Pod et le Deployment nginx
se trouvent dans le namespace default
.
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes 10.100.0.1 <none> 443/TCP 46m
service/nginx 10.100.0.16 <none> 80/TCP 33s
NAME READY STATUS RESTARTS AGE
pod/nginx-701339712-e0qfq 1/1 Running 0 35s
Tester le Service en y accédant depuis un autre Pod
Vous devriez pouvoir accéder au nouveau service nginx
depuis d'autres pods. Pour accéder au service nginx
depuis un autre pod dans le namespace default
, démarrez un conteneur busybox :
kubectl run busybox --rm -ti --image=busybox:1.28 -- /bin/sh
Dans votre shell, exécutez la commande suivante :
wget --spider --timeout=1 nginx
Connecting to nginx (10.100.0.16:80)
remote file exists
Limiter l'accès au Service nginx
Pour limiter l'accès au service nginx
afin que seuls les pods avec le label access: true
puissent le consulter, créez un objet NetworkPolicy comme suit :
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: access-nginx
spec:
podSelector:
matchLabels:
app: nginx
ingress:
- from:
- podSelector:
matchLabels:
access: "true"
Le nom d'un objet NetworkPolicy doit être un nom de sous-domaine DNS valide.
Note: Les NetworkPolicy incluent un podSelector
qui sélectionne le regroupement de pods auxquels la politique s'applique. Vous pouvez voir que cette politique sélectionne les pods avec le label app=nginx
. Ce label a été ajouté automatiquement au pod dans le déploiement nginx
. Un podSelector
vide sélectionne tous les pods dans le namespace.
Affecter la politique au Service
Utilisez kubectl pour créer une NetworkPolicy à partir du fichier nginx-policy.yaml
ci-dessus :
kubectl apply -f https://k8s.io/examples/service/networking/nginx-policy.yaml
networkpolicy.networking.k8s.io/access-nginx created
Tester l'accès au Service lorsque le label d'accès n'est pas défini
Lorsque vous tentez d'accéder au service nginx
depuis un pod sans les bons labels, la requête échoue :
kubectl run busybox --rm -ti --image=busybox:1.28 -- /bin/sh
Dans votre shell, exécutez la commande :
wget --spider --timeout=1 nginx
Connecting to nginx (10.100.0.16:80)
wget: download timed out
Définir le label d'accès et tester à nouveau
Vous pouvez créer un pod avec le bon label pour voir que la requête est autorisée :
kubectl run busybox --rm -ti --labels="access=true" --image=busybox:1.28 -- /bin/sh
Dans votre shell, exécutez la commande :
wget --spider --timeout=1 nginx
Connecting to nginx (10.100.0.16:80)
remote file exists
2.5 - Développer un Cloud Controller Manager
FEATURE STATE: Kubernetes v1.11 [beta]
Dans les prochaines versions, Cloud Controller Manager sera le moyen privilégié d’intégrer Kubernetes à n’importe quel cloud.
Cela garantira que les fournisseurs de cloud peuvent développer leurs fonctionnalités indépendamment des cycles de publication de Kubernetes.
FEATURE STATE: 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 bloc init
à 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.
2.6 - Kubernetes cloud-controller-manager
FEATURE STATE: Kubernetes v1.29 [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
et kube-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 marquage node.cloudprovider.kubernetes.io/uninitialized
avec un effet NoSchedule
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 registry.k8s.io/cloud-controller-manager
# cela peut être remplacé par n'importe quelle autre image pour les fournisseurs out-of-tree
image: registry.k8s.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.
3 - Configuration des Pods et des conteneurs
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, entrez
kubectl 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 :
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
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, entrez
kubectl 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:
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.
Note: Une autre explication possible de la restriction du CPU est que le Nœud pourrait ne pas avoir
suffisamment de ressources CPU disponibles. Rappelons que les conditions préalables à cet exercice exigent que chacun de vos Nœuds doit avoir au moins 1 CPU.
Si votre conteneur fonctionne sur un nœud qui n'a qu'un seul CPU, le conteneur ne peut pas utiliser plus que 1 CPU, quelle que soit la limite de CPU spécifiée pour le conteneur.
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 sont déjà disponibles.
- 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
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, entrez
kubectl 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
Note: Si un conteneur spécifie sa propre limite de mémoire, mais ne spécifie pas de demande de mémoire, Kubernetes attribue automatiquement une demande de mémoire correspondant à la limite. De même, si un conteneur spécifie sa propre limite CPU, mais ne spécifie pas de demande de CPU, Kubernetes lui attribue automatiquement une demande de CPU qui correspond à cette limite.
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
3.4 - Affecter des ressources supplémentaires à un conteneur
Cette page montre comment affecter des ressources supplémentaires à un conteneur.
FEATURE STATE: Kubernetes v1.29 [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, entrez
kubectl 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
Pour les administrateurs de cluster
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, entrez
kubectl version
.
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 que test-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 :
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.
3.6 - Configurer un Pod pour utiliser un stockage de type PersistentVolume
Cette page montre comment configurer un Pod afin qu'il utilise un PersistentVolumeClaim comme système de stockage.
Voici un résumé des étapes:
-
En tant qu'administrateur d'un cluster, vous créez un PersistentVolume qui pointe vers un système de stockage physique. Vous n'associez le volume avec aucun Pod pour le moment.
-
En tant que développeur ou utilisateur du cluster, vous créez un PersistentVolumeClaim qui sera automatiquement lié à un PersistentVolume adapté.
-
Vous créez un Pod qui utilise le PersistentVolumeClaim créé précédemment comme stockage.
Pré-requis
-
Vous devez avoir à disposition un cluster qui n'a qu'un seul noeud, et l'utilitaire en ligne de commande
kubectl doit être configuré pour communiquer avec votre cluster. Si vous n'avez pas déja de cluster à disposition, vous pouvez en créer un en utilisant Minikube.
-
Vous pouvez vous familiariser avec la documentation des
Persistent Volumes.
Créer un fichier index.html sur votre noeud
Ouvrez une session shell sur le noeud de votre cluster. La facon d'ouvrir
la session va dependre de la configuration de votre cluster. Si vous utilisez Minikube,
vous pouvez ouvrir une session via la commande minikube ssh
.
Via la session sur ce noeud, créez un dossier /mnt/data
:
# En supposant que votre noeud utilise `sudo` pour les accès privilégiés
sudo mkdir /mnt/data
Dans le dossier /mnt/data
, créez un fichier index.html
:
# En supposant toujours que votre noeud utilise `sudo` pour les accès privilégiés
sudo sh -c "echo 'Hello from Kubernetes storage' > /mnt/data/index.html"
Note: Si votre noeud utilise un utilitaire d'accès privilégié autre que sudo
, les commandes notées ici devraient fonctionner en remplacant sudo
par le nom de l'utilitaire.
Testez que le fichier index.html
existe:
Le résultat de la commande doit être:
Hello from Kubernetes storage
Vous pouvez maintenant fermer l'accès shell à votre Noeud.
Créer un PersistentVolume
Dans cet exercice, vous allez créer un PersistentVolume de type hostpath. Kubernetes prend en charge le type hostPath pour le développement et les tests sur un cluster à noeud unique. Un PersistentVolume de type hostPath utilise un fichier ou un dossier sur le noeud pour simuler un stockage réseau.
Dans un cluster de production, vous n'utiliseriez pas le type hostPath. Plus communément, un administrateur de cluster
provisionnerait une ressource réseau comme un disque persistant Google Compute Engine,
un partage NFS ou un volume Amazon Elastic Block Store. Les administrateurs de cluster peuvent également
utiliser les StorageClasses
pour paramétrer du
provisioning dynamique.
Voici le fichier de configuration pour le PersistentVolume de type hostPath:
apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
Le fichier de configuration spécifie que le chemin du volume sur le noeud est /mnt/data
. Il spécifie aussi une taille de 10 gibibytes, ainsi qu'un mode d'accès de type ReadWriteOnce
, impliquant que le volume ne peut être monté en lecture et écriture que par un seul noeud. Le fichier définit un nom de StorageClass à manual
, ce qui sera utilisé pour attacher un PersistentVolumeClaim à ce PersistentVolume
Créez le PersistentVolume:
kubectl apply -f https://k8s.io/examples/pods/storage/pv-volume.yaml
Affichez les informations du PersistentVolume:
kubectl get pv task-pv-volume
Le résultat affiche que le PersitentVolume a un STATUS
de Available
.
Cela signifie qu'il n'a pas encore été attaché à un PersistentVolumeClaim.
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
task-pv-volume 10Gi RWO Retain Available manual 4s
Créer un PersistentVolumeClaim
La prochaine étape est de créer un PersistentVolumeClaim (demande de stockage). Les Pods utilisent les PersistentVolumeClaims pour demander un accès à du stockage physique.
Dans cet exercice, vous créez un PersistentVolumeClaim qui demande un volume d'au moins 3 GB, et qui peut être monté en lecture et écriture sur au moins un noeud.
Voici le fichier de configuration du PersistentVolumeClaim:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
Créez le PersistentVolumeClaim:
kubectl apply -f https://k8s.io/examples/pods/storage/pv-claim.yaml
Après avoir créé le PersistentVolumeClaim, le control plane de Kubernetes va chercher un PersistentVolume qui respecte les exigences du PersistentVolumeClaim. Si le control plane trouve un PersistentVolume approprié avec la même StorageClass, il attache la demande au volume.
Affichez à nouveau les informations du PersistentVolume:
kubectl get pv task-pv-volume
Maintenant, le résultat affiche un STATUS
à Bound
.
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
task-pv-volume 10Gi RWO Retain Bound default/task-pv-claim manual 2m
Affichez les informations du PersistentVolumeClaim:
kubectl get pvc task-pv-claim
Le résultat montre que le PersistentVolumeClaim est attaché au PersistentVolume task-pv-volume
.
NAME STATUS VOLUME CAPACITY ACCESSMODES STORAGECLASS AGE
task-pv-claim Bound task-pv-volume 10Gi RWO manual 30s
Créer un Pod
La prochaine étape est de créer un Pod qui utilise le PersistentVolumeClaim comme volume de stockage.
Voici le fichier de configuration du Pod:
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
volumes:
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
containers:
- name: task-pv-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage
Notez que le fichier de configuration du Pod spécifie un PersistentVolumeClaim et non un PersistentVolume. Du point de vue du Pod, la demande est un volume de stockage.
Créez le Pod:
kubectl apply -f https://k8s.io/examples/pods/storage/pv-pod.yaml
Vérifiez que le container dans le Pod est opérationnel:
kubectl get pod task-pv-pod
Lancez un shell dans le container du Pod:
kubectl exec -it task-pv-pod -- /bin/bash
Depuis le shell, vérifiez que nginx utilise le fichier index.html
du volume hostPath:
# Assurez vous de lancer ces 3 commandes dans le shell qui provient de
# la commande "kubectl exec" exécutée précedemment
apt update
apt install curl
curl http://localhost/
Le résultat doit afficher le texte qui a été écrit auparavant dans le fichier index.html
dans le volume hostPath:
Hello from Kubernetes storage
Si vous voyez ce message, vous avez configuré un Pod qui utilise un PersistentVolumeClaim comme stockage avec succès.
Nettoyage
Supprimez le Pod, le PersistentVolumeClaim et le PersistentVolume:
kubectl delete pod task-pv-pod
kubectl delete pvc task-pv-claim
kubectl delete pv task-pv-volume
Si vous n'avez pas déja de session ouverte sur le noeud de votre cluster, ouvrez en un de la même manière que précédemment.
Dans la session shell, supprimez les fichiers et dossiers que vous avez créé:
# En assumant que le noeud utilise "sudo" pour les accès privilégiés
sudo rm /mnt/data/index.html
sudo rmdir /mnt/data
Vous pouvez maintenant arrêter la session shell vers votre noeud.
Monter le même PersistentVolume à deux endroits
Vous pouvez monter plusieurs fois un même PersistentVolume
à plusieurs endroits différents dans votre container nginx:
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- name: test
image: nginx
volumeMounts:
# a mount for site-data
- name: config
mountPath: /usr/share/nginx/html
subPath: html
# another mount for nginx config
- name: config
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
volumes:
- name: config
persistentVolumeClaim:
claimName: test-nfs-claim
/usr/share/nginx/html
pour le site statique
/etc/nginx/nginx.conf
pour la configuration par défaut
Contrôle d'accès
Le stockage configuré avec un ID de groupe (GID) ne permettra l'écriture que par les Pods qui utilisent le même GID.
Les GID manquants ou qui ne correspondent pas entraîneront des erreurs d'autorisation refusée. Pour alléger la coordination avec les utilisateurs, un administrateur peut annoter un PersistentVolume
avec un GID. Ensuite, le GID sera automatiquement ajouté à tout pod qui utilise le PersistentVolume.
Utilisez l'annotation pv.beta.kubernetes.io/gid
comme ceci:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
annotations:
pv.beta.kubernetes.io/gid: "1234"
Lorsqu'un Pod attache un PersistentVolume qui a une annotation pour le GID, ce dernier est appliqué à tous les containers du Pod de la même façon que les GID spécifiés dans le contexte de sécurité du Pod. Peu importe s'il provient d'une annotation du PersistentVolume ou de la spécification du Pod, chaque GID sera appliqué au premier process exécuté dans chaque container.
Note: Quand un Pod attache un PersistentVolume, les GID associés avec le PersistentVolume ne sont pas répércutés sur la spécification de la ressource du Pod.
A suivre
Références
3.7 - 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.
Note: Ce document décrit le comportement des comptes de service dans un cluster mis en place conformément aux recommandations du projet Kubernetes. L'administrateur de votre cluster a peut-être personnalisé le comportement dans votre cluster, dans ce cas cette documentation pourrait être non applicable.
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, entrez
kubectl 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: ...
Note: Le contenu de 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
FEATURE STATE: Kubernetes v1.12 [beta]
Note: 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.
3.8 - 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, entrez kubectl 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 :
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"
}
}
}
Note: Si vous utilisez le credentials store de Docker, vous ne verrez pas cette entrée 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
.
Note: Saisir des secrets sur la ligne de commande peut les conserver dans l'historique de votre shell sans protection, et ces secrets peuvent également être visibles par d'autres utilisateurs sur votre ordinateur pendant l'exécution de 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":"jdoe@example.com","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
3.9 - 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, entrez
kubectl 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 registry.k8s.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: registry.k8s.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -f /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 -f /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 "registry.k8s.io/busybox"
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "registry.k8s.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 "registry.k8s.io/busybox"
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "registry.k8s.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 registry.k8s.io/liveness
.
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness
image: registry.k8s.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: registry.k8s.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.
Note: Readiness probes fonctionnent sur le conteneur pendant tout son cycle de vie.
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.
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 tenter failureThreshold
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
Référence
3.10 - 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, entrez
kubectl version
.
Ajouter un label à un nœud
-
Listez les nœuds de votre cluster :
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 label disktype=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.
3.11 - 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, entrez
kubectl 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
3.12 - 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, entrez
kubectl 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"
Avertissement: Lorsque vous passez plusieurs fois --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'environnement SPECIAL_LEVEL_KEY
dans la spécification du Pod.
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: registry.k8s.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
kubectl create -f https://kubernetes.io/examples/configmap/configmaps.yaml
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
.
Note: Cette fonctionnalité est disponible dans Kubernetes v1.6 et versions ultérieures.
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: registry.k8s.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: registry.k8s.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
:
kubectl logs dapi-test-pod
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: registry.k8s.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
Avertissement: S'il y a des fichiers dans le dossier /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: registry.k8s.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 :
Avertissement: Comme avant, tous les fichiers précédents dans le répertoire /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.
Note: Un conteneur utilisant un ConfigMap comme volume
subPath ne recevra pas les mises à jour de ConfigMap.
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.
Note: Les ConfigMaps doivent faire référence aux fichiers de propriétés, et non les remplacer.
Pensez à la ConfigMap comme représentant quelque chose de similaire au répertoire
/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 :
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
3.13 - Partager l'espace de nommage des processus entre les conteneurs d'un Pod
FEATURE STATE: 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, entrez
kubectl version
.
Le partage de l'espace de nommage du processus est activé en utilisant le champ shareProcessNamespace
de v1.PodSpec
. Par exemple:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
shareProcessNamespace: true
containers:
- name: nginx
image: nginx
- name: shell
image: busybox
securityContext:
capabilities:
add:
- SYS_PTRACE
stdin: true
tty: true
-
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 lancez ps
:
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 comme kill -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.
3.14 - 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, entrez
kubectl 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:
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: registry.k8s.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
-
Pour convertir le fichier docker-compose.yml
en fichiers que vous pouvez utiliser avec kubectl
, lancez kompose convert
et ensuite kubectl 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
.
Guide de l'utilisateur
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 git@github.com: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
Note: Si vous poussez manuellement les artefacts OpenShift en utilisant
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 .
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 |
Note: Le label 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 |
Note: L'objet contrôleur peut être 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.
4 - Gérez vos objets Kubernetes
5 - Injecter des données dans les applications
Spécifier la configuration et paramètres pour les Pods qui exécutent vos charges de travail.
5.1 - Définir une commande et ses arguments pour un Container
Cette page montre comment définir les commandes et arguments d'un container au sein d'un Pod.
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, entrez
kubectl version
.
Définir une commande et ses arguments à la création d'un Pod
Lorsque vous créez un Pod, il est possible de définir une commande et des arguments
pour les containers qui seront exécutés dans votre Pod.
Pour définir une commande, ajoutez un champ command
dans le fichier de configuration.
Pour définir des arguments, ajoutez le champ args
dans le fichier de configuration.
La commande et les arguments qui sont définis ne peuvent être changés après la création du Pod.
La commande et les arguments que vous définissez dans le fichier de configuration
écraseront la commande et les arguments définis par l'image utilisée par le container.
Si vous définissez uniquement des arguments, la commande par défaut sera exécutée avec les arguments que vous avez configurés.
Note: Le champ command
correspond à entrypoint
dans certains runtimes de containers.
Dans cet exercice, vous allez créer un Pod qui exécute un container.
Le fichier de configuration pour le Pod défini une commande ainsi que deux arguments:
apiVersion: v1
kind: Pod
metadata:
name: command-demo
labels:
purpose: demonstrate-command
spec:
containers:
- name: command-demo-container
image: debian
command: ["printenv"]
args: ["HOSTNAME", "KUBERNETES_PORT"]
restartPolicy: OnFailure
-
Créez un Pod en utilisant le fichier YAML de configuration suivant:
kubectl apply -f https://k8s.io/examples/pods/commands.yaml
-
Listez les Pods
Le résultat montre que le container exécuté dans le Pod nommé container-demo a complété son exécution.
-
Pour voir le résultat de la commade exécutée dans le container, on peut afficher les logs pour le Pod:
kubectl logs command-demo
Le résultat montre les valeurs des variables d'environnement HOSTNAME et KUBERNETES_PORT:
command-demo
tcp://10.3.240.1:443
Utiliser des variables d'environnement dans les arguments
Dans l'exemple précédent, vous avez défini des arguments en donnant
directement les valeurs en format chaîne de caractères.
Il est aussi possible de définir des arguments en utilisant des variables d'environnement:
env:
- name: MESSAGE
value: "hello world"
command: ["/bin/echo"]
args: ["$(MESSAGE)"]
Il est donc possible de définir un argument pour un Pod en utilisant n'importe
quelle méthode disponible pour définir des variables d'environnements, ce qui inclut les
ConfigMaps
et les
Secrets.
Note: Les variables d'environnements apparaissent ente parenthèses "$(VAR)"
.
Cette écriture est requise pour que la variable soit correctement
développée dans les champs command
ou args
.
Exécuter une commande à l'intérieur d'un shell
Dans certains cas, certaines commandes nécéssitent d'être exécutées dans un shell. Par exemple, certaines commandes consistent en une chaîne de commandes, ou un script shell. Pour exécuter une commande dans un shell, il est possible d'envelopper la commande comme ceci:
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]
A suivre
5.2 - Définir des variables d'environnement dépendantes
Cette page montre comment définir des variables d'environnement
interdépendantes pour un container dans un Pod 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:
Définir une variable d'environnement dépendante pour un container
Lorsque vous créez un Pod, vous pouvez configurer des variables d'environnement interdépendantes pour les containers exécutés dans un Pod.
Pour définir une variable d'environnement dépendante, vous pouvez utiliser le format $(VAR_NAME) dans le champ value
de la spécification env
dans le fichier de configuration.
Dans cette exercice, vous allez créer un Pod qui exécute un container. Le fichier de configuration de ce Pod définit des variables d'environnement interdépendantes avec une ré-utilisation entre les différentes variables. Voici le fichier de configuration de ce Pod:
apiVersion: v1
kind: Pod
metadata:
name: dependent-envars-demo
spec:
containers:
- name: dependent-envars-demo
args:
- while true; do echo -en '\n'; printf UNCHANGED_REFERENCE=$UNCHANGED_REFERENCE'\n'; printf SERVICE_ADDRESS=$SERVICE_ADDRESS'\n';printf ESCAPED_REFERENCE=$ESCAPED_REFERENCE'\n'; sleep 30; done;
command:
- sh
- -c
image: busybox:1.28
env:
- name: SERVICE_PORT
value: "80"
- name: SERVICE_IP
value: "172.17.0.1"
- name: UNCHANGED_REFERENCE
value: "$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
- name: PROTOCOL
value: "https"
- name: SERVICE_ADDRESS
value: "$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
- name: ESCAPED_REFERENCE
value: "$$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
-
Créez un Pod en utilisant ce fichier de configuration:
kubectl apply -f https://k8s.io/examples/pods/inject/dependent-envars.yaml
pod/dependent-envars-demo created
-
Listez le Pod:
kubectl get pods dependent-envars-demo
NAME READY STATUS RESTARTS AGE
dependent-envars-demo 1/1 Running 0 9s
-
Affichez les logs pour le container exécuté dans votre Pod:
kubectl logs pod/dependent-envars-demo
UNCHANGED_REFERENCE=$(PROTOCOL)://172.17.0.1:80
SERVICE_ADDRESS=https://172.17.0.1:80
ESCAPED_REFERENCE=$(PROTOCOL)://172.17.0.1:80
Comme montré ci-dessus, vous avez défini une dépendance correcte pour SERVICE_ADDRESS
, une dépendance manquante pour UNCHANGED_REFERENCE
, et avez ignoré la dépendance pour ESCAPED_REFERENCE
.
Lorsqu'une variable d'environnement est déja définie alors
qu'elle est référencée par une autre variable, la référence s'effectue
correctement, comme dans l'exemple de SERVICE_ADDRESS
.
Il est important de noter que l'ordre dans la liste env
est important.
Une variable d'environnement ne sera pas considérée comme "définie"
si elle est spécifiée plus bas dans la liste. C'est pourquoi
UNCHANGED_REFERENCE
ne résout pas correctement $(PROTOCOL)
dans l'exemple précédent.
Lorsque la variable d'environnement n'est pas définie, ou n'inclut qu'une partie des variables, la variable non définie sera traitée comme une chaine de caractères, par exemple UNCHANGED_REFERENCE
. Notez que les variables d'environnement malformées n'empêcheront généralement pas le démarrage du conteneur.
La syntaxe $(VAR_NAME)
peut être échappée avec un double $
, par exemple $$(VAR_NAME)
.
Les références échappées ne sont jamais développées, que la variable référencée
soit définie ou non. C'est le cas pour l'exemple ESCAPED_REFERENCE
ci-dessus.
A suivre
5.3 - Définir des variables d'environnement pour un Container
Cette page montre comment définir des variables d'environnement pour un
container au sein d'un Pod 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:
Définir une variable d'environnement pour un container
Lorsque vous créez un Pod, vous pouvez définir des variables d'environnement
pour les containers qui seront exécutés au sein du Pod.
Pour les définir, utilisez le champ env
ou envFrom
dans le fichier de configuration.
Dans cet exercice, vous allez créer un Pod qui exécute un container. Le fichier de configuration pour ce Pod contient une variable d'environnement s'appelant DEMO_GREETING
et sa valeur est "Hello from the environment"
. Voici le fichier de configuration du Pod:
apiVersion: v1
kind: Pod
metadata:
name: envar-demo
labels:
purpose: demonstrate-envars
spec:
containers:
- name: envar-demo-container
image: gcr.io/google-samples/node-hello:1.0
env:
- name: DEMO_GREETING
value: "Hello from the environment"
- name: DEMO_FAREWELL
value: "Such a sweet sorrow"
-
Créez un Pod à partir de ce fichier:
kubectl apply -f https://k8s.io/examples/pods/inject/envars.yaml
-
Listez les Pods:
kubectl get pods -l purpose=demonstrate-envars
Le résultat sera similaire à celui-ci:
NAME READY STATUS RESTARTS AGE
envar-demo 1/1 Running 0 9s
-
Listez les variables d'environnement au sein du container:
kubectl exec envar-demo -- printenv
Le résultat sera similaire à celui-ci:
NODE_VERSION=4.4.2
EXAMPLE_SERVICE_PORT_8080_TCP_ADDR=10.3.245.237
HOSTNAME=envar-demo
...
DEMO_GREETING=Hello from the environment
DEMO_FAREWELL=Such a sweet sorrow
Note: Les variables d'environnement définies dans les champs env
ou envFrom
écraseront les variables définies dans l'image utilisée par le container.
Note: Une variable d'environnement peut faire référence à une autre variable,
cependant l'ordre de déclaration est important. Une variable faisant référence
à une autre doit être déclarée après la variable référencée.
De plus, il est recommandé d'éviter les références circulaires.
Utilisez des variables d'environnement dans la configuration
Les variables d'environnement que vous définissez dans la configuration d'un Pod peuvent être utilisées à d'autres endroits de la configuration, comme par exemple dans les commandes et arguments pour les containers.
Dans l'exemple ci-dessous, les variables d'environnement GREETING
, HONORIFIC
, et
NAME
ont des valeurs respectives de Warm greetings to
, The Most Honorable
, et Kubernetes
. Ces variables sont ensuites utilisées comme arguments
pour le container env-print-demo
.
apiVersion: v1
kind: Pod
metadata:
name: print-greeting
spec:
containers:
- name: env-print-demo
image: bash
env:
- name: GREETING
value: "Warm greetings to"
- name: HONORIFIC
value: "The Most Honorable"
- name: NAME
value: "Kubernetes"
command: ["echo"]
args: ["$(GREETING) $(HONORIFIC) $(NAME)"]
Une fois le Pod créé, la commande echo Warm greetings to The Most Honorable Kubernetes
sera exécutée dans le container.
A suivre
5.4 - Exposer les informations du Pod aux containers via les variables d'environnement
Cette page montre comment un Pod peut utiliser des variables d'environnement pour
exposer ses propres informations aux containers qu'il exécute via la
downward API.
Vous pouvez utiliser des variables d'environnement pour exposer des champs
de configuration du Pod, des containers ou les deux.
Dans Kubernetes, il y a deux façons distinctes d'exposer les champs de
configuration de Pod et de container à l'intérieur d'un container:
- Via les variables d'environnement, comme expliqué dans cette tâche,
- Via un volume
Ensemble, ces deux façons d'exposer des informations du Pod et du container sont appelées la downward API.
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:
Utiliser les champs du Pod comme variables d'environnement
Dans cette partie de l'exercice, vous allez créer un Pod qui a un container,
et vous allez projeter les champs d'informations du Pod à l'intérieur du
container comme variables d'environnement.
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-fieldref
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;
sleep 10;
done;
env:
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: MY_POD_SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
restartPolicy: Never
Dans ce fichier de configuration, on trouve cinq variables d'environnement.
Le champ env
est une liste de variables d'environnement.
Le premier élément de la liste spécifie que la valeur de la variable d'environnement
MY_NODE_NAME
hérite du champ spec.nodeName
du Pod.
Il en va de même pour les autres variables d'environnement, qui héritent
des autres champs du Pod.
Note: Les champs de configuration présents dans cet exemple sont des champs du Pod. Ce ne sont pas les champs du container à l'intérieur du Pod.
Créez le Pod:
kubectl apply -f https://k8s.io/examples/pods/inject/dapi-envars-pod.yaml
Vérifiez que le container dans le Pod fonctionne:
# Si le nouveau Pod n'est pas fonctionnel, re-exécutez cette commande plusieurs fois
kubectl get pods
Affichez les logs du container:
kubectl logs dapi-envars-fieldref
Le résultat doit afficher les valeurs des variables d'environnement choisies:
minikube
dapi-envars-fieldref
default
172.17.0.4
default
Pour comprendre pourquoi ces valeurs apparaissent dans les logs, regardez les champs command
et args
du fichier de configuration. Lorsque le container s'exécute, il écrit les valeurs de 5 variables d'environnement vers stdout, avec un interval de 10 secondes.
Ensuite, exécutez un shell à l'intérieur du container:
kubectl exec -it dapi-envars-fieldref -- sh
Dans ce shell, listez les variables d'environnement:
# À exécuter à l'intérieur du container
printenv
Le résultat doit montrer que certaines variables d'environnement contiennent
les informations du Pod:
MY_POD_SERVICE_ACCOUNT=default
...
MY_POD_NAMESPACE=default
MY_POD_IP=172.17.0.4
...
MY_NODE_NAME=minikube
...
MY_POD_NAME=dapi-envars-fieldref
Dans l'exercice précédent, vous avez utilisé les informations du Pod à
travers des variables d'environnement.
Dans cet exercice, vous allez faire passer des champs appartenant
au container
qui est exécuté à l'intérieur du Pod.
Voici un fichier de configuration pour un autre Pod qui ne contient qu'un seul
container:
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-resourcefieldref
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox:1.24
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_CPU_REQUEST MY_CPU_LIMIT;
printenv MY_MEM_REQUEST MY_MEM_LIMIT;
sleep 10;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
env:
- name: MY_CPU_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.cpu
- name: MY_CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.cpu
- name: MY_MEM_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.memory
- name: MY_MEM_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.memory
restartPolicy: Never
Dans ce fichier, vous pouvez voir 4 variables d'environnement.
Le champ env
est une liste de variables d'environnement.
Le premier élément de la liste spécifie que la variable d'environnement MY_CPU_REQUEST
aura sa valeur à partir du champ requests.cpu
du container avec le nom test-container
. Il en va de même pour les autres variables d'environnement, qui hériteront des champs du container qui sera exécuté.
Créez le Pod:
kubectl apply -f https://k8s.io/examples/pods/inject/dapi-envars-container.yaml
Vérifiez que le container dans le Pod fonctionne:
# Si le nouveau Pod n'est pas fonctionnel, re-exécutez cette commande plusieurs fois
kubectl get pods
Affichez les logs du container:
kubectl logs dapi-envars-resourcefieldref
Le résultat doit afficher les valeurs des variables selectionnées:
1
1
33554432
67108864
A suivre
En savoir plus sur les pods, les containers et les variables d'environnement avec les documentations de référence:
5.5 - Exposer les informations d'un Pod à ses containers à travers des fichiers
Cette page montre comment un Pod peut utiliser un
volume en downwardAPI
,
pour exposer des informations sur lui-même aux containers executés dans ce Pod.
Vous pouvez utiliser un volume downwardAPI
pour exposer des champs
de configuration du Pod, de ses containers ou les deux.
Dans Kubernetes, il y a deux façons distinctes d'exposer les champs de
configuration de Pod et de container à l'intérieur d'un container:
Ensemble, ces deux façons d'exposer des informations du Pod et du container sont appelées la downward API.
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:
Stocker des champs d'un Pod
Dans cette partie de l'exercice, vous allez créer un Pod qui a un container,
et vous allez projeter les champs d'informations du Pod à l'intérieur du
container via des fichiers dans le container.
Voici le fichier de configuration du Pod:
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
annotations:
build: two
builder: john-doe
spec:
containers:
- name: client-container
image: registry.k8s.io/busybox
command: ["sh", "-c"]
args:
- while true; do
if [[ -e /etc/podinfo/labels ]]; then
echo -en '\n\n'; cat /etc/podinfo/labels; fi;
if [[ -e /etc/podinfo/annotations ]]; then
echo -en '\n\n'; cat /etc/podinfo/annotations; fi;
sleep 5;
done;
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
Dans la configuration, on peut voir que le Pod a un volume de type downward API
, et que le container monte ce volume sur le chemin /etc/podinfo
.
Dans la liste items
sous la définition downwardAPI
, on peut voir que
chaque élément de la liste définit un fichier du volume Downward API.
Le premier élément spécifie que le champ metadata.labels
doit être exposé dans un fichier appelé labels
.
Le second élement spécifie que les champs annotations
du Pod doivent
être stockés dans un fichier appelé annotations
.
Note: Les champs de configuration présents dans cet exemple sont des champs du Pod. Ce ne sont pas les champs du container à l'intérieur du Pod.
Créez le Pod:
kubectl apply -f https://k8s.io/examples/pods/inject/dapi-volume.yaml
Vérifiez que le container dans le Pod fonctionne:
Affichez les logs du container:
kubectl logs kubernetes-downwardapi-volume-example
Le résultat doit afficher le contenu des fichiers labels
et annotations
:
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"
build="two"
builder="john-doe"
Exécutez un shell à l'intérieur du container de votre Pod:
kubectl exec -it kubernetes-downwardapi-volume-example -- sh
Dans ce shell, affichez le contenu du ficher labels
:
/# cat /etc/podinfo/labels
Le résultat doit montrer que tous les labels du Pod ont
été écrits dans le fichier labels
:
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"
Il en va de même pour le fichier annotations
:
/# cat /etc/podinfo/annotations
Listez les fichiers présents dans le dossier /etc/podinfo
:
Dans le résultat, vous pouvez voir que les fichiers labels
et annotations
sont dans un sous-dossier temporaire.
Dans cet exemple, ..2982_06_02_21_47_53.299460680
. Dans le dossier
/etc/podinfo
, le dossier ..data
est un lien symbolique au dossier temporaire.
De plus, dans le dossier /etc/podinfo
, les fichiers labels
et annotations
sont eux aussi des liens symboliques.
drwxr-xr-x ... Feb 6 21:47 ..2982_06_02_21_47_53.299460680
lrwxrwxrwx ... Feb 6 21:47 ..data -> ..2982_06_02_21_47_53.299460680
lrwxrwxrwx ... Feb 6 21:47 annotations -> ..data/annotations
lrwxrwxrwx ... Feb 6 21:47 labels -> ..data/labels
/etc/..2982_06_02_21_47_53.299460680:
total 8
-rw-r--r-- ... Feb 6 21:47 annotations
-rw-r--r-- ... Feb 6 21:47 labels
L'utilisation de liens symboliques permet une mise à jour atomique des
données. Les mises à jour sont écrites dans un nouveau dossier temporaire,
puis les liens symboliques sont mis à jour avec rename(2).
Note: Un container utilisant la Downward API via un volume monté dans un
subPath ne recevra pas de mise à jour de la Downward API.
Quittez la session shell:
Stocker des champs d'un container
Dans l'exercice précedent, vous avez rendu accessible des champs d'un Pod via la
Downward API.
Dans l'exercice suivant, vous allez faire passer de la même manière des champs
qui appartiennent au
container, plutôt qu'au Pod.
Voici un fichier de configuration pour un Pod qui n'a qu'un seul container:
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example-2
spec:
containers:
- name: client-container
image: registry.k8s.io/busybox:1.24
command: ["sh", "-c"]
args:
- while true; do
echo -en '\n';
if [[ -e /etc/podinfo/cpu_limit ]]; then
echo -en '\n'; cat /etc/podinfo/cpu_limit; fi;
if [[ -e /etc/podinfo/cpu_request ]]; then
echo -en '\n'; cat /etc/podinfo/cpu_request; fi;
if [[ -e /etc/podinfo/mem_limit ]]; then
echo -en '\n'; cat /etc/podinfo/mem_limit; fi;
if [[ -e /etc/podinfo/mem_request ]]; then
echo -en '\n'; cat /etc/podinfo/mem_request; fi;
sleep 5;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "cpu_limit"
resourceFieldRef:
containerName: client-container
resource: limits.cpu
divisor: 1m
- path: "cpu_request"
resourceFieldRef:
containerName: client-container
resource: requests.cpu
divisor: 1m
- path: "mem_limit"
resourceFieldRef:
containerName: client-container
resource: limits.memory
divisor: 1Mi
- path: "mem_request"
resourceFieldRef:
containerName: client-container
resource: requests.memory
divisor: 1Mi
Dans cette configuration, on peut voir que le Pod a un volume de type
downwardAPI
,
et que le container monte ce volume sur le chemin /etc/podinfo
.
Dans la liste items
sous la définition downwardAPI
, on peut voir que
chaque élément de la liste définit un fichier du volume Downward API.
Le premier élément spécifie que dans le container nommé client-container
,
la valeur du champ limits.cpu
dans un format spécifié par 1m
sera exposé dans
un fichier appelé cpu_limit
. Le champ divisor
est optionnel et a une valeur
par défaut de 1
. Un diviseur de 1 spécifie l'unité coeur
pour la ressource
cpu
, et l'unité bytes
pour la ressource memory
.
Créez le Pod:
kubectl apply -f https://k8s.io/examples/pods/inject/dapi-volume-resources.yaml
Exécutez un shell à l'intérieur du container de votre Pod:
kubectl exec -it kubernetes-downwardapi-volume-example-2 -- sh
Dans le shell, affichez le contenu du fichier cpu_limit
:
# À exécuter à l'intérieur du container
cat /etc/podinfo/cpu_limit
Vous pouvez utiliser des commandes similaires pour afficher les fichiers
cpu_request
, mem_limit
et mem_request
.
Projection de champs sur des chemins spécifiques et droits d'accès
Vous pouvez projeter des champs sur des chemins spécifiques,
et assigner des permissions pour chacun de ces chemins.
Pour plus d'informations, regardez la documentation des
Secrets.
A suivre
5.6 - Distribuer des données sensibles de manière sécurisée avec les Secrets
Cette page montre comment injecter des données sensibles comme des mots de passe ou des clés de chiffrement dans 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:
Supposons que vous avez deux données sensibles: un identifiant my-app
et un
mot de passe
39528$vdg7Jb
. Premièrement, utilisez un outil capable d'encoder vos données
dans un format base64. Voici un exemple en utilisant le programme base64:
echo -n 'my-app' | base64
echo -n '39528$vdg7Jb' | base64
Le résultat montre que la représentation base64 de l'utilisateur est bXktYXBw
,
et que la représentation base64 du mot de passe est Mzk1MjgkdmRnN0pi
.
Avertissement: Utilisez un outil local approuvé par votre système d'exploitation
afin de réduire les risques de sécurité liés à l'utilisation d'un outil externe.
Créer un Secret
Voici un fichier de configuration que vous pouvez utiliser pour créer un Secret
qui contiendra votre identifiant et mot de passe:
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
username: bXktYXBw
password: Mzk1MjgkdmRnN0pi
-
Créez le Secret:
kubectl apply -f https://k8s.io/examples/pods/inject/secret.yaml
-
Listez les informations du Secret:
kubectl get secret test-secret
Résultat:
NAME TYPE DATA AGE
test-secret Opaque 2 1m
-
Affichez les informations détaillées du Secret:
kubectl describe secret test-secret
Résultat:
Name: test-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 13 bytes
username: 7 bytes
Créer un Secret en utilisant kubectl
Si vous voulez sauter l'étape d'encodage, vous pouvez créer le même Secret
en utilisant la commande kubectl create secret
. Par exemple:
kubectl create secret generic test-secret --from-literal='username=my-app' --from-literal='password=39528$vdg7Jb'
Cette approche est plus pratique. La façon de faire plus explicite
montrée précédemment permet de démontrer et comprendre le fonctionnement des Secrets.
Créer un Pod qui a accès aux données sensibles à travers un Volume
Voici un fichier de configuration qui permet de créer un Pod:
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
spec:
containers:
- name: test-container
image: nginx
volumeMounts:
# name must match the volume name below
- name: secret-volume
mountPath: /etc/secret-volume
readOnly: true
# The secret data is exposed to Containers in the Pod through a Volume.
volumes:
- name: secret-volume
secret:
secretName: test-secret
-
Créez le Pod:
kubectl apply -f https://k8s.io/examples/pods/inject/secret-pod.yaml
-
Vérifiez que le Pod est opérationnel:
kubectl get pod secret-test-pod
Résultat:
NAME READY STATUS RESTARTS AGE
secret-test-pod 1/1 Running 0 42m
-
Exécutez une session shell dans le Container qui est dans votre Pod:
kubectl exec -i -t secret-test-pod -- /bin/bash
-
Les données sont exposées au container à travers un Volume monté sur
/etc/secret-volume
.
Dans votre shell, listez les fichiers du dossier /etc/secret-volume
:
# À exécuter à l'intérieur du container
ls /etc/secret-volume
Le résultat montre deux fichiers, un pour chaque donnée du Secret:
password username
-
Toujours dans le shell, affichez le contenu des fichiers
username
et password
:
# À exécuter à l'intérieur du container
echo "$( cat /etc/secret-volume/username )"
echo "$( cat /etc/secret-volume/password )"
Le résultat doit contenir votre identifiant et mot de passe:
my-app
39528$vdg7Jb
Vous pouvez alors modifier votre image ou votre ligne de commande pour que le programme
recherche les fichiers contenus dans le dossier du champ mountPath
.
Chaque clé du Secret data
sera exposée comme un fichier à l'intérieur de ce dossier.
Monter les données du Secret sur des chemins spécifiques
Vous pouvez contrôler les chemins sur lesquels les données des Secrets sont montées.
Utilisez le champ .spec.volumes[].secret.items
pour changer le
chemin cible de chaque donnée:
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
Voici ce qu'il se passe lorsque vous déployez ce Pod:
- La clé
username
du Secret mysecret
est montée dans le container sur le chemin
/etc/foo/my-group/my-username
au lieu de /etc/foo/username
.
- La clé
password
du Secret n'est pas montée dans le container.
Si vous listez de manière explicite les clés en utilisant le champ .spec.volumes[].secret.items
,
il est important de prendre en considération les points suivants:
- Seules les clés listées dans le champ
items
seront montées.
- Pour monter toutes les clés du Secret, toutes doivent être
définies dans le champ
items
.
- Toutes les clés définies doivent exister dans le Secret.
Sinon, le volume ne sera pas créé.
Appliquer des permissions POSIX aux données
Vous pouvez appliquer des permissions POSIX pour une clé d'un Secret. Si vous n'en configurez pas, les permissions seront par défaut 0644
.
Vous pouvez aussi définir des permissions pour tout un Secret, et redéfinir les permissions pour chaque clé si nécessaire.
Par exemple, il est possible de définir un mode par défaut:
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: 0400
Le Secret sera monté sur /etc/foo
; tous les fichiers créés par le secret
auront des permissions de type 0400
.
Note: Si vous définissez un Pod en utilisant le format JSON, il est important de
noter que la spécification JSON ne supporte pas le système octal, et qu'elle
comprendra la valeur 0400
comme la valeur décimale 400
.
En JSON, utilisez plutôt l'écriture décimale pour le champ defaultMode
.
Si vous utilisez le format YAML, vous pouvez utiliser le système octal
pour définir defaultMode
.
Définir des variables d'environnement avec des Secrets
Il est possible de monter les données des Secrets comme variables d'environnement dans vos containers.
Si un container consomme déja un Secret en variables d'environnement,
la mise à jour de ce Secret ne sera pas répercutée dans le container tant
qu'il n'aura pas été redémarré. Il existe cependant des solutions tierces
permettant de redémarrer les containers lors d'une mise à jour du Secret.
Définir une variable d'environnement à partir d'un seul Secret
-
Définissez une variable d'environnement et sa valeur à l'intérieur d'un Secret:
kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
-
Assignez la valeur de backend-username
définie dans le Secret
à la variable d'environnement SECRET_USERNAME
dans la configuration du Pod.
apiVersion: v1
kind: Pod
metadata:
name: env-single-secret
spec:
containers:
- name: envars-test-container
image: nginx
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: backend-user
key: backend-username
-
Créez le Pod:
kubectl create -f https://k8s.io/examples/pods/inject/pod-single-secret-env-variable.yaml
-
À l'intérieur d'une session shell, affichez le contenu de la variable
d'environnement SECRET_USERNAME
:
kubectl exec -i -t env-single-secret -- /bin/sh -c 'echo $SECRET_USERNAME'
Le résultat est:
backend-admin
Définir des variables d'environnement à partir de plusieurs Secrets
-
Comme précédemment, créez d'abord les Secrets:
kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
kubectl create secret generic db-user --from-literal=db-username='db-admin'
-
Définissez les variables d'environnement dans la configuration du Pod.
apiVersion: v1
kind: Pod
metadata:
name: envvars-multiple-secrets
spec:
containers:
- name: envars-test-container
image: nginx
env:
- name: BACKEND_USERNAME
valueFrom:
secretKeyRef:
name: backend-user
key: backend-username
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-user
key: db-username
-
Créez le Pod:
kubectl create -f https://k8s.io/examples/pods/inject/pod-multiple-secret-env-variable.yaml
-
Dans un shell, listez les variables d'environnement du container:
kubectl exec -i -t envvars-multiple-secrets -- /bin/sh -c 'env | grep _USERNAME'
Le résultat est:
DB_USERNAME=db-admin
BACKEND_USERNAME=backend-admin
Note: Cette fonctionnalité n'est disponible que dans les versions de Kubernetes
égales ou supérieures à v1.6.
-
Créez un Secret contenant plusieurs paires de clé-valeur:
kubectl create secret generic test-secret --from-literal=username='my-app' --from-literal=password='39528$vdg7Jb'
-
Utilisez envFrom
pour définir toutes les données du Secret comme variables
d'environnement. Les clés du Secret deviendront les noms des variables
d'environnement à l'intérieur du Pod.
apiVersion: v1
kind: Pod
metadata:
name: envfrom-secret
spec:
containers:
- name: envars-test-container
image: nginx
envFrom:
- secretRef:
name: test-secret
-
Créez le Pod:
kubectl create -f https://k8s.io/examples/pods/inject/pod-secret-envFrom.yaml
-
Dans votre shell, affichez les variables d'environnement username
et password
:
kubectl exec -i -t envfrom-secret -- /bin/sh -c 'echo "username: $username\npassword: $password\n"'
Le résultat est:
username: my-app
password: 39528$vdg7Jb
Références
A suivre
6 - Exécution des applications
Exécutez et gérez des applications stateful et stateless.
6.1 - Exécuter une application stateless avec un Déploiement
Cette page montre comment exécuter une application en utilisant une resource Deployment (déploiement) dans Kubernetes.
Objectifs
- Créer un déploiement nginx.
- Utiliser kubectl pour afficher des informations sur le déploiement.
- Mettre à jour le déploiement.
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.9.
Pour consulter la version, entrez
kubectl version
.
Création et exploration d'un déploiement nginx
Vous pouvez exécuter une application en créant un objet
déploiement Kubernetes, et vous pouvez décrire un
déploiement dans un fichier YAML. Par exemple,
ce fichier YAML décrit un déploiement qui exécute l'image Docker nginx:1.14.2 :
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
-
Créez un déploiement basé sur ce fichier YAML:
kubectl apply -f https://k8s.io/examples/application/deployment.yaml
-
Affichez les informations du déploiement:
kubectl describe deployment nginx-deployment
Le résultat sera similaire à ceci :
Name: nginx-deployment
Namespace: default
CreationTimestamp: Tue, 30 Aug 2016 18:11:37 -0700
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision=1
Selector: app=nginx
Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.14.2
Port: 80/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-1771418926 (2/2 replicas created)
No events.
-
Affichez les Pods créés par le déploiement :
kubectl get pods -l app=nginx
Le résultat sera similaire à ceci :
NAME READY STATUS RESTARTS AGE
nginx-deployment-1771418926-7o5ns 1/1 Running 0 16h
nginx-deployment-1771418926-r18az 1/1 Running 0 16h
-
Affichez les informations d'un Pod :
kubectl describe pod <pod-name>
où est le nom d'un de vos Pods.
Mise à jour du déploiement
Vous pouvez mettre à jour le déploiement en appliquant un nouveau fichier YAML.
Ce fichier YAML indique que le déploiement doit être mis à jour
pour utiliser nginx 1.16.1.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.16.1 # Update the version of nginx from 1.14.2 to 1.16.1
ports:
- containerPort: 80
-
Appliquez le nouveau fichier YAML :
kubectl apply -f https://k8s.io/examples/application/deployment-update.yaml
-
Regardez le déploiement créer de nouveaux pods et supprimer les anciens :
kubectl get pods -l app=nginx
Mise à l'échelle de l'application en augmentant le nombre de réplicas
Vous pouvez augmenter le nombre de pods dans votre déploiement en appliquant un nouveau fichier YAML.
Ce fichier YAML définit replicas
à 4, ce qui spécifie que le déploiement devrait avoir quatre pods :
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 4 # Update the replicas from 2 to 4
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.16.1
ports:
- containerPort: 80
-
Appliquez le nouveau fichier YAML :
kubectl apply -f https://k8s.io/examples/application/deployment-scale.yaml
-
Vérifiez que le déploiement a quatre pods:
kubectl get pods -l app=nginx
Le résultat sera similaire à ceci :
NAME READY STATUS RESTARTS AGE
nginx-deployment-148880595-4zdqq 1/1 Running 0 25s
nginx-deployment-148880595-6zgi1 1/1 Running 0 25s
nginx-deployment-148880595-fxcez 1/1 Running 0 2m
nginx-deployment-148880595-rwovn 1/1 Running 0 2m
Suppression d'un déploiement
Supprimez le déploiement avec son nom :
kubectl delete deployment nginx-deployment
ReplicationControllers -- méthode obsolète
La méthode préférée pour créer une application répliquée consiste à utiliser un déploiement,
qui utilise à son tour un ReplicaSet.
Avant que le déploiement et le ReplicaSet ne soient
ajoutés à Kubernetes, les applications répliquées étaient configurées
à l'aide d'un ReplicationController.
A suivre
6.2 - Exécutez une application stateful mono-instance
Cette page montre comment exécuter une application mono-instance, avec gestion d'état (stateful) dans Kubernetes en utilisant un PersistentVolume et un Deployment. L'application utilisée est MySQL.
Objectifs
- Créer un PersistentVolume en référençant un disque dans votre environnement.
- Créer un déploiement MySQL.
- Exposer MySQL à d'autres pods dans le cluster sous un nom DNS connu.
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, entrez kubectl version
.
-
Vous devez disposer soit d'un fournisseur PersistentVolume dynamique avec une valeur par défaut StorageClass, soit préparer un PersistentVolumes statique pour satisfaire les PersistentVolumeClaims utilisés ici.
Déployer MySQL
Vous pouvez exécuter une application stateful en créant un Deployment Kubernetes
et en le connectant à un PersistentVolume existant à l'aide d'un
PersistentVolumeClaim. Par exemple, ce fichier YAML décrit un
Deployment qui exécute MySQL et référence le PersistentVolumeClaim. Le fichier
définit un point de montage pour /var/lib/mysql, puis crée un
PersistentVolumeClaim qui réclame un volume de 20G.
Cette demande est satisfaite par n'importe quel volume existant qui répond aux exigences,
ou par un provisionneur dynamique.
Remarque: le mot de passe MySQL est défini dans le fichier de configuration YAML, ce qui n'est pas sécurisé.
Voir les secrets Kubernetes
pour une approche sécurisée.
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 3306
selector:
app: mysql
clusterIP: None
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
# Use secret in real usage
- name: MYSQL_ROOT_PASSWORD
value: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
-
Déployez le PV et le PVC du fichier YAML:
kubectl apply -f https://k8s.io/examples/application/mysql/mysql-pv.yaml
-
Déployez les resources du fichier YAML:
kubectl apply -f https://k8s.io/examples/application/mysql/mysql-deployment.yaml
-
Affichez les informations liées au Deployment:
kubectl describe deployment mysql
Le résultat sera similaire à ceci:
Name: mysql
Namespace: default
CreationTimestamp: Tue, 01 Nov 2016 11:18:45 -0700
Labels: app=mysql
Annotations: deployment.kubernetes.io/revision=1
Selector: app=mysql
Replicas: 1 desired | 1 updated | 1 total | 0 available | 1 unavailable
StrategyType: Recreate
MinReadySeconds: 0
Pod Template:
Labels: app=mysql
Containers:
mysql:
Image: mysql:5.6
Port: 3306/TCP
Environment:
MYSQL_ROOT_PASSWORD: password
Mounts:
/var/lib/mysql from mysql-persistent-storage (rw)
Volumes:
mysql-persistent-storage:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: mysql-pv-claim
ReadOnly: false
Conditions:
Type Status Reason
---- ------ ------
Available False MinimumReplicasUnavailable
Progressing True ReplicaSetUpdated
OldReplicaSets: <none>
NewReplicaSet: mysql-63082529 (1/1 replicas created)
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
33s 33s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set mysql-63082529 to 1
-
Listez les Pods créés par le Deployment:
kubectl get pods -l app=mysql
Le résultat sera similaire à ceci:
NAME READY STATUS RESTARTS AGE
mysql-63082529-2z3ki 1/1 Running 0 3m
-
Inspectez le PersistentVolumeClaim:
kubectl describe pvc mysql-pv-claim
Le résultat sera similaire à ceci:
Name: mysql-pv-claim
Namespace: default
StorageClass:
Status: Bound
Volume: mysql-pv-volume
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed=yes
pv.kubernetes.io/bound-by-controller=yes
Capacity: 20Gi
Access Modes: RWO
Events: <none>
Accès à l'instance MySQL
Le fichier YAML précédent crée un service qui permet à d'autres
pods dans le cluster d'accéder à la base de données.
L'option clusterIP: None
du service permet à son nom DNS
de résoudre directement l'adresse IP du pod.
C'est optimal lorsque vous n'avez qu'un seul pod derrière
un service et que vous n'avez pas l'intention
d'augmenter le nombre de pods.
Exécutez un client MySQL pour vous connecter au serveur :
kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h mysql -ppassword
Cette commande crée un nouveau pod dans le cluster exécutant
un client MySQL et le connecte au serveur via le Service.
Si la connexion réussit, cela signifie que votre base de données MySQL est opérationnelle.
Waiting for pod default/mysql-client-274442439-zyp6i to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.
mysql>
Mises à jour
L'image ou toute autre partie du Deployment peut être mise à jour
comme d'habitude avec la commande kubectl apply
.
Voici quelques précautions spécifiques aux applications stateful :
- Ne pas mettre à l'échelle l'application. Cette configuration
est conçue pour des applications à une seule instance seulement.
Le PersistentVolume sous-jacent ne peut être monté que sur un
Pod. Pour les applications stateful clusterisées, consultez la
documentation sur les StatefulSets.
- Utilisez
strategy
: type: Recreate
dans le fichier de
configuration YAML du Deployment.
Cela indique à Kubernetes de ne pas utiliser des mises à jour
continues. Les mises à jour en roulement ne fonctionneront pas,
car vous ne pouvez pas avoir plus d'un Pod en cours
d'exécution à la fois. La stratégie Recreate
arrêtera le
premier pod avant d'en créer un nouveau avec la configuration mise à jour.
Suppression d'un déploiement
Supprimez les ressources déployées avec leur noms:
kubectl delete deployment,svc mysql
kubectl delete pvc mysql-pv-claim
kubectl delete pv mysql-pv-volume
Si vous avez provisionné manuellement un PersistentVolume, vous
devrez également le supprimer manuellement,
ainsi que libérer la ressource sous-jacente.
Si vous avez utilisé un provisionneur dynamique,
il supprimera automatiquement le PersistentVolume
lorsqu'il verra que vous avez supprimé le PersistentVolumeClaim.
Certains provisionneurs dynamiques (comme ceux pour EBS et PD)
libèrent également la ressource sous-jacente lors de la
suppression du PersistentVolume.
A suivre
6.3 - Découverte de l'HorizontalPodAutoscaler
Un HorizontalPodAutoscaler (raccourci en HPA)
met à jour automatiquement une ressource de charge de travail
(comme un Deployment
ou un StatefulSet),
dans le but de faire évoluer automatiquement la charge de travail en fonction
de la demande.
L'évolutivité horizontale signifie que la réponse à une
augmentation de la charge est de déployer plus de Pods.
Cela diffère de l'évolutivité verticale, qui pour Kubernetes
signifierait attribuer plus de ressources (par exemple : mémoire ou CPU)
aux Pods qui sont déjà en cours d'exécution pour la charge de travail.
Si la charge diminue et que le nombre de Pods est supérieur au minimum configuré,
le HorizontalPodAutoscaler indique à la ressource de charge de travail
(le Deployment, le StatefulSet ou une autre ressource similaire)
de réduire son échelle (nombre de réplicas).
Ce document vous guide à travers un exemple d'activation de HorizontalPodAutoscaler pour gérer
automatiquement l'échelle d'une application web.
Cette charge de travail d'exemple est Apache httpd exécutant du code PHP.
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 1.23.
Pour consulter la version, entrez
kubectl version
.
Si vous utilisez
une version plus ancienne de Kubernetes, consultez la version de la documentation correspondante
(voir
versions de documentation disponibles).
Pour suivre ce guide, vous devez également utiliser un cluster qui dispose d'un
Metrics Server déployé et configuré.
Le Metrics Server Kubernetes collecte les métriques des ressources des
kubelets de votre cluster et expose
ces métriques via l'API Kubernetes,
en utilisant un APIService
pour ajouter de nouveaux types de ressources représentant les lectures de métriques.
Pour apprendre comment déployer le Metrics Server, consultez la documentation de metrics-server.
Exécutez et exposez le serveur php-apache
Pour démontrer un HorizontalPodAutoscaler, vous commencerez par démarrer un
Deployment qui exécute un conteneur utilisant l'image hpa-example
et l'expose en tant que Service en utilisant le
manifeste suivant:
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-apache
spec:
selector:
matchLabels:
run: php-apache
template:
metadata:
labels:
run: php-apache
spec:
containers:
- name: php-apache
image: registry.k8s.io/hpa-example
ports:
- containerPort: 80
resources:
limits:
cpu: 500m
requests:
cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
name: php-apache
labels:
run: php-apache
spec:
ports:
- port: 80
selector:
run: php-apache
Pour créer les ressources, exécutez la commande suivante:
kubectl apply -f https://k8s.io/examples/application/php-apache.yaml
deployment.apps/php-apache created
service/php-apache created
Créer le HorizontalPodAutoscaler
Maintenant que le serveur est en cours d'exécution, créez l'autoscaler à l'aide de kubectl
.
Il existe une sous-commande kubectl autoscale
,
faisant partie de kubectl
, qui vous aide à le faire.
Vous allez bientôt exécuter une commande qui crée un HorizontalPodAutoscaler
qui maintient entre 1 et 10 réplicas des Pods contrôlés par le déploiement
php-apache que vous avez créé lors de la première étape.
En parlant simplement, le HPA (contrôleur)
augmentera ou diminuera le nombre de réplicas (en mettant à jour le déploiement)
pour maintenir une utilisation CPU moyenne de 50% sur l'ensemble des Pods.
Ensuite, le déploiement met à jour le ReplicaSet - cela fait partie du
fonctionnement de tous les déploiements dans Kubernetes - puis le ReplicaSet
ajoute ou supprime des Pods en fonction des modifications apportées à son champ .spec
.
Étant donné que chaque pod demande 200 milli-cores via kubectl run
,
cela signifie une utilisation CPU moyenne de 100 milli-cores.
Consultez les détails de l'algorithme pour plus d'informations sur celui-ci.
Créez le HorizontalPodAutoscaler :
kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
horizontalpodautoscaler.autoscaling/php-apache autoscaled
Vous pouvez visualiser le statut actuel du nouvel HorizontalPodAutoscaler avec la commande:
# Vous pouvez utiliser "hpa" ou "horizontalpodautoscaler"; les deux appelations fonctionnent.
kubectl get hpa
Le résultat sera similaire à celui-ci:
NAME REFERENCE TARGET MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache/scale 0% / 50% 1 10 1 18s
(Si vous voyez d'autres HorizontalPodAutoscalers avec des noms différents,
cela signifie qu'ils existaient déjà et ce n'est généralement pas un problème).
Veuillez noter que la consommation actuelle de CPU est de 0 %
car il n'y a pas de clients envoyant des requêtes au serveur
(la colonne TARGET
montre la moyenne de tous les Pods
contrôlés par le déploiement correspondant).
Augmenter la charge
Ensuite, voyons comment l'autoscaler réagit à une augmentation de la charge.
Pour cela, vous allez démarrer un autre Pod pour agir en tant que client.
Le conteneur à l'intérieur du Pod client
s'exécute dans une boucle infinie, envoyant des requêtes au service php-apache.
# Exécutez ceci dans un terminal séparé
# pour que la montée en charge s'applique pendant que vous continuez les étapes suivantes
kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done"
Maintenant exécutez:
# Entrez Ctrl+C pour terminer lorsque c'est ok
kubectl get hpa php-apache --watch
Après environ une minute, vous devriez constater une augmentation de la charge
CPU, comme ceci:
NAME REFERENCE TARGET MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache/scale 305% / 50% 1 10 1 3m
en réponse, une augmentation du nombre de réplicas, comme ceci:
NAME REFERENCE TARGET MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache/scale 305% / 50% 1 10 7 3m
Dans ce cas, la consommation CPU a atteint 305% de ce qui était demandé.
Ainsi, le nombre de réplicas du Deployment a été augmenté à 7:
kubectl get deployment php-apache
Vous devriez voir le nombre de réplicas être égal à la valeur du HorizontalPodAutoscaler:
NAME READY UP-TO-DATE AVAILABLE AGE
php-apache 7/7 7 7 19m
Note: La stabilisation du nombre de réplicas peut prendre quelques minutes.
Comme la charge est incontrollée, le nombre final de réplicas
peut varier par rapport à l'exemple présenté.
Arrêt de la charge
Pour finir cet exemple, nous allons arrêter d'envoyer des requètes.
Dans le terminal utilisé pour créer le Pod qui exécute une image busybox
, arrêtez la charge en entrant <Ctrl> +C
.
Puis vérifiez le résultat après un temps d'attente:
# entrez Ctrl+C pour arrêter une fois la charge arretée
kubectl get hpa php-apache --watch
Le résultat sera similaire à:
NAME REFERENCE TARGET MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache/scale 0% / 50% 1 10 1 11m
et le nombre de réplicas du Deployment sera redescendu:
kubectl get deployment php-apache
NAME READY UP-TO-DATE AVAILABLE AGE
php-apache 1/1 1 1 27m
Une fois que la consommation CPU atteindra 0, le HPA ajustera automatiquement le nombre de réplicas à 1.
Cette étape peut prendre quelques minutes.
L'auto-ajustement basé sur des métriques multiples ou personnalisées
Vous pouvez ajouter de nouvelles métriques à utiliser pour l'auto-ajustement du Deployment php-apache
en utilisant l'api autoscaling/v2
.
Pour commencer, récupérez le YAML de votre HorizontalPodAutoscaler en format autoscaling/v2
:
kubectl get hpa php-apache -o yaml > /tmp/hpa-v2.yaml
Ouvrez le fichier /tmp/hpa-v2.yaml
avec votre éditeur, le YAML devrait ressembler à ceci:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
status:
observedGeneration: 1
lastScaleTime: <some-time>
currentReplicas: 1
desiredReplicas: 1
currentMetrics:
- type: Resource
resource:
name: cpu
current:
averageUtilization: 0
averageValue: 0
Veuillez noter que le champ targetCPUUtilizationPercentage
a été remplacé par un tableau appelé metrics
.
La métrique d'utilisation du CPU est une métrique de ressource, car elle est représentée en pourcentage d'une ressource spécifiée sur les conteneurs de pod.
Notez que vous pouvez spécifier d'autres métriques de ressource en plus du CPU.
Par défaut, la seule autre métrique de ressource prise en charge est la mémoire.
Ces ressources ne changent pas de nom d'un cluster à l'autre et devraient
toujours être disponibles tant que l'API metrics.k8s.io
est disponible.
Vous pouvez également spécifier des métriques de ressource en termes de valeurs directes, au lieu de pourcentages de la valeur demandée,
en utilisant un target.type
de AverageValue
au lieu de Utilization
,
et en définissant le champ correspondant target.averageValue
au lieu de target.averageUtilization
.
Il existe deux autres types de métriques, tous deux considérés comme des métriques personnalisées: les métriques de pod et les métriques d'objet.
Ces métriques peuvent avoir des noms spécifiques au cluster et
nécessitent une configuration de la surveillance du cluster plus avancée.
Le premier de ces types de métriques alternatives est les métriques de pod.
Ces métriques décrivent les pods et sont regroupées en moyenne sur l'ensemble des pods,
puis comparées à une valeur cible pour déterminer le nombre de réplicas.
Elles fonctionnent de manière similaire aux métriques de ressource,
à la différence qu'elles prennent en charge seulement le type de target
AverageValue
.
Les métriques de pod sont spécifiées à l'aide d'une définition metric
comme ceci:
type: Pods
pods:
metric:
name: packets-per-second
target:
type: AverageValue
averageValue: 1k
Le deuxième type de métrique alternative est les métriques d'objet.
Ces métriques décrivent un objet différent dans le même namespace,
au lieu de décrire des Pods.
Les métriques ne sont pas nécessairement récupérées à partir de l'objet mais le décrivent.
Les métriques d'objet prennent en charge les types de target
suivants: Value
et AverageValue
.
Avec Value
, la cible est comparée directement à la métrique renvoyée par l'API.
Avec AverageValue
, la valeur renvoyée par l'API de métriques
personnalisées est divisée par le nombre de Pods avant d'être comparée à la cible.
L'exemple suivant est la représentation YAML de la métrique requests-per-second
.
type: Object
object:
metric:
name: requests-per-second
describedObject:
apiVersion: networking.k8s.io/v1
kind: Ingress
name: main-route
target:
type: Value
value: 2k
Si vous fournissez plusieurs définitions de métriques similaires,
le HorizontalPodAutoscaler examinera chaque métrique à tour de rôle.
Il calculera les nombres de réplicas proposés pour chaque métrique,
puis choisira celle avec le nombre de réplicas le plus élevé.
Par exemple, si votre système de surveillance collecte des métriques sur le trafic réseau,
vous pouvez mettre à jour la définition ci-dessus en utilisant kubectl edit
pour qu'elle ressemble à ceci :
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
- type: Pods
pods:
metric:
name: packets-per-second
target:
type: AverageValue
averageValue: 1k
- type: Object
object:
metric:
name: requests-per-second
describedObject:
apiVersion: networking.k8s.io/v1
kind: Ingress
name: main-route
target:
type: Value
value: 10k
status:
observedGeneration: 1
lastScaleTime: <some-time>
currentReplicas: 1
desiredReplicas: 1
currentMetrics:
- type: Resource
resource:
name: cpu
current:
averageUtilization: 0
averageValue: 0
- type: Object
object:
metric:
name: requests-per-second
describedObject:
apiVersion: networking.k8s.io/v1
kind: Ingress
name: main-route
current:
value: 10k
Ensuite, votre HorizontalPodAutoscaler tentera de s'assurer
que chaque pod consomme environ 50% de sa CPU demandée,
en traitant 1000 paquets par seconde,
et que tous les pods derrière l'Ingress main-route
servent un total de 10000 requêtes par seconde.
Auto-ajustement sur des métriques plus spécifiques
De nombreuses chaines de métriques vous permettent de décrire les métriques soit par leur nom,
soit par un ensemble de descripteurs supplémentaires appelés labels.
Pour tous les types de métriques autres que les ressources (pod, objet et externe, décrits ci-dessous),
vous pouvez spécifier un sélecteur de label supplémentaire qui est transmis à votre chaine de métriques.
Par exemple, si vous collectez une métrique http_requests
avec le label verb
,
vous pouvez spécifier la définition de métrique suivante pour ne faire varier l'échelle que sur les requêtes de type GET:
type: Object
object:
metric:
name: http_requests
selector: {matchLabels: {verb: GET}}
Ce sélecteur utilise la même syntaxe que les sélecteurs d'étiquettes complets de Kubernetes.
La chaine de surveillance détermine comment regrouper plusieurs séries en une seule valeur, si le nom et le sélecteur correspondent à plusieurs séries.
Le sélecteur est additif et ne peut pas sélectionner des métriques qui décrivent des objets qui ne sont pas l'objet cible
(les pods cibles dans le cas du type Pods
, et l'objet décrit dans le cas du type Object
).
Auto-ajustement sur des métriques non liées aux objets Kubernetes
Les applications s'exécutant sur Kubernetes peuvent avoir besoin de
s'auto-adapter en fonction de métriques qui n'ont pas de relation évidente
avec un objet dans le cluster Kubernetes,
telles que des métriques décrivant un service hébergé sans corrélation directe avec les namespace Kubernetes.
À partir de Kubernetes 1.10, vous pouvez répondre à ce cas d'utilisation avec des métriques externes.
L'utilisation de métriques externes nécessite une connaissance de votre système de surveillance ;
la configuration est similaire à celle requise lors de l'utilisation de métriques personnalisées.
Les métriques externes vous permettent de mettre à l'échelle automatiquement
votre cluster en fonction de n'importe quelle métrique disponible dans votre
système de surveillance.
Créez un bloc metric
avec un name
et un selector
, comme ci-dessus,
et utilisez le type de métrique External
au lieu de Object
.
Si plusieurs séries temporelles correspondent au metricSelector
,
la somme de leurs valeurs sera utilisée par le HorizontalPodAutoscaler.
Les métriques externes prennent en charge les types de cible Value
et AverageValue
, qui fonctionnent exactement de la même manière que lorsque vous utilisez le type Object
.
Par exemple, si votre application traite des tâches à partir d'un service de file de messages hébergé,
vous pouvez ajouter la section suivante à votre déclaration de
HorizontalPodAutoscaler pour spécifier que vous avez besoin
d'un travailleur par tranche de 30 tâches en attente.
- type: External
external:
metric:
name: queue_messages_ready
selector:
matchLabels:
queue: "worker_tasks"
target:
type: AverageValue
averageValue: 30
Lorsque possible, il est préférable d'utiliser les types de cible métrique personnalisés plutôt que des métriques externes,
car cela facilite la sécurisation de l'API des métriques personnalisées pour les administrateurs de cluster.
L'API des métriques externes permet potentiellement l'accès à n'importe quelle métrique,
il est donc nécessaire que les administrateurs de cluster fassent attention lors de son exposition.
Annexe : Conditions d'état du Horizontal Pod Autoscaler
Lorsque vous utilisez la forme autoscaling/v2
du HorizontalPodAutoscaler,
vous pourrez voir les conditions d'état définies par Kubernetes sur celui-ci.
Ces conditions d'état indiquent s'il est capable de se mettre à l'échelle et s'il est actuellement
restreint de quelque manière que ce soit. Les conditions apparaissent dans le
champ status.conditions
.
Pour voir les conditions affectant un HorizontalPodAutoscaler, nous pouvons utiliser la commande kubectl describe hpa
.
kubectl describe hpa cm-test
Name: cm-test
Namespace: prom
Labels: <none>
Annotations: <none>
CreationTimestamp: Fri, 16 Jun 2017 18:09:22 +0000
Reference: ReplicationController/cm-test
Metrics: ( current / target )
"http_requests" on pods: 66m / 500m
Min replicas: 1
Max replicas: 4
ReplicationController pods: 1 current / 1 desired
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale True ReadyForNewScale the last scale time was sufficiently old as to warrant a new scale
ScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from pods metric http_requests
ScalingLimited False DesiredWithinRange the desired replica count is within the acceptable range
Events:
Pour ce HorizontalPodAutoscaler, vous pouvez voir plusieurs conditions dans un état sain.
La première, AbleToScale
, indique si le HPA est capable de récupérer et de mettre à jour les échelles,
ainsi que si des conditions liées aux limitations sont susceptibles d'empêcher le redimensionnement.
La deuxième, ScalingActive
, indique si le HPA est activé (c'est-à-dire que le nombre de réplicas de la cible n'est pas nul) et est capable de calculer les échelles souhaitées.
Lorsqu'il est False
, cela indique généralement des problèmes de récupération des métriques.
Enfin, la dernière condition, ScalingLimited
, indique que l'échelle souhaitée a été limitée par le maximum ou le minimum du HorizontalPodAutoscaler.
Cela indique que vous souhaiteriez peut-être augmenter ou diminuer les contraintes de nombre de réplicas minimum ou maximum de votre HorizontalPodAutoscaler.
Quantités
Toutes les métriques dans le HorizontalPodAutoscaler et les API de métriques
sont spécifiées à l'aide d'une notation spéciale en nombres entiers connue dans Kubernetes sous le nom de quantité.
Par exemple, la quantité 10500m
serait écrite comme 10.5
en notation décimale.
Les API de métriques renvoient des nombres entiers sans suffixe lorsque cela est possible, et renvoient généralement des quantités en milli-unités sinon.
Cela signifie que vous pouvez voir la valeur de votre métrique fluctuer entre 1
et 1500m
, ou 1
et 1.5
lorsqu'elle est écrite en notation décimale.
Autres scénarios possibles
Création de l'autoscaler de manière déclarative
Au lieu d'utiliser la commande kubectl autoscale
pour créer un HorizontalPodAutoscaler de manière impérative,
nous pouvons utiliser le manifeste suivant pour le créer de manière déclarative :
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 50
Ensuite, créez l'autoscaler en exécutant la commande suivante :
kubectl create -f https://k8s.io/examples/application/hpa/php-apache.yaml
horizontalpodautoscaler.autoscaling/php-apache created
6.4 - Accéder à l'API de Kubernetes depuis un Pod
Ce guide explique comment accéder à l'API de Kubernetes depuis un Pod.
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:
Accéder à l'API depuis un Pod
Lorsque l'on veut accéder à l'API depuis un Pod, localiser et s'authentifier
auprès du serveur API se passe différement que dans le cas d'un client externe.
Le moyen le plus simple pour interagir avec l'API Kubernetes depuis un Pod est d'utiliser l'une des
librairies clientes officielles.
Ces bibliothèques peuvent automatiquement découvrir le serveur API et s'authentifier.
Utilisation des clients officiels
Depuis un Pod, les moyens recommandés pour se connecter à l'API Kubernetes sont:
-
Pour un client Go, utilisez la bibliothèque client officielle
Go.
La fonction rest.InClusterConfig()
gère automatiquement
la découverte de l'hôte API et l'authentification.
Voir un exemple ici.
-
Pour un client Python, utilisez la bibliothèque client officielle
Python.
La fonction config.load_incluster_config()
gère automatiquement
la découverte de l'hôte API et l'authentification.
Voir un exemple ici.
-
Il existe d'autres bibliothèques disponibles, vous pouvez vous référer à la page
Bibliothèques clientes.
Dans tous les cas, les informations d'identification du compte de service du Pod seront utilisées pour communiquer avec le serveur API.
Accès direct à l'API REST
En s'exécutant dans un Pod, votre conteneur peut créer une URL HTTPS
pour le serveur API Kubernetes en récupérant les variables d'environnement
KUBERNETES_SERVICE_HOST
et KUBERNETES_SERVICE_PORT_HTTPS
.
L'adresse du serveur API dans le cluster est également publiée
dans un Service nommé kubernetes
dans le namespace default
afin que les pods puissent référencer
kubernetes.default.svc
comme nom DNS pour le serveur API.
Note: Kubernetes ne garantit pas que le serveur API dispose d'un certificat valide
pour le nom d'hôte kubernetes.default.svc
;
cependant, le plan de contrôle doit présenter un certificat valide
pour le nom d'hôte ou l'adresse IP que $KUBERNETES_SERVICE_HOST
représente.
La manière recommandée pour s'authentifier auprès du serveur API
est d'utiliser les identifiants d'un
compte de service.
Par défaut, un Pod est associé à un compte de service,
et un identifiant pour ce compte de service est placé
dans le système de fichiers de chaque conteneur dans ce Pod,
dans /var/run/secrets/kubernetes.io/serviceaccount/token
.
Si disponible, un lot de certificats est placé dans le système de fichiers de chaque conteneur dans /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
et doit être utilisé pour vérifier le certificat du serveur API.
Enfin, le namespace courant dans lequel est déployé le Pod est
placé dans un fichier /var/run/secrets/kubernetes.io/serviceaccount/namespace
dans chaque container.
Avec utilisation du proxy kubectl
Si vous souhaitez interroger l'API sans utiliser de bibliothèque client officielle,
vous pouvez exécuter kubectl proxy
en tant que
commande
d'un nouveau conteneur sidecar dans le Pod.
De cette manière, kubectl proxy
s'authentifiera auprès de l'API
et l'exposera sur l'interface localhost
du Pod,
de sorte que les autres conteneurs dans le Pod puissent l'utiliser directement.
Sans utiliser de proxy
Il est possible d'éviter l'utilisation du proxy kubectl en passant
directement les informations d'authentification au serveur API.
Le certificat interne sécurise la connexion.
# Pointe vers le nom d'hôte interne du serveur API.
APISERVER=https://kubernetes.default.svc
# Chemin du token pour le compte de service
SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
# Lire le namespace du Pod
NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
# Lire le token du compte de service
TOKEN=$(cat ${SERVICEACCOUNT}/token)
# Référence l'authorité de certificat interne
CACERT=${SERVICEACCOUNT}/ca.crt
# Accéder à l'API avec le token
curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api
Le résultat sera similaire à:
{
"kind": "APIVersions",
"versions": ["v1"],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "10.0.1.149:443"
}
]
}
7 - Exécution des jobs
8 - Accès aux applications dans un cluster
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/charts/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.
Attention: L’exemple d’utilisateur créé dans le didacticiel disposera de privilèges d’administrateur et servira uniquement à des fins pédagogiques.
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 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.
Note: La méthode d'authentification Kubeconfig ne prend pas en charge les fournisseurs d'identité externes ni l'authentification basée sur un certificat x509.
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.
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
.
Note: Un fichier utilisé pour configurer l'accès à un cluster est parfois appelé fichier kubeconfig.
C'est une manière générique de se référer aux fichiers de configuration.
Cela ne signifie pas qu'il existe un fichier nommé 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
Note:
- 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:
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:
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
8.3 - Utiliser le Port Forwarding pour accéder à des applications dans un cluster
Cette page montre comment utiliser kubectl port-forward
pour se connecter à un serveur MongoDB s'exécutant dans un cluster Kubernetes.
Ce type de connexion peut être utile pour le debug d'une base 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:
Votre serveur Kubernetes doit être au moins à la version v1.10.
Pour consulter la version, entrez kubectl version
.
- Installez MongoDB Shell.
Création du déploiement et du service MongoDB
-
Créez un déploiement qui exécute MongoDB :
kubectl apply -f https://k8s.io/examples/application/mongodb/mongo-deployment.yaml
Le résultat d'une commande réussie doit valider que le déploiement a bien été créé :
deployment.apps/mongo créé
Affichez l'état du pod pour vérifier qu'il est prêt :
Le résultat doit lister le pod créé :
NOM PRÊT STATUT REDÉMARRAGES ÂGE
mongo-75f59d57f4-4nd6q 1/1 Running 0 2m4s
Affichez l'état du déploiement :
Le résultat affiche que le déploiement a bien été créé :
NOM PRÊT ACTUALISÉ DISPONIBLE ÂGE
mongo 1/1 1 1 2m21s
Le déploiement gère automatiquement un ReplicaSet. Affichez l'état du ReplicaSet à l'aide de la commande :
Le résultat affiche que le ReplicaSet a bien été créé :
NOM DÉSIRÉ ACTUEL PRÊT ÂGE
mongo-75f59d57f4 1 1 1 3m12s
-
Créez un service pour exposer MongoDB sur le réseau :
kubectl apply -f https://k8s.io/examples/application/mongodb/mongo-service.yaml
Le résultat d'une commande réussie vérifie que le service a été créé :
service/mongo créé
Vérifiez que le service a été créé :
kubectl get service mongo
Le résultat affiche le service qui vient d'être créé :
NOM TYPE CLUSTER-IP EXTERNAL-IP PORT(S) ÂGE
mongo ClusterIP 10.96.41.183 <none> 27017/TCP 11s
-
Vérifiez que le serveur MongoDB s'exécute dans le pod et écoute sur le port 27017 :
# Changez mongo-75f59d57f4-4nd6q par le nom du pod
kubectl get pod mongo-75f59d57f4-4nd6q --template='{{(index (index .spec.containers 0).ports 0).containerPort}}{{"\n"}}'
Le résultat affiche le port pour MongoDB dans ce pod :
27017
27017 est le port TCP attribué à MongoDB sur Internet.
Rediriger un port local vers un port du pod
-
kubectl port-forward
permet d'utiliser un nom de ressource, tel qu'un nom de pod, pour sélectionner un pod correspondant vers lequel rediriger le port.
# Changez mongo-75f59d57f4-4nd6q par le nom du pod
kubectl port-forward mongo-75f59d57f4-4nd6q 28015:27017
qui est identique à
kubectl port-forward pods/mongo-75f59d57f4-4nd6q 28015:27017
ou
kubectl port-forward deployment/mongo 28015:27017
ou
kubectl port-forward replicaset/mongo-75f59d57f4 28015:27017
ou
kubectl port-forward service/mongo 28015:27017
N'importe laquelle des commandes ci-dessus fonctionne. Le résultat sera similaire à ceci :
Forwarding from 127.0.0.1:28015 -> 27017
Forwarding from [::1]:28015 -> 27017
Note: kubectl port-forward
ne se termine pas une fois le port-forward lancé. Pour continuer avec les exercices, vous devrez ouvrir un autre terminal.
-
Démarrez l'interface de ligne de commande MongoDB :
-
Depuis la ligne de commande de MongoDB, entrez la commande ping
:
db.runCommand( { ping: 1 } )
Une demande de ping réussie renvoie :
{ ok: 1 }
Laisser kubectl choisir le port local
Si vous n'avez pas besoin d'un port local précis,
vous pouvez laisser kubectl
choisir et attribuer le port local,
vous évitant ainsi de gérer les conflits de ports locaux, avec cette syntaxe légèrement plus simple :
kubectl port-forward deployment/mongo :27017
kubectl
trouvera un numéro de port local qui n'est pas utilisé
(en évitant les numéros de ports bas, car ils pourraient être utilisés par d'autres applications).
Le résultat sera similaire à :
Forwarding from 127.0.0.1:63753 -> 27017
Forwarding from [::1]:63753 -> 27017
Discussion
Les connexions établies sur le port local 28015 sont redirigées vers le port 27017 du pod qui exécute le serveur MongoDB.
Avec cette connexion en place, vous pouvez utiliser votre poste de travail local
pour debug la base de données MongoDB qui s'exécute dans le pod.
Note: kubectl port-forward
est implémenté pour les ports TCP uniquement. La prise en charge du protocole UDP est suivie dans
l'issue 47862.
A suivre
En savoir plus sur kubectl port-forward.
8.4 - Utiliser un Service pour accéder à une application dans un cluster
Cette page montre comment créer un Service Kubernetes que des clients externes peuvent utiliser
pour accéder à une application s'exécutant dans un cluster.
Le Service fournit une répartition de charge pour une application
ayant deux instances 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:
Objectifs
- Exécuter deux instances d'une application Hello World.
- Créer un Service qui expose un port du nœud.
- Utiliser le Service pour accéder à l'application en cours d'exécution.
Création d'un service pour une application s'exécutant dans deux pods
Voici le fichier de configuration pour le déploiement de l'application :
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world
spec:
selector:
matchLabels:
run: load-balancer-example
replicas: 2
template:
metadata:
labels:
run: load-balancer-example
spec:
containers:
- name: hello-world
image: gcr.io/google-samples/node-hello:1.0
ports:
- containerPort: 8080
protocol: TCP
-
Exécutez une application Hello World dans votre cluster :
Créez le déploiement de l'application en utilisant le fichier ci-dessus :
kubectl apply -f https://k8s.io/examples/service/access/hello-application.yaml
La commande précédente crée un
Deployment
et un
ReplicaSet associé.
Le ReplicaSet possède deux
Pods,
chacun exécutant l'application Hello World.
-
Affichez les informations du déploiement :
kubectl get deployments hello-world
kubectl describe deployments hello-world
-
Affichez les informations des ReplicaSet :
kubectl get replicasets
kubectl describe replicasets
-
Créez un Service qui expose le déploiement :
kubectl expose deployment hello-world --type=NodePort --name=example-service
-
Affichez les informations sur le Service :
kubectl describe services example-service
Le résultat sera similaire à ceci :
Name: example-service
Namespace: default
Labels: run=load-balancer-example
Annotations: <none>
Selector: run=load-balancer-example
Type: NodePort
IP: 10.32.0.16
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 31496/TCP
Endpoints: 10.200.1.4:8080,10.200.2.5:8080
Session Affinity: None
Events: <none>
Notez la valeur de NodePort pour le service. Par exemple,
dans le résultat précédent, la valeur de NodePort est 31496.
-
Répertoriez les pods qui exécutent l'application Hello World :
kubectl get pods --selector="run=load-balancer-example" --output=wide
Le résultat est similaire à ceci :
NAME READY STATUS ... IP NODE
hello-world-2895499144-bsbk5 1/1 Running ... 10.200.1.4 worker1
hello-world-2895499144-m1pwt 1/1 Running ... 10.200.2.5 worker2
-
Obtenez l'adresse IP publique de l'un de vos nœuds qui exécute
un pod Hello World. L'obtention de cette adresse dépend de la manière dont vous avez configuré votre cluster.
Par exemple, si vous utilisez Minikube, vous pouvez
voir l'adresse du nœud en exécutant kubectl cluster-info
. Si vous utilisez
des instances Google Compute Engine, vous pouvez utiliser la commande
gcloud compute instances list
pour voir les adresses publiques de vos
nœuds.
-
Sur le nœud choisi, créez une règle de pare-feu autorisant le trafic TCP
sur votre port. Par exemple, si votre Service a une valeur NodePort de
31568, créez une règle de pare-feu autorisant le trafic TCP vers le port 31568. Différents
fournisseurs cloud offrent différentes façons de configurer des règles de pare-feu.
-
Utilisez l'adresse du nœud et le port de nœud pour accéder à l'application Hello World :
curl http://<adresse-ip-publique>:<port>
où <adresse-ip-publique>
est l'adresse IP publique de votre nœud,
et <port>
est la valeur de NodePort pour votre service. La
réponse à une requête réussie est un message de bienvenue :
Hello Kubernetes!
Utilisation d'un fichier de configuration de service
Au lieu d'utiliser kubectl expose
, vous pouvez utiliser un
fichier de configuration de service
pour créer un Service.
Cleanup
Pour supprimer le Service, saisissez cette commande :
kubectl delete services example-service
Pour supprimer le Déploiement, le ReplicaSet et les Pods qui exécutent
l'application Hello World, saisissez cette commande :
kubectl delete deployment hello-world
A suivre
Suivez le tutoriel
Connecter des applications avec les Services.
8.5 - Connecter un Frontend à un Backend en utilisant les Services
Cette tâche montre comment créer un microservice frontend et un microservice backend.
Le backend renvoie un message de salutations à chaque requête.
Le frontend expose le backend en utilisant Nginx et un Service Kubernetes.
Objectifs
- Créer et exécuter un microservice backend
hello
en utilisant un Déploiement.
- Utiliser un Service pour envoyer du trafic vers les multiples réplicas du microservice backend.
- Créer et exécuter un microservice frontend
nginx
, en utilisant également un Deployment.
- Configurer le microservice frontend pour envoyer du trafic vers le microservice backend.
- Utiliser un Service de type
LoadBalancer
pour exposer le microservice frontend en dehors du 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, entrez
kubectl version
.
Cette tâche utilise les Services avec des équilibreurs de charge externes,
qui nécessitent un environnement spécifique.
Si votre environnement ne prend pas en charge cette fonction, vous pouvez utiliser un Service de type
NodePort à la place.
Création du backend à l'aide d'un Deployment
Le backend est un simple microservice de salutations.
Voici le fichier de configuration pour le Deployment backend :
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
selector:
matchLabels:
app: hello
tier: backend
track: stable
replicas: 3
template:
metadata:
labels:
app: hello
tier: backend
track: stable
spec:
containers:
- name: hello
image: "gcr.io/google-samples/hello-go-gke:1.0"
ports:
- name: http
containerPort: 80
...
Créez le Deployment backend :
kubectl apply -f https://k8s.io/examples/service/access/backend-deployment.yaml
Affichez les informations du Deployment:
kubectl describe deployment backend
Le retour sera similaire à celui-ci:
Name: backend
Namespace: default
CreationTimestamp: Mon, 24 Oct 2016 14:21:02 -0700
Labels: app=hello
tier=backend
track=stable
Annotations: deployment.kubernetes.io/revision=1
Selector: app=hello,tier=backend,track=stable
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: app=hello
tier=backend
track=stable
Containers:
hello:
Image: "gcr.io/google-samples/hello-go-gke:1.0"
Port: 80/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: hello-3621623197 (3/3 replicas created)
Events:
...
Création du Service hello
La solution pour envoyer des requêtes d'un frontend vers un backend est le Service backend
.
Un Service crée une adresse IP persistante et un enregistrement DNS afin que le microservice backend puisse toujours être joignable.
Un Service utilise des sélecteurs pour trouver les Pods vers lesquels acheminer le trafic.
Tout d'abord, explorez le fichier de configuration du Service :
---
apiVersion: v1
kind: Service
metadata:
name: hello
spec:
selector:
app: hello
tier: backend
ports:
- protocol: TCP
port: 80
targetPort: http
...
Dans le fichier de configuration, vous pouvez voir que le Service,
nommé hello
, achemine le trafic vers les Pods ayant les labels app: hello
et tier: backend
.
Créez le Service backend :
kubectl apply -f https://k8s.io/examples/service/access/backend-service.yaml
À ce stade, vous avez un Deployment backend
exécutant trois réplicas de votre application hello
,
et un Service capable d'acheminer le trafic vers celles-ci.
Cependant, ce service n'est ni disponible, ni résolvable en dehors du cluster.
Création du frontend
Maintenant que votre backend est opérationnel,
vous pouvez créer un frontend accessible en dehors du cluster,
qui se connecte au backend en acheminant les requêtes vers celui-ci.
Le frontend envoie des requêtes aux Pods du backend en utilisant le nom DNS attribué au Service backend.
Le nom DNS est hello
, qui est la valeur du champ name
dans le fichier de configuration examples/service/access/backend-service.yaml
.
Les Pods du frontend Deployment exécutent une image nginx
configurée pour acheminer les requêtes vers le Service backend hello
.
Voici le fichier de configuration nginx :
# The identifier Backend is internal to nginx, and used to name this specific upstream
upstream Backend {
# hello is the internal DNS name used by the backend Service inside Kubernetes
server hello;
}
server {
listen 80;
location / {
# The following statement will proxy traffic to the upstream named Backend
proxy_pass http://Backend;
}
}
Comme pour le backend, le frontend dispose d'un Deployment et d'un Service.
Une différence importante à noter entre les services backend et frontend est que
le Service frontend est configuré avec un type: LoadBalancer
, ce qui signifie que le Service utilise
un équilibreur de charge provisionné par votre fournisseur de cloud et sera accessible depuis l'extérieur du cluster.
---
apiVersion: v1
kind: Service
metadata:
name: frontend
spec:
selector:
app: hello
tier: frontend
ports:
- protocol: "TCP"
port: 80
targetPort: 80
type: LoadBalancer
...
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
selector:
matchLabels:
app: hello
tier: frontend
track: stable
replicas: 1
template:
metadata:
labels:
app: hello
tier: frontend
track: stable
spec:
containers:
- name: nginx
image: "gcr.io/google-samples/hello-frontend:1.0"
lifecycle:
preStop:
exec:
command: ["/usr/sbin/nginx","-s","quit"]
...
Créez le Deployment et le Service frontend :
kubectl apply -f https://k8s.io/examples/service/access/frontend-deployment.yaml
kubectl apply -f https://k8s.io/examples/service/access/frontend-service.yaml
Le retour valide la création des deux ressources:
deployment.apps/frontend created
service/frontend created
Note: La configuration de nginx est présente dans
l'image du container. Une meilleure approche serait
d'utiliser une
ConfigMap,
afin de pouvoir changer la configuration plus facilement.
Interagir avec le Service frontend
Une fois que vous avez créé un Service de type LoadBalancer, vous pouvez utiliser cette commande pour trouver l'IP externe :
kubectl get service frontend --watch
Cela affiche la configuration du Service frontend
et surveille les changements.
Initialement, l'IP externe est indiquée comme <pending>
:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend LoadBalancer 10.51.252.116 <pending> 80/TCP 10s
Dès qu'une IP externe est attribuée, cependant,
la configuration est mise à jour pour inclure la nouvelle IP sous l'en-tête EXTERNAL-IP
:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend LoadBalancer 10.51.252.116 XXX.XXX.XXX.XXX 80/TCP 1m
Cette IP peut maintenant être utilisée pour interagir avec le service frontend
depuis l'extérieur du cluster.
Envoyer du trafic via le frontend
Le frontend et le backend sont maintenant connectés.
Vous pouvez accéder à l'endpoint en utilisant la commande curl sur l'IP externe de votre Service frontend.
curl http://${EXTERNAL_IP} # à remplacer par l'ip externe affichée précédemment
Le résultat affiche le message généré par le backend :
Cleanup
Pour supprimer les Services, saisissez cette commande :
kubectl delete services frontend backend
Pour supprimer les Deployments, les ReplicaSets et les Pods qui exécutent les applications backend et frontend,
saisissez cette commande :
kubectl delete deployment frontend backend
A suivre
8.6 - 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, entrez
kubectl 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 champ image
du json retourné.
- 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
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
Note: Lors de la récupération d'un seul pod par son nom, par exemple 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
9 - Gestion des Secrets
Gérer des données confidentielles avec les Secrets.
9.1 - Gestion des secrets avec kubectl
Créer des Secrets via la ligne de commande kubectl.
Cette page vous montre comment créer, éditer, gérer et supprimer des
Secrets Kubernetes en utilisant l'outil de ligne de commande kubectl
.
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:
Créer un Secret
Un objet Secret
stocke des données sensibles telles que des informations d'identification
utilisées par des Pods pour accéder à des services. Par exemple, vous pourriez avoir besoin d'un Secret pour stocker
le nom d'utilisateur et le mot de passe nécessaires pour accéder à une base de données.
Vous pouvez créer le Secret en passant les données brutes dans la commande, ou en stockant
les informations d'identification dans des fichiers que vous transmettez à la commande. Les commandes suivantes
créent un Secret qui stocke le nom d'utilisateur admin
et le mot de passe S!B\*d$zDsb=
.
Utiliser des données brutes
Exécutez la commande suivante :
kubectl create secret generic db-user-pass \
--from-literal=username=admin \
--from-literal=password='S!B\*d$zDsb='
Vous devez utiliser des guillemets simples ''
pour échapper les caractères spéciaux tels que $
, \
,
*
, =
, et !
dans vos chaînes de caractères. Sinon, votre shell
interprétera ces caractères.
Note: Le champ stringData
pour un Secret ne fonctionne pas bien avec le traitement des modifications coté serveur (Server Side Apply).
Utiliser des fichiers sources
-
Stockez les informations d'identification dans des fichiers :
echo -n 'admin' > ./username.txt
echo -n 'S!B\*d$zDsb=' > ./password.txt
L'argument -n
garantit que les fichiers générés n'ont pas de saut de ligne supplémentaire
à la fin du texte. C'est important car lorsque kubectl
lit un fichier et encode le contenu dans une chaîne base64, le saut de ligne supplémentaire
sera également encodé. Vous n'avez pas besoin d'échapper les caractères spéciaux
dans les chaînes que vous incluez dans un fichier.
-
Passez les chemins des fichiers dans la commande kubectl
:
kubectl create secret generic db-user-pass \
--from-file=./username.txt \
--from-file=./password.txt
Par défaut, le nom de la clé sera le nom du fichier. Vous pouvez éventuellement définir le nom de la clé
en utilisant --from-file=[key=]source
. Par exemple :
kubectl create secret generic db-user-pass \
--from-file=username=./username.txt \
--from-file=password=./password.txt
Avec l'une ou l'autre méthode, le résultat est similaire à :
secret/db-user-pass created
Vérifier le Secret
Vérifiez que le Secret a été créé :
Le résultat est similaire à :
NAME TYPE DATA AGE
db-user-pass Opaque 2 51s
Affichez les détails du Secret :
kubectl describe secret db-user-pass
Le résultat est similaire à :
Name: db-user-pass
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 12 bytes
username: 5 bytes
Les commandes kubectl get
et kubectl describe
n'affichent pas le contenu
d'un Secret
par défaut. Cela protège le Secret
contre une exposition
accidentelle, ou d'être stocké dans un historique de terminal.
Décoder le Secret
-
Affichez le contenu du Secret que vous avez créé :
kubectl get secret db-user-pass -o jsonpath='{.data}'
Le résultat est similaire à :
{ "password": "UyFCXCpkJHpEc2I9", "username": "YWRtaW4=" }
-
Décodez les données de password
:
echo 'UyFCXCpkJHpEc2I9' | base64 --decode
Le résultat est similaire à :
S!B\*d$zDsb=
Avertissement: Ceci est un exemple à des fins de documentation. En pratique,
cette méthode pourrait entraîner l'enregistrement de la commande avec les données encodées
dans l'historique de votre shell. Toute personne ayant accès à votre ordinateur pourrait trouver la
commande et décoder le secret. Une meilleure approche consiste à combiner les commandes d'affichage et de décodage.
kubectl get secret db-user-pass -o jsonpath='{.data.password}' | base64 --decode
Modifier un Secret
Vous pouvez éditer un objet Secret
existant sauf s'il est
immuable. Pour éditer un
Secret, exécutez la commande suivante :
kubectl edit secrets <secret-name>
Cela ouvre votre éditeur par défaut et vous permet de mettre à jour les valeurs base64 encodées
du Secret dans le champ data
, comme dans l'exemple suivant :
# Éditez l'objet ci-dessous. Les lignes commençant par '#' seront ignorées,
# et un fichier vide interrompra l'édition. Si une erreur se produit lors de l'enregistrement du fichier, il sera
# re ouvert en affichant les erreurs.
#
apiVersion: v1
data:
password: UyFCXCpkJHpEc2I9
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: "2022-06-28T17:44:13Z"
name: db-user-pass
namespace: default
resourceVersion: "12708504"
uid: 91becd59-78fa-4c85-823f-6d44436242ac
type: Opaque
Nettoyer
Pour supprimer un Secret, exécutez la commande suivante :
kubectl delete secret db-user-pass
A suivre
9.2 - Gestion des Secrets avec un fichier de configuration
Créer des Secrets en utilisant un fichier de configuration de ressources.
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:
Créer le Secret
Vous pouvez d'abord définir l'objet Secret
dans un fichier, au format JSON ou YAML,
puis créer cet objet. La ressource
Secret
contient deux clé : data
et stringData
.
Le champ data
est utilisé pour stocker des données encodées en base64. Le
champ stringData
est fourni par commodité et permet de fournir
les mêmes données sous forme de texte non encodé.
Les valeurs de data
et stringData
doivent être composées de caractères alphanumériques,
-
, _
ou .
.
L'exemple suivant stocke deux chaînes de caractères dans un Secret en utilisant le champ data
.
-
Convertissez le texte en base64 :
echo -n 'admin' | base64
echo -n '1f2d1e2e67df' | base64
Note: Les valeurs JSON et YAML du Secret sont sérialisées puis encodées en base64. Les sauts de ligne ne sont pas valides à l'intérieur de 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 lignes longues. En revanche, les utilisateurs Linux doivent ajouter l'option -w 0
à la commande base64
ou alors utiliser base64 | tr -d '\n'
si l'option -w
n'est pas disponible.
Le résultat sera similaire à :
YWRtaW4=
MWYyZDFlMmU2N2Rm
-
Créez le manifeste :
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
Notez que le nom d'un objet Secret doit être un
nom de sous-domaine DNS valide.
-
Créez le Secret en utilisant kubectl apply
:
kubectl apply -f ./secret.yaml
Le résultat sera similaire à :
secret/mysecret created
Pour vérifier que le Secret a été créé et pour décoder les données du Secret, référez-vous à la page sur la
Gestion des secrets à l'aide de kubectl.
Spécifier des données non encodées lors de la création d'un Secret
Pour certains cas, vous pouvez
utiliser le champ stringData
à la place. Ce
champ vous permet d'ajouter du texte non encodé directement dans le Secret,
et il sera encodé pour vous lors de la création ou de la mise à jour du Secret.
Un exemple pratique de ce besoin pourrait être lorsque vous déployez une application
qui utilise un Secret pour stocker un fichier de configuration, et que vous voulez configurer
certaines parties de ce fichier de configuration pendant votre processus de déploiement.
Par exemple, si votre application utilise le fichier de configuration suivant :
apiUrl: "https://my.api.com/api/v1"
username: "<user>"
password: "<password>"
Vous pourriez le stocker dans un Secret en utilisant la définition suivante :
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
stringData:
config.yaml: |
apiUrl: "https://my.api.com/api/v1"
username: <user>
password: <password>
Note: Le champ stringData
pour un Secret ne fonctionne pas bien avec le traitement des modifications coté serveur (Server Side Apply).
Lorsque vous récupérez les données du Secret, la commande retourne les valeurs encodées,
et non les valeurs en texte brut que vous avez fournies dans stringData
.
Par exemple, si vous exécutez la commande suivante :
kubectl get secret mysecret -o yaml
Le résultat sera similaire à :
apiVersion: v1
data:
config.yaml: YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IHt7dXNlcm5hbWV9fQpwYXNzd29yZDoge3twYXNzd29yZH19
kind: Secret
metadata:
creationTimestamp: 2018-11-15T20:40:59Z
name: mysecret
namespace: default
resourceVersion: "7225"
uid: c280ad2e-e916-11e8-98f2-025000000001
type: Opaque
Spécifier à la fois data
et stringData
Si vous spécifiez un champ à la fois dans data
et stringData
, la valeur de stringData
sera utilisée.
Par exemple, si vous définissez le Secret suivant :
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
stringData:
username: administrator
Note: Le champ stringData
pour un Secret ne fonctionne pas bien avec le traitement des modifications coté serveur (Server Side Apply).
L'objet Secret
sera créé comme ceci :
apiVersion: v1
data:
username: YWRtaW5pc3RyYXRvcg==
kind: Secret
metadata:
creationTimestamp: 2018-11-15T20:46:46Z
name: mysecret
namespace: default
resourceVersion: "7579"
uid: 91460ecb-e917-11e8-98f2-025000000001
type: Opaque
YWRtaW5pc3RyYXRvcg==
décodé devient administrator
.
Modifier un Secret
Pour éditer les données du Secret que vous avez créé à l'aide d'un manifeste, modifiez le champ data
ou stringData
dans votre manifeste et appliquez le fichier à votre
cluster. Vous pouvez éditer un objet Secret existant à moins qu'il ne soit
immuable.
Par exemple, si vous souhaitez changer le mot de passe de l'exemple précédent pour
birdsarentreal
, procédez comme suit :
-
Encodez le nouveau mot de passe:
echo -n 'birdsarentreal' | base64
Le résultat sera similaire à :
YmlyZHNhcmVudHJlYWw=
-
Mettre à jour le champ data
avec votre nouvelle valeur :
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: YmlyZHNhcmVudHJlYWw=
-
Appliquer la configuration sur votre cluster :
kubectl apply -f ./secret.yaml
Le résultat sera similaire à :
secret/mysecret configured
Kubernetes met à jour l'objet Secret existant. Pour être précis, l'outil kubectl
remarque qu'il existe déja un Secret
existant avec le même nom. kubectl
récupère l'objet existant, planifie les modifications dessus et soumet le Secret
modifié au plan de contrôle du cluster.
Si vous utilisez kubectl apply --server-side
, kubectl
utilisera plutôt
le traitement coté serveur (Server Side Apply).
Nettoyage
Pour supprimer le Secret que vous venez de créer :
kubectl delete secret mysecret
A suivre
9.3 - Gestion des secrets avec Kustomize
Créer des Secrets à l'aide du fichier kustomization.yaml.
kubectl
prend en charge l'utilisation de l'outil de gestion des objets Kustomize pour gérer les Secrets
et ConfigMaps. Vous créez un générateur de ressources avec Kustomize, qui
génère un Secret que vous pouvez appliquer au serveur API à l'aide de kubectl
.
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:
Créer un Secret
Vous pouvez générer un Secret en définissant un secretGenerator
dans un
fichier kustomization.yaml
qui référence d'autres fichiers existants, des fichiers .env
, ou
des valeurs littérales. Par exemple, les instructions suivantes créent un fichier Kustomization
pour le nom d'utilisateur admin
et le mot de passe 1f2d1e2e67df
.
Note: Le champ stringData
pour un Secret ne fonctionne pas bien avec le traitement des modifications coté serveur (Server Side Apply).
Créer le fichier Kustomization
secretGenerator:
- name: database-creds
literals:
- username=admin
- password=1f2d1e2e67df
-
Stockez les informations d'identification dans des fichiers. Les noms de fichiers sont les clés du secret :
echo -n 'admin' > ./username.txt
echo -n '1f2d1e2e67df' > ./password.txt
L'argument -n
garantit qu'il n'y a pas de saut de ligne supplémentaire
à la fin de vos fichiers.
-
Créez le fichier kustomization.yaml
:
secretGenerator:
- name: database-creds
files:
- username.txt
- password.txt
Vous pouvez également définir le générateur de secret dans le fichier kustomization.yaml
en
fournissant des fichiers .env
. Par exemple, le fichier kustomization.yaml
suivant
récupère les données du fichier .env.secret
:
secretGenerator:
- name: db-user-pass
envs:
- .env.secret
Dans tous les cas, vous n'avez pas besoin d'encoder les valeurs en base64. Le nom du fichier YAML
doit être kustomization.yaml
ou kustomization.yml
.
Appliquer le fichier kustomization
Pour créer le Secret, appliquez le répertoire contenant le fichier kustomization :
kubectl apply -k <directory-path>
Le résutat est similaire à :
secret/database-creds-5hdh7hhgfk created
Lorsqu'un Secret est généré, le nom du Secret est créé en hashant
les données du Secret et en ajoutant la valeur de hachage au nom. Cela garantit qu'un
nouveau Secret sera généré à chaque fois que les données sont modifiées.
Pour vérifier que le Secret a été créé et décoder les données du Secret,
kubectl get -k <directory-path> -o jsonpath='{.data}'
Le résutat est similaire à :
{ "password": "UyFCXCpkJHpEc2I9", "username": "YWRtaW4=" }
echo 'UyFCXCpkJHpEc2I9' | base64 --decode
Le résultat est similaire à :
S!B\*d$zDsb=
Pour en savor plus, consultez
la gestion des secrets avec kubectl et la
Gestion déclarative des objets Kubernetes avec Kustomize.
Modifier un Secret
-
Dans votre fichier kustomization.yaml
, modifiez les données, par exemple password
.
-
Appliquez le dossier contenant le fichier kustomization :
kubectl apply -k <directory-path>
Le résultat sera similaire à :
secret/db-user-pass-6f24b56cc8 created
Le Secret modifié est créé en tant que nouvel objet Secret
, au lieu de mettre à jour
le Secret
existant. Il sera peut-être nécessaire de
mettre à jour les références au Secret dans vos Pods.
Nettoyage
Pour supprimer un Secret, utilisez kubectl
:
kubectl delete secret db-user-pass
A suivre
10 - Monitoring, Logging et Debugging
10.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, entrez
kubectl 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
Note: Le double tiret "-" est utilisé pour séparer les arguments que vous souhaitez passer à la commande des arguments kubectl.
Dans votre shell, listez le répertoire racine:
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
:
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
11 - Extensions de Kubernetes
11.1 - Utilisation des ressources personnalisées
12 - TLS
13 - Fédération
13.1 - Administration du Control Plane de la fédération
14 - Gestion des démons du cluster