Tâches

Cette section de la documentation de Kubernetes contient des pages qui montrent comment effectuer des tâches individuelles. Une page montre comment effectuer une seule chose, généralement en donnant une courte séquence d'étapes.

Interface web (Dashboard)

Déployer et accéder au dashboard web de votre cluster pour vous aider à le gérer et administrer un cluster Kubernetes.

Utilisation de la ligne de commande kubectl

Installez et configurez l’outil en ligne de commande kubectl utilisé pour gérer directement les clusters Kubernetes.

Configuration des Pods et des Conteneurs

Effectuer des tâches de configuration courantes pour les pods et les conteneurs.

Exécution d'applications

Effectuez des tâches courantes de gestion des applications, telles que les mises à jour progressives, l'injection de données dans les pods et la mise à l'échelle automatique des pods.

Executez des jobs

Exécuter des jobs en utilisant un traitement parallèle

Accéder aux applications dans un cluster

Configuration du load balancing, du port forwarding, ou mise en place d'un firewall ou la configuration DNS pour accéder aux applications dans un cluster.

Monitoring, Logging, and Debugging

Mettre en place le monitoring et le logging pour diagnostiquer un cluster ou debugguer une application conteneurisée.

Accéder à l'API Kubernetes

Apprenez diverses méthodes pour accéder directement à l'API Kubernetes.

Utiliser TLS

Configurer votre application pour faire confiance à et utiliser le certificat racine de votre Certificate Authority (CA).

Administration d'un cluster

Apprenez les tâches courantes pour administrer un cluster.

Administration d'une fédération

Configurez les composants dans une fédération de cluster.

Gestion des applications avec état

Effectuez des taches communes pour gérer des applications avec état, notamment la mise à l'échelle, la suppression et le debugging des objets StatefulSets.

Gestion des démons cluster

Effectuez des tâches courantes pour gérer un DaemonSet, telles que la mise à jour progressive.

Gestion des GPU

Configurer des GPUs NVIDIA pour les utiliser dans des noeuds dans un cluster.

Gestion des HugePages

Configuration des huge pages comme une ressource planifiable dans un cluster.

A suivre

Si vous souhaitez écrire une page, consultez Création d'une PullRequest de documentation.

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

  1. Téléchargez la dernière release avec la commande :

    curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
    

    Pour télécharger une version spécifique, remplacez $(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt) avec la version spécifique.

    Par exemple, pour télécharger la version v1.22.16 sur Linux, tapez :

    curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.22.16/bin/linux/amd64/kubectl
    
  2. Rendez le binaire kubectl exécutable.

    chmod +x ./kubectl
    
  3. Déplacez le binaire dans votre PATH.

    sudo mv ./kubectl /usr/local/bin/kubectl
    
  4. Testez pour vous assurer que la version que vous avez installée est à jour:

    kubectl version --client
    

Installation à l'aide des gestionnaires des paquets natifs


sudo apt-get update && sudo apt-get install -y apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubectl

sudo cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
sudo yum install -y kubectl

Installation avec des gestionnaires de paquets alternatifs

Si vous êtes sur Ubuntu ou une autre distribution Linux qui supporte le gestionnaire de paquets snap, kubectl est disponible comme application snap.

snap install kubectl --classic

kubectl version --client

Si vous êtes sur Linux et que vous utiliser Homebrew comme gestionnaire de paquets, kubectl est disponible. installation

brew install kubectl

kubectl version --client

Installer kubectl sur macOS

Installer le binaire kubectl avec curl sur macOS

  1. Téléchargez la dernière version:

    curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl
    

    Pour télécharger une version spécifique, remplacez $(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt) avec la version spécifique.

    Par exemple, pour télécharger la version v1.22.16 sur macOS, tapez :

    curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.22.16/bin/darwin/amd64/kubectl
    
  2. Rendez le binaire kubectl exécutable.

    chmod +x ./kubectl
    
  3. Déplacez le binaire dans votre PATH.

    sudo mv ./kubectl /usr/local/bin/kubectl
    
  4. 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.

  1. Exécutez la commande d'installation:

    brew install kubectl 
    

    ou

    brew install kubernetes-cli
    
  2. 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.

  1. Exécuter la commande d'installation:

    sudo port selfupdate
    sudo port install kubectl
    
  2. 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

  1. Téléchargez la dernière version v1.22.16 depuis ce lien.

    Ou si vous avez curl installé, utilisez cette commande:

    curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.22.16/bin/windows/amd64/kubectl.exe
    

    Pour connaître la dernière version stable (par exemple, en scripting), jetez un coup d'oeil à https://storage.googleapis.com/kubernetes-release/release/stable.txt.

  2. Ajoutez le binaire dans votre PATH.

  3. Testez pour vous assurer que la version que vous avez installée est à jour:

    kubectl version --client
    

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.

  1. Exécutez les commandes d'installation (spécifier le DownloadLocation):

    Install-Script -Name install-kubectl -Scope CurrentUser -Force
    install-kubectl.ps1 [-DownloadLocation <path>]
    

    Le programme d'installation creé $HOME/.kube qui est suivie par la création d'un fichier de configuration

  2. Testez pour vous assurer que la version que vous avez installée est à jour:

    kubectl version --client
    

Installer sur Windows avec Chocolatey ou Scoop

Pour installer kubectl sur Windows, vous pouvez utiliser le gestionnaire de paquets Chocolatey ou l'installateur en ligne de commande Scoop.

choco install kubernetes-cli

scoop install kubectl
2. Testez pour vous assurer que la version que vous avez installée est à jour:

```
kubectl version --client
```
  1. Accédez à votre répertoire personnel:

    cd %USERPROFILE%
    
  2. Créez le répertoire .kube:

    mkdir .kube
    
  3. Allez dans le répertoire .kube que vous venez de créer:

    cd .kube
    
  4. Configurez kubectl pour utiliser un remote cluster Kubernetes:

    New-Item config -type file
    

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.

  1. Installer Google Cloud SDK.

  2. Exécutez la commande d'installation kubectl:

    gcloud components install kubectl
    
  3. Testez pour vous assurer que la version que vous avez installée est à jour:

    kubectl version --client
    

Vérification de la configuration de kubectl

Pour permettre à kubectl de trouver et d'accéder à un cluster Kubernetes, il lui faut un fichier kubeconfig, qui est créé automatiquement lorsque vous créez un cluster avec kube-up.sh ou en déployant un cluster Minikube avec succès. Par défaut, la configuration de kubectl est située sous ~/.kube/config.

Vérifiez que kubectl est correctement configuré en obtenant l'état du cluster:

kubectl cluster-info

Si vous voyez une réponse avec une URL, kubectl est correctement configuré pour accéder à votre cluster.

Si vous voyez un message similaire à celui qui suit, kubectl n'est pas configuré correctement ou n'est pas capable de se connecter à un cluster Kubernetes.

The connection to the server <server-name:port> was refused - did you specify the right host or port?

Si par exemple, vous avez l'intention d'exécuter un cluster Kubernetes sur votre machine (localement), vous aurez besoin d'un outil comme Minikube pour être installé en premier et exécuter à nouveau les commandes décrites ci-dessus.

Si kubectl cluster-info retourne la réponse en url mais que vous ne pouvez pas accéder à votre cluster, vous pouvez vérifier s'il est configuré correctement, en utilisant:

kubectl cluster-info dump

Configurations kubectl optionnelles

Activation de l'auto-complétion de shell

kubectl fournit un support d'auto-complétion pour Bash et Zsh, ce qui peut vous éviter beaucoup de temps de saisie.

Vous trouverez ci-dessous les étapes à suivre pour configurer l'auto-complétion pour Bash (y compris la différence entre Linux et MacOS) et Zsh.

Introduction

Le script de complétion kubectl pour Bash peut être généré avec la commande kubectl completion bash. Sourcer le script de completion dans votre shell permet l'auto-complétion de kubectl.

En revanche, le script de complétion dépend de bash-completion, ce qui implique que vous devez d'abord installer ce logiciel (vous pouvez tester si vous avez déjà installé bash-completion en utilisant type _init_completion).

Installer bash-completion

bash-completion est fourni par plusieurs gestionnaires de paquets (voir ici). Vous pouvez l'installer avec apt-get install bash-completion or yum install bash-completion, etc.

Les commandes ci-dessus créent /usr/share/bash-completion/bash_completion, qui est le script principal de bash-completion. En fonction de votre gestionnaire de paquets, vous devez manuellement sourcer ce fichier dans votre ~/.bashrc.

Il vous suffit de recharger votre shell et de lancer type _init_completion. Si la commande réussit, vous êtes déjà configuré, sinon ajoutez le suivant à votre fichier `~/.bashrc' :

source /usr/share/bash-completion/bash_completion

Rechargez votre shell et vérifiez que bash-completion est correctement installé en tapant type _init_completion.

Activer l'auto-complétion de kubectl

Vous devez maintenant vérifier que le script de completion de kubectl est bien sourcé dans toutes vos sessions shell. Il y a deux façons de le faire:

  • Sourcer le script de completion dans votre fichier ~/.bashrc:

    echo 'source <(kubectl completion bash)' >>~/.bashrc
    
  • Ajoutez le script de complétion dans le répertoire /etc/bash_completion.d:

    kubectl completion bash >/etc/bash_completion.d/kubectl
    
  • Si vous avez un alias pour kubectl, vous pouvez étendre la completion de votre shell pour fonctionner avec cet alias:

    echo 'alias k=kubectl' >>~/.bashrc
    echo 'complete -F __start_kubectl k' >>~/.bashrc
    

Les deux approches sont équivalentes. Après avoir rechargé votre shell, l'auto-complétion de kubectl devrait fonctionner.

Introduction

Le script de complétion kubectl pour Bash peut être généré avec la commande kubectl completion bash. Sourcer le script de completion dans votre shell permet l'auto-complétion de kubectl.

En revanche, le script de complétion dépend de bash-completion, ce qui implique que vous devez d'abord installer ce logiciel.

Installer bash-completion

Vous pouvez tester si vous avez déjà installé bash-completion en utilisant type _init_completion. Si il n'est pas installé, vous pouvez installer bash-completion avec Homebrew:

brew install bash-completion@2

Comme indiqué dans la sortie de brew install (section "Caveats"), ajoutez les lignes suivantes à votre fichier ~/.bashrc ou ~/.bash_profile :

export BASH_COMPLETION_COMPAT_DIR="/usr/local/etc/bash_completion.d"
[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"

Rechargez votre shell et vérifiez que bash-completion v2 est correctement installé avec type _init_completion.

Activer l'auto-complétion de kubectl

Si vous n'avez pas installé via Homebrew, vous devez maintenant vous assurer que le script de complétion kubectl est bien sourcé dans toutes vos sessions shell comme suit:

  • Sourcer le script de completion dans votre fichier ~/.bashrc:

    echo 'source <(kubectl completion bash)' >>~/.bashrc
    
    
  • Ajoutez le script de complétion dans le répertoire /usr/local/etc/bash_completion.d:

    kubectl completion bash >/usr/local/etc/bash_completion.d/kubectl
    
  • Si vous avez un alias pour kubectl, vous pouvez étendre la completion de votre shell pour fonctionner avec cet alias:

    echo 'alias k=kubectl' >>~/.bashrc
    echo 'complete -F __start_kubectl k' >>~/.bashrc
    

Si vous avez installé kubectl avec Homebrew (comme expliqué ici), alors le script de complétion a été automatiquement installé dans /usr/local/etc/bash_completion.d/kubectl. Dans ce cas, vous n'avez rien à faire.

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.

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.

Installer Minikube à l'aide d'un package

Il existe des packages * expérimentaux * pour Minikube; vous pouvez trouver des packages Linux (AMD64) depuis la page releases de Minikube sur GitHub.

Utilisez l'outil de package de votre distribution Linux pour installer un package approprié.

Installez Minikube par téléchargement direct

Si vous n'installez pas via un package, vous pouvez télécharger un binaire autonome et l'utiliser.

curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 \
  && chmod +x minikube

Voici un moyen simple d'ajouter l'exécutable Minikube à votre path :

sudo mkdir -p /usr/local/bin/
sudo install minikube /usr/local/bin/

Installer Minikube en utilisant Homebrew

Une autre alternative, vous pouvez installer Minikube en utilisant Linux [Homebrew] (https://docs.brew.sh/Homebrew-on-Linux) :

brew install minikube

Installer kubectl

Installez kubectl en suivant les instructions de la section Installer et configurer kubectl.

Installer un hyperviseur

Si vous n'avez pas encore installé d'hyperviseur, installez-en un maintenant :

HyperKit

VirtualBox

VMware Fusion

Installer Minikube

La façon la plus simple d'installer Minikube sur macOS est d'utiliser Homebrew:

brew install minikube

Vous pouvez aussi l'installer sur macOS en téléchargeant un binaire statique :

curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 \
  && chmod +x minikube

Voici une façon simple d'ajouter l'exécutable de Minikube à votre path :

sudo mv minikube /usr/local/bin

Installer kubectl

Installez kubectl en suivant les instructions de la section Installer et configurer kubectl.

Installer un hyperviseur

Si vous n'avez pas encore installé d'hyperviseur, installez-en un maintenant :

Hyper-V

VirtualBox

Installer Minikube en utilisant Chocolatey

La façon la plus simple d'installer Minikube sur Windows est d'utiliser Chocolatey (exécuté avec les droits administrateur) :

choco install minikube

Une fois l'installation de Minikube terminée, fermez la session CLI en cours et redémarrez. Minikube devrait avoir été ajouté à votre path automatiquement.

Installer Minikube avec Windows Installer

Pour installer manuellement Minikube sur Windows à l'aide de Windows Installer, téléchargez minikube-installer.exe et exécutez l'Installer.

Installer Minikube manuellement

Pour installer Minikube manuellement sur Windows, téléchargez minikube-windows-amd64, renommez-le en minikube.exe, et ajoutez-le à votre path.

Confirmer l'installation

Pour confirmer la réussite de l'installation d'un hyperviseur et d'un mini-cube, vous pouvez exécuter la commande suivante pour démarrer un cluster Kubernetes local :

minikube start --driver=<driver_name>

Une fois minikube start terminé, exécutez la commande ci-dessous pour vérifier l'état du cluster :

minikube status

Si votre cluster est en cours d'exécution, la sortie de minikube status devrait être similaire à :

host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

Après avoir vérifié si Minikube fonctionne avec l'hyperviseur choisi, vous pouvez continuer à utiliser Minikube ou arrêter votre cluster. Pour arrêter votre cluster, exécutez :

minikube stop

Tout nettoyer pour recommencer à zéro

Si vous avez déjà installé minikube, exécutez :

minikube start

Si cette commande renvoie une erreur :

machine does not exist

Vous devez supprimer les fichiers de configuration :

rm -rf ~/.minikube

A suivre

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é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:

  1. Créez un package Go avec une implémentation satisfaisantcloudprovider.Interface.
  2. 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é.
  3. 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.5 - Kubernetes cloud-controller-manager

FEATURE STATE: Kubernetes v1.22 [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 k8s.gcr.io/cloud-controller-manager
        # cela peut être remplacé par n'importe quelle autre image pour les fournisseurs out-of-tree
        image: k8s.gcr.io/cloud-controller-manager:v1.8.0
        command:
        - /usr/local/bin/cloud-controller-manager
        - --cloud-provider=<YOUR_CLOUD_PROVIDER>   # Ajoutez votre propre fournisseur de cloud ici!
        - --leader-elect=true
        - --use-service-account-credentials
        # ces drapeaux varient pour chaque fournisseur de cloud
        - --allocate-node-cidrs=true
        - --configure-cloud-routes=true
        - --cluster-cidr=172.17.0.0/16
      tolerations:
      # cela est nécessaire pour que CCM puisse s'initialiser
      - key: node.cloudprovider.kubernetes.io/uninitialized
        value: "true"
        effect: NoSchedule
      # le daemonset doit pouvoir être exécuté sur les nœuds master. Le marquage peut varier en fonction de la configuration de votre cluster.
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      # ceci limite le fonctionnement du CCM sur des nœuds master
      # le sélecteur de nœud peut varier en fonction de la configuration de votre cluster
      nodeSelector:
        node-role.kubernetes.io/master: ""

Limitations

L'exécution du cloud-controller-manager est soumise à quelques limitations. Bien que ces limitations soient levées dans les prochaines versions, il est important que vous connaissiez ces limitations pour les charges de travail de production.

Prise en charge des volumes

Le cloud-controller-manager n'implémente aucun des contrôleurs de volume trouvés dans kube-controller-manager car les intégrations de volume nécessitent également une coordination avec les kubelets. Au fur et à mesure de l'évolution de CSI (interface de stockage de conteneur) et de la prise en charge renforcée des plug-ins de volume flexible, le cloud-controller-manager prendra en charge le support nécessaire afin que les clouds puissent pleinement s'intégrer aux volumes. Pour en savoir plus sur les plug-ins de volume CSI en dehors des sources de Kubernetes consultez ceci.

Charge sur les APIs cloud

Dans l'architecture précédente pour les fournisseurs de cloud, nous utilisions des kubelets utilisant un service de métadonnées local pour extraire des informations sur les nœuds. Avec cette nouvelle architecture, nous comptons désormais entièrement sur les cloud-controller-manager pour extraire les informations de tous les nœuds. Pour les très grand clusters, vous devez envisager les goulots d'étranglement tels que les besoins en ressources et la limitation de la vitesse des APIs de votre fournisseur cloud.

Problème de l'oeuf et de la poule

L'objectif du projet des cloud-controller-manager est de dissocier le développement des fonctionnalités de cloud computing du projet de base Kubernetes. Malheureusement, de nombreux aspects du projet Kubernetes supposent que les fonctionnalités de fournisseur de cloud soient étroitement intégrées au projet. Par conséquent, l'adoption de cette nouvelle architecture peut créer plusieurs situations dans lesquelles une demande d'informations auprès d'un fournisseur de cloud est demandée, mais le cloud-controller-manager peut ne pas être en mesure de renvoyer ces informations sans que la demande d'origine soit complète.

La fonctionnalité d’amorçage TLS dans Kubelet en est un bon exemple. Actuellement, l’amorçage TLS suppose que Kubelet aie la possibilité de demander au fournisseur de cloud (ou à un service de métadonnées local) tous ses types d’adresses (privé, public, etc.), mais le cloud-controller-manager ne peut pas définir les types d’adresse d’un nœud sans être initialisé dans le système. Ce qui nécessite que le kubelet possède des certificats TLS pour communiquer avec l’apiserver.

À mesure que cette initiative évoluera, des modifications seront apportées pour résoudre ces problèmes dans les prochaines versions.

Développer votre propre cloud-controller-manager

Pour créer et développer votre propre cloud-controller-manager, lisez la documentation Développer un cloud-controller-manager.

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 :

kubectl get apiservices

Si l'API des métriques de ressources est disponible, la sortie inclura une référence à metrics.k8s.io.

NAME
v1beta1.metrics.k8s.io

Créer un namespace

Créez un namespace de manière à ce que les ressources que vous créez dans cet exercice soient isolées du reste de votre cluster.

kubectl create namespace mem-example

Spécifier une demande de mémoire et une limite de mémoire

Pour spécifier une demande de mémoire pour un conteneur, incluez le champ resources:requests. dans le manifeste des ressources du conteneur. Pour spécifier une limite de mémoire, incluez resources:limits.

Dans cet exercice, vous créez un pod qui possède un seul conteneur. Le conteneur dispose d'une demande de mémoire de 100 MiB et une limite de mémoire de 200 MiB. Voici le fichier de configuration pour le Pod :

apiVersion: v1
kind: Pod
metadata:
  name: memory-demo
  namespace: mem-example
spec:
  containers:
  - name: memory-demo-ctr
    image: polinux/stress
    resources:
      limits:
        memory: "200Mi"
      requests:
        memory: "100Mi"
    command: ["stress"]
    args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]

La section args de votre fichier de configuration fournit des arguments pour le conteneur lorsqu'il démarre. Les arguments "--vm-bytes", "150M" indiquent au conteneur d'allouer 150 MiB de mémoire.

Créez le Pod:

kubectl apply -f https://k8s.io/examples/pods/resource/memory-request-limit.yaml --namespace=mem-example

Vérifiez que le Pod fonctionne :

kubectl get pod memory-demo --namespace=mem-example

Consultez des informations détaillées sur le Pod :

kubectl get pod memory-demo --output=yaml --namespace=mem-example

La sortie montre que le conteneur dans le Pod a une demande de mémoire de 100 MiB et une limite de mémoire de 200 MiB.

...
resources:
  limits:
    memory: 200Mi
  requests:
    memory: 100Mi
...

Exécutez kubectl top pour récupérer les métriques du pod :

kubectl top pod memory-demo --namespace=mem-example

La sortie montre que le Pod utilise environ 162.900.000 bytes de mémoire, qui est d'environ 150 MiB. Ce qui est supérieur à la demande de 100 MiB du Pod, mais ne dépassant pas la limite de 200 Mio de Pod.

NAME                        CPU(cores)   MEMORY(bytes)
memory-demo                 <something>  162856960

Supprimez votre Pod :

kubectl delete pod memory-demo --namespace=mem-example

Dépasser la limite de mémoire d'un conteneur

Un conteneur peut dépasser sa demande de mémoire si le nœud dispose de la mémoire disponible. Cependant, un conteneur n'est pas autorisé à utiliser plus que sa limite de mémoire. Si un conteneur alloue plus de mémoire que sa limite, le Conteneur devient un candidat à la terminaison. Si le conteneur continue à consommer de la mémoire au-delà de sa limite, le conteneur est arrêté. Si un conteneur terminé peut être redémarré, le kubelet le redémarre, comme pour tout autre type d'échec d'exécution.

Dans cet exercice, vous créez un Pod qui tente d'allouer plus de mémoire que sa limite. Voici le fichier de configuration d'un Pod qui contient un conteneur avec une demande de mémoire de 50 MiB et une limite de mémoire de 100 MiB :

apiVersion: v1
kind: Pod
metadata:
  name: memory-demo-2
  namespace: mem-example
spec:
  containers:
  - name: memory-demo-2-ctr
    image: polinux/stress
    resources:
      requests:
        memory: "50Mi"
      limits:
        memory: "100Mi"
    command: ["stress"]
    args: ["--vm", "1", "--vm-bytes", "250M", "--vm-hang", "1"]

Dans la section args du fichier de configuration, vous pouvez voir que le conteneur tentera d'allouer 250 MiB de mémoire, ce qui est bien au-dessus de la limite de 100 MiB.

Créez le Pod :

kubectl apply -f https://k8s.io/examples/pods/resource/memory-request-limit-2.yaml --namespace=mem-example

Consultez des informations détaillées sur le Pod :

kubectl get pod memory-demo-2 --namespace=mem-example

A ce niveau, le conteneur est soit en train de tourner, soit stoppé. Répétez la commande précédente jusqu'à ce que le conteneur soit terminé :

NAME            READY     STATUS      RESTARTS   AGE
memory-demo-2   0/1       OOMKilled   1          24s

Obtenez une vue plus détaillée de l'état du conteneur :

kubectl get pod memory-demo-2 --output=yaml --namespace=mem-example

La sortie indique que le conteneur a été stoppé suite à un manque de mémoire (OOM) :

lastState:
   terminated:
     containerID: docker://65183c1877aaec2e8427bc95609cc52677a454b56fcb24340dbd22917c23b10f
     exitCode: 137
     finishedAt: 2017-06-20T20:52:19Z
     reason: OOMKilled
     startedAt: null

Le conteneur dans cet exercice pourra être redémarré, ainsi le kubelet le redémarre. Répéter cette commande plusieurs fois pour s'assurer que le conteneur est stoppé et redémarré d'une manière répététive :

kubectl get pod memory-demo-2 --namespace=mem-example

La sortie permet de voir que le conteneur est stoppé, redémarré, stoppé à nouveau, redémarré, et ainsi de suite :

kubectl get pod memory-demo-2 --namespace=mem-example
NAME            READY     STATUS      RESTARTS   AGE
memory-demo-2   0/1       OOMKilled   1          37s

kubectl get pod memory-demo-2 --namespace=mem-example
NAME            READY     STATUS    RESTARTS   AGE
memory-demo-2   1/1       Running   2          40s

Affichez des informations détaillées sur l'historique du Pod :

kubectl describe pod memory-demo-2 --namespace=mem-example

La sortie indique que le conteneur se démarre et échoue continuellement :

... Normal  Created   Created container with id 66a3a20aa7980e61be4922780bf9d24d1a1d8b7395c09861225b0eba1b1f8511
... Warning BackOff   Back-off restarting failed container

Affichez des informations détaillées sur les nœuds de votre cluster :

kubectl describe nodes

La sortie inclut un enregistrement de la mise à mort du conteneur suite à une condition hors mémoire :

Warning OOMKilling Memory cgroup out of memory: Kill process 4481 (stress) score 1994 or sacrifice child

Supprimez votre Pod :

kubectl delete pod memory-demo-2 --namespace=mem-example

Spécifiez une demande de mémoire trop volumineuse pour vos nœuds.

Les demandes de mémoire et les limites sont associées aux conteneurs, mais il est utile de réfléchir avant tout à la capacité de demande et limite mémoire des pods. La demande de mémoire pour le Pod est la somme des demandes de mémoire pour tous ses conteneurs. De même, la mémoire limite pour le Pod est la somme des limites de tous ses Conteneurs.

L'ordonnancement des modules est basé sur les demandes. Un Pod est schedulé pour se lancer sur un Nœud uniquement si le Nœud dispose de suffisamment de mémoire disponible pour répondre à la demande de mémoire du Pod.

Dans cet exercice, vous allez créer un Pod dont la demande de mémoire est si importante qu'elle dépasse la capacité de la mémoire de n'importe quel nœud de votre cluster. Voici le fichier de configuration d'un Pod qui possède un seul conteneur avec une demande de 1000 GiB de mémoire, qui dépasse probablement la capacité de tous les nœuds de votre cluster.

apiVersion: v1
kind: Pod
metadata:
  name: memory-demo-3
  namespace: mem-example
spec:
  containers:
  - name: memory-demo-3-ctr
    image: polinux/stress
    resources:
      limits:
        memory: "1000Gi"
      requests:
        memory: "1000Gi"
    command: ["stress"]
    args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]

Créez le Pod :

kubectl apply -f https://k8s.io/examples/pods/resource/memory-request-limit-3.yaml --namespace=mem-example

Affichez l'état du Pod :

kubectl get pod memory-demo-3 --namespace=mem-example

La sortie indique que l'état du Pod est PENDING. En d'autres termes, le Pod n'est pas programmé pour tourner sur aucun Nœud, et il restera indéfiniment dans l'état PENDING :

kubectl get pod memory-demo-3 --namespace=mem-example
NAME            READY     STATUS    RESTARTS   AGE
memory-demo-3   0/1       Pending   0          25s

Affichez des informations détaillées sur le Pod, y compris les événements :

kubectl describe pod memory-demo-3 --namespace=mem-example

La sortie indique que le conteneur ne peut pas être planifié par manque de mémoire sur les nœuds :

Events:
  ...  Reason            Message
       ------            -------
  ...  FailedScheduling  No nodes are available that match all of the following predicates:: Insufficient memory (3).

Unités de mémoire

La ressource mémoire est mesurée en bytes. Vous pouvez exprimer la mémoire sous la forme d'un nombre entier simple ou d'un nombre avec l'un de ces suffixes : E, P, T, G, M, K, Ei, Pi, Ti, Gi, Mi, Ki. Par exemple, les valeurs suivantes représentent approximativement la même valeur :

128974848, 129e6, 129M , 123Mi

Supprimez votre Pod :

kubectl delete pod memory-demo-3 --namespace=mem-example

Si vous ne spécifiez pas de limite de mémoire

Si vous ne spécifiez pas de limite de mémoire pour un conteneur, l'une des situations suivantes s'applique :

  • Le conteneur n'a pas de limite maximale quant à la quantité de mémoire qu'il utilise. Le conteneur pourrait utiliser toute la mémoire disponible sur le nœud où il est en cours d'exécution, ce qui pourrait à son tour invoquer le OOM killer. De plus, dans le cas d'un OOM Kill, un conteneur sans limite de ressources aura plus de chance d'être stoppé.

  • Le conteneur s'exécute dans un namespace qui a une limite de mémoire par défaut, d'ou le conteneur est automatiquement affecté cette limite par defaut. Les administrateurs du cluster peuvent utiliser un LimitRange pour spécifier une valeur par défaut pour la limite de mémoire.

Motivation pour les demandes et les limites de mémoire

En configurant les demandes de mémoire et les limites pour les conteneurs qui s'exécutent dans votre cluster. vous pouvez utiliser efficacement les ressources mémoire disponibles sur les noeuds de votre cluster. En gardant la demande de mémoire d'un Pod basse, vous donnez au Pod une bonne chance d'être schedulé. En ayant une limite de mémoire supérieure à la demande de mémoire, vous accomplissez deux choses :

  • Le Pod peut avoir des éclats d'activités où il fait usage de la mémoire qui se trouve être disponible.
  • La quantité de mémoire qu'un Pod peut utiliser pendant un éclat d'activité est limitée à une quantité raisonnable.

Clean up

Supprimez votre namespace. Ceci va supprimer tous les Pods que vous avez créés dans cet exercice :

kubectl delete namespace mem-example

A suivre

Pour les développeurs d'applications

Pour les administrateurs de cluster

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:

kubectl get apiservices

Si l'API de métriques de ressources est disponible, la sortie inclura une référence à metrics.k8s.io.

NAME
v1beta1.metrics.k8s.io

Créer un namespace

Créez un namespace de manière à ce que les ressources que vous créez dans cet exercice soient isolés du reste de votre cluster.

kubectl create namespace cpu-example

Spécifier une demande de CPU et une limite de CPU

Pour spécifier une demande de CPU pour un conteneur, incluez le champ resources:requests. dans le manifeste des ressources du conteneur. Pour spécifier une limite de CPU, incluez resources:limits.

Dans cet exercice, vous allez créer un Pod qui a un seul conteneur. Le conteneur a une demande de 0.5 CPU et une limite de 1 CPU. Voici le fichier de configuration du Pod :

apiVersion: v1
kind: Pod
metadata:
  name: cpu-demo
  namespace: cpu-example
spec:
  containers:
  - name: cpu-demo-ctr
    image: vish/stress
    resources:
      limits:
        cpu: "1"
      requests:
        cpu: "0.5"
    args:
    - -cpus
    - "2"

La section args du fichier de configuration fournit des arguments pour le conteneur lorsqu'il démarre. L'argument -cpus "2" demande au conteneur d'utiliser 2 CPUs.

Créez le Pod:

kubectl apply -f https://k8s.io/examples/pods/resource/cpu-request-limit.yaml --namespace=cpu-example

Vérifiez que le Pod fonctionne :

kubectl get pod cpu-demo --namespace=cpu-example

Consultez des informations détaillées sur le Pod :

kubectl get pod cpu-demo --output=yaml --namespace=cpu-example

La sortie indique que le conteneur dans le Pod a une demande CPU de 500 milliCPU. et une limite de CPU de 1 CPU.

resources:
  limits:
    cpu: "1"
  requests:
    cpu: 500m

Utilisez kubectl top pour récupérer les métriques du pod :

kubectl top pod cpu-demo --namespace=cpu-example

La sortie montre que le Pod utilise 974 milliCPU, ce qui est légèrement inférieur à la limite de 1 CPU spécifiée dans le fichier de configuration du Pod.

NAME                        CPU(cores)   MEMORY(bytes)
cpu-demo                    974m         <something>

Souvenez-vous qu'en réglant -cpu "2", vous avez configuré le conteneur pour faire en sorte qu'il utilise 2 CPU, mais que le conteneur ne peut utiliser qu'environ 1 CPU. L'utilisation du CPU du conteneur est entravée, car le conteneur tente d'utiliser plus de ressources CPU que sa limite.

Unités de CPU

La ressource CPU est mesurée en unités CPU. Un CPU, à Kubernetes, est équivalent à:

  • 1 AWS vCPU
  • 1 GCP Core
  • 1 Azure vCore
  • 1 Hyperthread sur un serveur physique avec un processeur Intel qui a de l'hyperthreading.

Les valeurs fractionnelles sont autorisées. Un conteneur qui demande 0,5 CPU est garanti deux fois moins CPU par rapport à un conteneur qui demande 1 CPU. Vous pouvez utiliser le suffixe m pour signifier milli. Par exemple 100m CPU, 100 milliCPU, et 0.1 CPU sont tous égaux. Une précision plus fine que 1m n'est pas autorisée.

Le CPU est toujours demandé en tant que quantité absolue, jamais en tant que quantité relative, 0.1 est la même quantité de CPU sur une machine single-core, dual-core ou 48-core.

Supprimez votre pod :

kubectl delete pod cpu-demo --namespace=cpu-example

Spécifier une demande de CPU trop élevée pour vos nœuds.

Les demandes et limites de CPU sont associées aux conteneurs, mais il est utile de réfléchir à la demande et à la limite de CPU d'un pod. La demande de CPU pour un Pod est la somme des demandes de CPU pour tous les conteneurs du Pod. De même, la limite de CPU pour les un Pod est la somme des limites de CPU pour tous les conteneurs du Pod.

L'ordonnancement des pods est basé sur les demandes. Un Pod est prévu pour se lancer sur un Nœud uniquement si le nœud dispose de suffisamment de ressources CPU pour satisfaire la demande de CPU du Pod.

Dans cet exercice, vous allez créer un Pod qui a une demande de CPU si importante qu'elle dépassera la capacité de n'importe quel nœud de votre cluster. Voici le fichier de configuration d'un Pod qui a un seul conteneur. Le conteneur nécessite 100 CPU, ce qui est susceptible de dépasser la capacité de tous les nœuds de votre cluster.

apiVersion: v1
kind: Pod
metadata:
  name: cpu-demo-2
  namespace: cpu-example
spec:
  containers:
  - name: cpu-demo-ctr-2
    image: vish/stress
    resources:
      limits:
        cpu: "100"
      requests:
        cpu: "100"
    args:
    - -cpus
    - "2"

Créez le Pod :

kubectl apply -f https://k8s.io/examples/pods/resource/cpu-request-limit-2.yaml --namespace=cpu-example

Affichez l'état du Pod :

kubectl get pod cpu-demo-2 --namespace=cpu-example

La sortie montre que l'état du Pod est en attente. En d'autres termes, le Pod n'a pas été planifié pour tourner sur n'importe quel Nœud, et il restera à l'état PENDING indéfiniment :

kubectl get pod cpu-demo-2 --namespace=cpu-example
NAME         READY     STATUS    RESTARTS   AGE
cpu-demo-2   0/1       Pending   0          7m

Afficher des informations détaillées sur le Pod, y compris les événements:

kubectl describe pod cpu-demo-2 --namespace=cpu-example

la sortie signale que le conteneur ne peut pas être planifié en raison d'une quantité insuffisante de ressources de CPU sur les Nœuds :

Events:
  Reason			Message
  ------			-------
  FailedScheduling	No nodes are available that match all of the following predicates:: Insufficient cpu (3).

Supprimez votre Pod :

kubectl delete pod cpu-demo-2 --namespace=cpu-example

Si vous ne spécifiez pas de limite CPU

Si vous ne spécifiez pas de limite CPU pour un conteneur, une de ces situations s'applique :

  • Le conteneur n'a pas de limite maximale quant aux ressources CPU qu'il peut utiliser. Le conteneur pourrait utiliser toutes les ressources CPU disponibles sur le nœud où il est lancé.

  • Le conteneur est lancé dans un namespace qui a une limite par défaut de CPU, ainsi le conteneur reçoit automatiquement cette limite par défaut. Les administrateurs du cluster peuvent utiliser un LimitRange pour spécifier une valeur par défaut pour la limite de CPU.

Motivation pour les demandes et les limites du CPU

En configurant les demandes et les limites de CPU des conteneurs qui se lancent sur votre cluster, vous pouvez utiliser efficacement les ressources CPU disponibles sur les Nœuds de votre cluster. En gardant une demande faible de CPU de pod, vous donnez au Pod une bonne chance d'être ordonnancé. En ayant une limite CPU supérieure à la demande de CPU, vous accomplissez deux choses :

  • Le Pod peut avoir des pics d'activité où il utilise les ressources CPU qui se sont déjà disponible.
  • La quantité de ressources CPU qu'un Pod peut utiliser pendant une pic d'activité est limitée à une quantité raisonnable.

Nettoyage

Supprimez votre namespace :

kubectl delete namespace cpu-example

A suivre

Pour les développeurs d'applications

Pour les administrateurs de cluster

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

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.22 [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/fooexample.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.

Configurer un volume pour un Pod

Dans cet exercice, vous créez un pod qui contient un seul conteneur. Ce Pod a un Volume de type emptyDir qui dure toute la vie du Pod, même si le conteneur se termine et redémarre. Voici le fichier de configuration du Pod :

apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: redis
    volumeMounts:
    - name: redis-storage
      mountPath: /data/redis
  volumes:
  - name: redis-storage
    emptyDir: {}
  1. Créez le Pod :

    kubectl apply -f https://k8s.io/examples/pods/storage/redis.yaml
    
  2. 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
    
  3. Dans un autre terminal, accédez à la console shell du conteneur en cours d'exécution :

    kubectl exec -it redis -- /bin/bash
    
  4. 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
    
  5. 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
    
  6. Dans votre shell, arrêtez le processus Redis :

    root@redis:/data/redis# kill <pid>
    

    <pid> est l'ID de processus Redis (PID).

  7. 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.

  1. Accédez à la console shell du conteneur redémarré :

    kubectl exec -it redis -- /bin/bash
    
  2. 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
    
  3. Supprimez le pod que vous avez créé pour cet exercice :

    kubectl delete pod redis
    

A suivre

  • Voir Volume.

  • Voir Pod.

  • En plus du stockage sur disque local fourni par emptyDir, Kubernetes supporte de nombreuses solutions de stockage connectées au réseau, y compris PD sur GCE et EBS sur EC2, qui sont préférés pour les données critiques et qui s'occuperont des autres détails tels que le montage et le démontage sur les nœuds. Voir Volumes pour plus de détails.

3.6 - Configurer les comptes de service pour les pods

Un ServiceAccount (compte de service) fournit une identité pour les processus qui s'exécutent dans un Pod.

Ceci est une introduction aux comptes de service pour les utilisateurs. Voir aussi Guide de l'administrateur du cluster des comptes de service.

Lorsque vous (un humain) accédez au cluster (par exemple, en utilisant kubectl), vous êtes authentifié par l'apiserver en tant que compte d'utilisateur particulier (actuellement, il s'agit généralement de l'utilisateur admin, à moins que votre administrateur de cluster n'ait personnalisé votre cluster). Les processus dans les conteneurs dans les Pods peuvent également contacter l'apiserver. Dans ce cas, ils sont authentifiés en tant que compte de service particulier (par exemple, default).

Pré-requis

Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:

Pour consulter la version, 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:          ...

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]

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.7 - Récupération d'une image d'un registre privé

Cette page montre comment créer un Pod qui utilise un Secret pour récupérer une image d'un registre privé.

Pré-requis

  • Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:

    Pour consulter la version, 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 :

docker login

Une fois que c'est fait, entrez votre nom d'utilisateur et votre mot de passe Docker.

Le processus de connexion crée ou met à jour un fichier config.json qui contient un token d'autorisation.

Consultez le fichier config.json :

cat ~/.docker/config.json

La sortie comporte une section similaire à celle-ci :

{
    "auths": {
        "https://index.docker.io/v1/": {
            "auth": "c3R...zE2"
        }
    }
}

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.

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.8 - Configurer les Liveness, Readiness et Startup Probes

Cette page montre comment configurer les liveness, readiness et startup probes pour les conteneurs.

Le Kubelet utilise les liveness probes pour détecter quand redémarrer un conteneur. Par exemple, les Liveness probes pourraient attraper un deadlock dans le cas où une application est en cours d'exécution, mais qui est incapable de traiter les requêtes. Le redémarrage d'un conteneur dans un tel état rend l'application plus disponible malgré les bugs.

Le Kubelet utilise readiness probes pour savoir quand un conteneur est prêt à accepter le trafic. Un Pod est considéré comme prêt lorsque tous ses conteneurs sont prêts. Ce signal sert notamment à contrôler les pods qui sont utilisés comme backends pour les Services. Lorsqu'un Pod n'est pas prêt, il est retiré des équilibreurs de charge des Services.

Le Kubelet utilise startup probes pour savoir quand une application d'un conteneur a démarré. Si une telle probe est configurée, elle désactive les contrôles de liveness et readiness jusqu'à cela réussit, en s'assurant que ces probes n'interfèrent pas avec le démarrage de l'application. Cela peut être utilisé dans le cas des liveness checks sur les conteneurs à démarrage lent, en les évitant de se faire tuer par le Kubelet avant qu'ils ne soient opérationnels.

Pré-requis

Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:

Pour consulter la version, 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 k8s.gcr.io/busybox. Voici le fichier de configuration pour le Pod :

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

Dans le fichier de configuration, vous constatez que le Pod a un seul conteneur. Le champ periodSeconds spécifie que le Kubelet doit effectuer un check de liveness toutes les 5 secondes. Le champ initialDelaySeconds indique au Kubelet qu'il devrait attendre 5 secondes avant d'effectuer la première probe. Pour effectuer une probe, le Kubelet exécute la commande cat /tmp/healthy dans le conteneur. Si la commande réussit, elle renvoie 0, et le Kubelet considère que le conteneur est vivant et en bonne santé. Si la commande renvoie une valeur non nulle, le Kubelet tue le conteneur et le redémarre.

Au démarrage, le conteneur exécute cette commande :

/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"

Pour les 30 premières secondes de la vie du conteneur, il y a un fichier /tmp/healthy. Donc pendant les 30 premières secondes, la commande cat /tmp/healthy renvoie un code de succès. Après 30 secondes, cat /tmp/healthy renvoie un code d'échec.

Créez le Pod :

kubectl apply -f https://k8s.io/examples/pods/probe/exec-liveness.yaml

Dans les 30 secondes, visualisez les événements du Pod :

kubectl describe pod liveness-exec

La sortie indique qu'aucune liveness probe n'a encore échoué :

FirstSeen    LastSeen    Count   From            SubobjectPath           Type        Reason      Message
--------- --------    -----   ----            -------------           --------    ------      -------
24s       24s     1   {default-scheduler }                    Normal      Scheduled   Successfully assigned liveness-exec to worker0
23s       23s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Pulling     pulling image "k8s.gcr.io/busybox"
23s       23s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Pulled      Successfully pulled image "k8s.gcr.io/busybox"
23s       23s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Created     Created container with docker id 86849c15382e; Security:[seccomp=unconfined]
23s       23s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Started     Started container with docker id 86849c15382e

Après 35 secondes, visualisez à nouveau les événements du Pod :

kubectl describe pod liveness-exec

Au bas de la sortie, il y a des messages indiquant que les liveness probes ont échoué, et que les conteneurs ont été tués et recréés.

FirstSeen LastSeen    Count   From            SubobjectPath           Type        Reason      Message
--------- --------    -----   ----            -------------           --------    ------      -------
37s       37s     1   {default-scheduler }                    Normal      Scheduled   Successfully assigned liveness-exec to worker0
36s       36s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Pulling     pulling image "k8s.gcr.io/busybox"
36s       36s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Pulled      Successfully pulled image "k8s.gcr.io/busybox"
36s       36s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Created     Created container with docker id 86849c15382e; Security:[seccomp=unconfined]
36s       36s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Started     Started container with docker id 86849c15382e
2s        2s      1   {kubelet worker0}   spec.containers{liveness}   Warning     Unhealthy   Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory

Attendez encore 30 secondes et vérifiez que le conteneur a été redémarré :

kubectl get pod liveness-exec

La sortie montre que RESTARTS a été incrémenté :

NAME            READY     STATUS    RESTARTS   AGE
liveness-exec   1/1       Running   1          1m

Définir une requête HTTP de liveness

Un autre type de liveness probe utilise une requête GET HTTP. Voici la configuration d'un Pod qui fait fonctionner un conteneur basé sur l'image k8s.gcr.io/liveness.

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/liveness
    args:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3

Dans le fichier de configuration, vous pouvez voir que le Pod a un seul conteneur. Le champ periodSeconds spécifie que le Kubelet doit effectuer une liveness probe toutes les 3 secondes. Le champ initialDelaySeconds indique au Kubelet qu'il devrait attendre 3 secondes avant d'effectuer la première probe. Pour effectuer une probe, le Kubelet envoie une requête HTTP GET au serveur qui s'exécute dans le conteneur et écoute sur le port 8080. Si le handler du chemin /healthz du serveur renvoie un code de succès, le Kubelet considère que le conteneur est vivant et en bonne santé. Si le handler renvoie un code d'erreur, le Kubelet tue le conteneur et le redémarre.

Tout code supérieur ou égal à 200 et inférieur à 400 indique un succès. Tout autre code indique un échec.

Vous pouvez voir le code source du serveur dans server.go.

Pendant les 10 premières secondes où le conteneur est en vie, le handler /healthz renvoie un statut de 200. Après cela, le handler renvoie un statut de 500.

http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
    duration := time.Now().Sub(started)
    if duration.Seconds() > 10 {
        w.WriteHeader(500)
        w.Write([]byte(fmt.Sprintf("erreur: %v", duration.Seconds())))
    } else {
        w.WriteHeader(200)
        w.Write([]byte("ok"))
    }
})

Le Kubelet commence à effectuer des contrôles de santé 3 secondes après le démarrage du conteneur. Ainsi, les premiers contrôles de santé seront réussis. Mais après 10 secondes, les contrôles de santé échoueront, et le Kubelet tuera et redémarrera le conteneur.

Pour essayer le HTTP liveness check, créez un Pod :

kubectl apply -f https://k8s.io/examples/pods/probe/http-liveness.yaml

Après 10 secondes, visualisez les événements du Pod pour vérifier que les liveness probes ont échoué et le conteneur a été redémarré :

kubectl describe pod liveness-http

Dans les versions antérieures à la v1.13 (y compris la v1.13), au cas où la variable d'environnement http_proxy (ou HTTP_PROXY) est définie sur le noeud où tourne un Pod, le HTTP liveness probe utilise ce proxy. Dans les versions postérieures à la v1.13, les paramètres de la variable d'environnement du HTTP proxy local n'affectent pas le HTTP liveness probe.

Définir une TCP liveness probe

Un troisième type de liveness probe utilise un TCP Socket. Avec cette configuration, le Kubelet tentera d'ouvrir un socket vers votre conteneur sur le port spécifié. S'il arrive à établir une connexion, le conteneur est considéré comme étant en bonne santé, s'il n'y arrive pas, c'est un échec.

apiVersion: v1
kind: Pod
metadata:
  name: goproxy
  labels:
    app: goproxy
spec:
  containers:
  - name: goproxy
    image: k8s.gcr.io/goproxy:0.1
    ports:
    - containerPort: 8080
    readinessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
    livenessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 20

Comme vous le voyez, la configuration pour un check TCP est assez similaire à un check HTTP. Cet exemple utilise à la fois des readiness et liveness probes. Le Kubelet transmettra la première readiness probe 5 secondes après le démarrage du conteneur. Il tentera de se connecter au conteneur goproxy sur le port 8080. Si la probe réussit, le conteneur sera marqué comme prêt. Kubelet continuera à effectuer ce check tous les 10 secondes.

En plus de la readiness probe, cette configuration comprend une liveness probe. Le Kubelet effectuera la première liveness probe 15 secondes après que le conteneur démarre. Tout comme la readiness probe, celle-ci tentera de se connecter au conteneur de goproxy sur le port 8080. Si la liveness probe échoue, le conteneur sera redémarré.

Pour essayer la TCP liveness check, créez un Pod :

kubectl apply -f https://k8s.io/examples/pods/probe/tcp-liveness-readiness.yaml

Après 15 secondes, visualisez les événements de Pod pour vérifier les liveness probes :

kubectl describe pod goproxy

Utilisation d'un port nommé

Vous pouvez utiliser un ContainerPort nommé pour les HTTP or TCP liveness probes :

ports:
- name: liveness-port
  containerPort: 8080
  hostPort: 8080

livenessProbe:
  httpGet:
    path: /healthz
    port: liveness-port

Protéger les conteneurs à démarrage lent avec des startup probes

Parfois, vous devez faire face à des applications legacy qui peuvent nécessiter un temps de démarrage supplémentaire lors de leur première initialisation. Dans de telles situations, il peut être compliqué de régler les paramètres de la liveness probe sans compromettant la réponse rapide aux blocages qui ont motivé une telle probe. L'astuce est de configurer une startup probe avec la même commande, HTTP ou TCP check avec un failureThreshold * periodSeconds assez long pour couvrir le pire des scénarios des temps de démarrage.

Ainsi, l'exemple précédent deviendrait :

ports:
- name: liveness-port
  containerPort: 8080
  hostPort: 8080

livenessProbe:
  httpGet:
    path: /healthz
    port: liveness-port
  failureThreshold: 1
  periodSeconds: 10

startupProbe:
  httpGet:
    path: /healthz
    port: liveness-port
  failureThreshold: 30
  periodSeconds: 10

Grâce à la startup probe, l'application aura un maximum de 5 minutes (30 * 10 = 300s) pour terminer son démarrage. Une fois que la startup probe a réussi, la liveness probe prend le relais pour fournir une réponse rapide aux blocages de conteneurs. Si la startup probe ne réussit jamais, le conteneur est tué après 300s puis soumis à la restartPolicy (politique de redémarrage) du Pod.

Définir les readiness probes

Parfois, les applications sont temporairement incapables de servir le trafic. Par exemple, une application peut avoir besoin de charger des larges données ou des fichiers de configuration pendant le démarrage, ou elle peut dépendre de services externes après le démarrage. Dans ces cas, vous ne voulez pas tuer l'application, mais vous ne voulez pas non plus lui envoyer de requêtes. Kubernetes fournit des readiness probes pour détecter et atténuer ces situations. Un pod avec des conteneurs qui signale qu'elle n'est pas prête ne reçoit pas de trafic par les services de Kubernetes.

Readiness probes sont configurées de la même façon que les liveness probes. La seule différence est que vous utilisez le champ readinessProbe au lieu du champ livenessProbe.

readinessProbe:
  exec:
    command:
    - cat
    - /tmp/healthy
  initialDelaySeconds: 5
  periodSeconds: 5

La configuration des readiness probes HTTP et TCP reste également identique à celle des liveness probes.

Les readiness et liveness probes peuvent être utilisées en parallèle pour le même conteneur. L'utilisation des deux peut garantir que le trafic n'atteigne pas un conteneur qui n'est pas prêt et que les conteneurs soient redémarrés en cas de défaillance.

Configurer les Probes

Probes ont un certain nombre de champs qui vous pouvez utiliser pour contrôler plus précisément le comportement de la vivacité et de la disponibilité des probes :

  • initialDelaySeconds: Nombre de secondes après le démarrage du conteneur avant que les liveness et readiness probes ne soient lancées. La valeur par défaut est de 0 seconde. La valeur minimale est 0.
  • periodSeconds: La fréquence (en secondes) à laquelle la probe doit être effectuée. La valeur par défaut est de 10 secondes. La valeur minimale est de 1.
  • timeoutSeconds: Nombre de secondes après lequel la probe time out. Valeur par défaut à 1 seconde. La valeur minimale est de 1.
  • successThreshold: Le minimum de succès consécutifs pour que la probe soit considérée comme réussie après avoir échoué. La valeur par défaut est 1. Doit être 1 pour la liveness probe. La valeur minimale est de 1.
  • failureThreshold: Quand un Pod démarre et que la probe échoue, Kubernetes va 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.9 - Assigner des pods aux nœuds

Cette page montre comment assigner un Pod à un nœud particulier dans un cluster Kubernetes.

Pré-requis

Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:

Pour consulter la version, entrez kubectl version.

Ajouter un label à un nœud

  1. Listez les nœuds de votre cluster :

    kubectl get nodes
    

    La sortie est la suivante :

    NAME      STATUS    ROLES     AGE     VERSION
    worker0   Ready     <none>    1d      v1.13.0
    worker1   Ready     <none>    1d      v1.13.0
    worker2   Ready     <none>    1d      v1.13.0
    
  2. Choisissez l'un de vos nœuds et ajoutez-y un label :

    kubectl label nodes <your-node-name> disktype=ssd
    

    <your-node-name> est le nom du noeud que vous avez choisi.

  3. 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
  1. 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
    
  2. 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.10 - Configurer l'initialisation du pod

Cette page montre comment utiliser un Init conteneur pour initialiser un Pod avant de lancer un conteneur d'application.

Pré-requis

Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:

Pour consulter la version, 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.11 - Configurer un pod pour utiliser une ConfigMap

Les ConfigMaps vous permettent de découpler les artefacts de configuration du contenu de l'image pour garder les applications conteneurisées portables. Cette page fournit une série d'exemples d'utilisation montrant comment créer des ConfigMaps et configurer des pods à l'aide des données stockées dans des ConfigMaps.

Pré-requis

Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:

Pour consulter la version, 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"

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>

<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

  1. Définissez une variable d'environnement comme paire clé-valeur dans un ConfigMap:

    kubectl create configmap special-config --from-literal=special.how=very
    
  2. 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: k8s.gcr.io/busybox
          command: [ "/bin/sh", "-c", "env" ]
          env:
            # Définie la variable d'environnement
            - name: SPECIAL_LEVEL_KEY
              valueFrom:
                configMapKeyRef:
                  # La ConfigMap contenant la valeur que vous voulez attribuer à SPECIAL_LEVEL_KEY
                  name: special-config
                  # Spécifier la clé associée à la valeur
                  key: special.how
      restartPolicy: Never
    

    Créez le pod:

kubectl create -f https://kubernetes.io/examples/pods/pod-single-configmap-env-variable.yaml

Maintenant, la sortie du Pod comprend une variable d'environnement SPECIAL_LEVEL_KEY=very.

Définir des variables d'environnement de conteneur avec des données de plusieurs ConfigMaps

  • Comme avec l'exemple précédent, créez d'abord les ConfigMaps.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: special-config
      namespace: default
    data:
      special.how: very
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: env-config
      namespace: default
    data:
      log_level: INFO
    

    Créez le ConfigMap:

kubectl create -f https://kubernetes.io/examples/configmap/configmaps.yaml
  • Définissez les variables d'environnement dans la spécification Pod.

    apiVersion: v1
    kind: Pod
    metadata:
      name: dapi-test-pod
    spec:
      containers:
        - name: test-container
          image: k8s.gcr.io/busybox
          command: [ "/bin/sh", "-c", "env" ]
          env:
            - name: SPECIAL_LEVEL_KEY
              valueFrom:
                configMapKeyRef:
                  name: special-config
                  key: special.how
            - name: LOG_LEVEL
              valueFrom:
                configMapKeyRef:
                  name: env-config
                  key: log_level
      restartPolicy: Never
    

    Créez le pod:

kubectl create -f https://kubernetes.io/examples/pods/pod-multiple-configmap-env-variable.yaml

Maintenant, la sortie du Pod comprend des variables d'environnement SPECIAL_LEVEL_KEY=very et LOG_LEVEL=INFO.

Configurer toutes les paires clé-valeur dans un ConfigMap en tant que variables d'environnement de conteneur

  • Créez un ConfigMap contenant plusieurs paires clé-valeur.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: special-config
      namespace: default
    data:
      SPECIAL_LEVEL: very
      SPECIAL_TYPE: charm
    

    Créez le ConfigMap:

kubectl create -f https://kubernetes.io/examples/configmap/configmap-multikeys.yaml
  • Utilisez envFrom pour définir toutes les données du ConfigMap en tant que variables d'environnement du conteneur. La clé de ConfigMap devient le nom de la variable d'environnement dans le pod.
apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
      - configMapRef:
          name: special-config
  restartPolicy: Never

Créez le pod:

kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-envFrom.yaml

Maintenant, la sortie du Pod comprend les variables d'environnement SPECIAL_LEVEL=very et SPECIAL_TYPE=charm.

Utiliser des variables d'environnement définies par ConfigMap dans les commandes du Pod

Vous pouvez utiliser des variables d'environnement définies par ConfigMap dans la section command de la spécification du Pod en utilisant la syntaxe de substitution Kubernetes $(VAR_NAME).

Par exemple, la spécification de pod suivante

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/echo", "$(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]
      env:
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: SPECIAL_LEVEL
        - name: SPECIAL_TYPE_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: SPECIAL_TYPE
  restartPolicy: Never

créé en exécutant

kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-env-var-valueFrom.yaml

produit la sortie suivante dans le conteneur test-container:

very charm

Ajouter des données ConfigMap à un volume

Comme expliqué dans Créer des ConfigMaps à partir de fichiers, lorsque vous créez un ConfigMap à l'aide --from-file, le nom de fichier devient une clé stockée dans la section data du ConfigMap. Le contenu du fichier devient la valeur de la clé.

Les exemples de cette section se réfèrent à un ConfigMap nommé special-config, illustré ci-dessous.

apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  SPECIAL_LEVEL: very
  SPECIAL_TYPE: charm

Créez le ConfigMap:

kubectl create -f https://kubernetes.io/examples/configmap/configmap-multikeys.yaml

Remplissez un volume avec des données stockées dans un ConfigMap

Ajoutez le nom ConfigMap sous la section volumes de la spécification Pod. Ceci ajoute les données ConfigMap au répertoire spécifié comme volumeMounts.mountPath (dans ce cas, /etc/config). La section command répertorie les fichiers de répertoire dont les noms correspondent aux clés de ConfigMap.

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "ls /etc/config/" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        # Indiquez le nom de la ConfigMap contenant les fichiers que vous souhaitez ajouter au conteneur
        name: special-config
  restartPolicy: Never

Créez le pod:

kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-volume.yaml

Lorsque le pod s'exécute, la commande ls /etc/config/ produit la sortie ci-dessous:

SPECIAL_LEVEL
SPECIAL_TYPE

Ajouter un configmap à un chemin spécifique dans un volume

Utilisez le champ path pour spécifier le chemin de fichier souhaité pour les éléments de configmap spécifiques. Dans ce cas, le SPECIAL_LEVEL sera monté dans le volume config-volume au chemin /etc/config/keys.

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh","-c","cat /etc/config/keys" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: special-config
        items:
        - key: SPECIAL_LEVEL
          path: keys
  restartPolicy: Never

Créez le Pod :

kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-volume-specific-key.yaml

Lorsque le pod fonctionne, la commande cat /etc/config/keys produit la sortie ci-dessous :

very

Projections de clés pour des chemins et des autorisations de fichiers spécifiques

Vous pouvez projeter des clés vers des chemins spécifiques avec des autorisations spécifiques fichiers par fichiers. Le guide de l'utilisateur Secrets explique la syntaxe.

Les ConfigMaps montées sont mises à jour automatiquement

Lorsqu'une ConfigMap déjà consommée dans un volume est mise à jour, les clés projetées sont éventuellement mises à jour elles aussi. Kubelet vérifie si la ConfigMap montée est fraîche à chaque synchronisation périodique. Cependant, il utilise son cache local basé sur le ttl pour obtenir la valeur actuelle de la ConfigMap. Par conséquent, le délai total entre le moment où la ConfigMap est mise à jour et le moment où les nouvelles clés sont projetées vers le pod peut être aussi long que la période de synchronisation de kubelet (1 minute par défaut) + le ttl du cache ConfigMaps (1 minute par défaut) dans kubelet. Vous pouvez déclencher un rafraîchissement immédiat en mettant à jour l'une des annotations du pod.

Comprendre le lien entre les ConfigMaps et les Pods

La ressource API ConfigMap stocke les données de configuration sous forme de paires clé-valeur. Les données peuvent être consommées dans des pods ou fournir les configurations des composants du système tels que les contrôleurs. ConfigMap est similaire à Secrets, mais fournit un moyen de travailler avec des chaînes de caractères qui ne contiennent pas d'informations sensibles. Les utilisateurs comme les composants du système peuvent stocker des données de configuration dans un ConfigMap.

Le champ data de la ConfigMap contient les données de configuration. Comme le montre l'exemple ci-dessous, cela peut être simple -- comme des propriétés individuelles définies à l'aide de --from-literal -- ou complexe -- comme des fichiers de configuration ou des blobs JSON définis à l'aide de --from-file.

apiVersion: v1
kind: ConfigMap
metadata:
  creationTimestamp: 2016-02-18T19:14:38Z
  name: example-config
  namespace: default
data:
  # example of a simple property defined using --from-literal
  example.property.1: hello
  example.property.2: world
  # example of a complex property defined using --from-file
  example.property.file: |-
    property.1=value-1
    property.2=value-2
    property.3=value-3    

Restrictions

  • Vous devez créer un ConfigMap avant de le référencer dans une spécification de Pod (sauf si vous marquez le ConfigMap comme "facultatif"). Si vous faites référence à un ConfigMap qui n'existe pas, le Pod ne démarrera pas. De même, les références à des clés qui n'existent pas dans la ConfigMap empêcheront le pod de démarrer.

  • Si vous utilisez envFrom pour définir des variables d'environnement à partir de ConfigMaps, les clés considérées comme invalides seront ignorées. Le pod sera autorisé à démarrer, mais les noms invalides seront enregistrés dans le journal des événements (InvalidVariableNames). Le message du journal énumère chaque clé sautée. Par exemple :

    kubectl get events
    

    Le résultat est similaire à celui-ci :

    LASTSEEN FIRSTSEEN COUNT NAME          KIND  SUBOBJECT  TYPE      REASON                            SOURCE                MESSAGE
    0s       0s        1     dapi-test-pod Pod              Warning   InvalidEnvironmentVariableNames   {kubelet, 127.0.0.1}  Keys [1badkey, 2alsobad] from the EnvFrom configMap default/myconfig were skipped since they are considered invalid environment variable names.
    
  • Les ConfigMaps résident dans un Namespace. Un ConfigMap ne peut être référencé que par des pods résidant dans le même namespace.

  • Vous ne pouvez pas utiliser des ConfigMaps pour static pods, car le Kubelet ne le supporte pas.

A suivre

3.12 - 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.

Configurer un Pod

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
  1. Créez le pod nginx sur votre cluster :

    kubectl apply -f https://k8s.io/examples/pods/share-process-namespace.yaml
    
  2. 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 :

  1. 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.)

  2. 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.

  3. 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.13 - Convertir un fichier Docker Compose en ressources Kubernetes

C'est quoi Kompose ? C'est un outil de conversion de tout ce qui compose (notamment Docker Compose) en orchestrateurs de conteneurs (Kubernetes ou OpenShift). Vous trouverez plus d'informations sur le site web de Kompose à http://kompose.io.

Pré-requis

Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:

Pour consulter la version, 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:

brew install kompose

Utiliser Kompose

En quelques étapes, nous vous emmenons de Docker Compose à Kubernetes. Tous dont vous avez besoin est un fichier docker-compose.yml.

  1. Allez dans le répertoire contenant votre fichier docker-compose.yml. Si vous n'en avez pas, faites un test en utilisant celui-ci.

    version: "2"
    
    services:
    
      redis-master:
        image: k8s.gcr.io/redis:e2e
        ports:
          - "6379"
    
      redis-slave:
        image: gcr.io/google_samples/gb-redisslave:v3
        ports:
          - "6379"
        environment:
          - GET_HOSTS_FROM=dns
    
      frontend:
        image: gcr.io/google-samples/gb-frontend:v4
        ports:
          - "80:80"
        environment:
          - GET_HOSTS_FROM=dns
        labels:
          kompose.service.type: LoadBalancer
    
  2. Lancez la commande kompose up pour déployer directement sur Kubernetes, ou passez plutôt à l'étape suivante pour générer un fichier à utiliser avec kubectl.

    $ kompose up
    We are going to create Kubernetes Deployments, Services and PersistentVolumeClaims for your Dockerized application.
    If you need different kind of resources, use the 'kompose convert' and 'kubectl apply -f' commands instead.
    
    INFO Successfully created Service: redis          
    INFO Successfully created Service: web            
    INFO Successfully created Deployment: redis       
    INFO Successfully created Deployment: web         
    
    Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods,pvc' for details.
    
  3. 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.

  4. Accédez à votre application.

    Si vous utilisez déjà minikube pour votre processus de développement :

    $ minikube service frontend
    

    Sinon, regardons quelle IP votre service utilise !

    $ kubectl describe svc frontend
    Name:                   frontend
    Namespace:              default
    Labels:                 service=frontend
    Selector:               service=frontend
    Type:                   LoadBalancer
    IP:                     10.0.0.183
    LoadBalancer Ingress:   192.0.2.89
    Port:                   80      80/TCP
    NodePort:               80      31144/TCP
    Endpoints:              172.17.0.4:80
    Session Affinity:       None
    No events.
    
    

    Si vous utilisez un fournisseur de cloud computing, votre IP sera listée à côté de LoadBalancer Ingress.

    $ curl http://192.0.2.89
    

Guide de l'utilisateur

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

kompose up

Kompose propose un moyen simple de déployer votre application "composée" sur Kubernetes ou OpenShift via kompose up.

Kubernetes

$ kompose --file ./examples/docker-guestbook.yml up
We are going to create Kubernetes deployments and services for your Dockerized application.
If you need different kind of resources, use the 'kompose convert' and 'kubectl apply -f' commands instead.

INFO Successfully created service: redis-master   
INFO Successfully created service: redis-slave    
INFO Successfully created service: frontend       
INFO Successfully created deployment: redis-master
INFO Successfully created deployment: redis-slave
INFO Successfully created deployment: frontend    

Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods' for details.

$ kubectl get deployment,svc,pods
NAME                                              DESIRED       CURRENT       UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/frontend                    1             1             1            1           4m
deployment.extensions/redis-master                1             1             1            1           4m
deployment.extensions/redis-slave                 1             1             1            1           4m

NAME                         TYPE               CLUSTER-IP    EXTERNAL-IP   PORT(S)      AGE
service/frontend             ClusterIP          10.0.174.12   <none>        80/TCP       4m
service/kubernetes           ClusterIP          10.0.0.1      <none>        443/TCP      13d
service/redis-master         ClusterIP          10.0.202.43   <none>        6379/TCP     4m
service/redis-slave          ClusterIP          10.0.1.85     <none>        6379/TCP     4m

NAME                                READY         STATUS        RESTARTS     AGE
pod/frontend-2768218532-cs5t5       1/1           Running       0            4m
pod/redis-master-1432129712-63jn8   1/1           Running       0            4m
pod/redis-slave-2504961300-nve7b    1/1           Running       0            4m

Note:

  • Vous devez avoir un cluster Kubernetes en cours d'exécution avec kubectl pré-configuré.
  • Seuls les déploiements et les services sont générés et déployés dans Kubernetes. Si vous avez besoin d'autres types de ressources, utilisez les commandes kompose convert et kubectl apply -f à la place.

OpenShift

$ kompose --file ./examples/docker-guestbook.yml --provider openshift up
We are going to create OpenShift DeploymentConfigs and Services for your Dockerized application.
If you need different kind of resources, use the 'kompose convert' and 'oc create -f' commands instead.

INFO Successfully created service: redis-slave    
INFO Successfully created service: frontend       
INFO Successfully created service: redis-master   
INFO Successfully created deployment: redis-slave
INFO Successfully created ImageStream: redis-slave
INFO Successfully created deployment: frontend    
INFO Successfully created ImageStream: frontend   
INFO Successfully created deployment: redis-master
INFO Successfully created ImageStream: redis-master

Your application has been deployed to OpenShift. You can run 'oc get dc,svc,is' for details.

$ oc get dc,svc,is
NAME               REVISION                              DESIRED       CURRENT    TRIGGERED BY
dc/frontend        0                                     1             0          config,image(frontend:v4)
dc/redis-master    0                                     1             0          config,image(redis-master:e2e)
dc/redis-slave     0                                     1             0          config,image(redis-slave:v1)
NAME               CLUSTER-IP                            EXTERNAL-IP   PORT(S)    AGE
svc/frontend       172.30.46.64                          <none>        80/TCP     8s
svc/redis-master   172.30.144.56                         <none>        6379/TCP   8s
svc/redis-slave    172.30.75.245                         <none>        6379/TCP   8s
NAME               DOCKER REPO                           TAGS          UPDATED
is/frontend        172.30.12.200:5000/fff/frontend                     
is/redis-master    172.30.12.200:5000/fff/redis-master                 
is/redis-slave     172.30.12.200:5000/fff/redis-slave    v1  

Note:

  • Vous devez avoir un cluster OpenShift en cours d'exécution avec oc pré-configuré (oc login)

kompose down

Une fois que vous avez déployé l'application "composée" sur Kubernetes, $ kompose down vous facilitera la suppression de l'application en supprimant ses déploiements et services. Si vous avez besoin de supprimer d'autres ressources, utilisez la commande 'kubectl'.

$ kompose --file docker-guestbook.yml down
INFO Successfully deleted service: redis-master   
INFO Successfully deleted deployment: redis-master
INFO Successfully deleted service: redis-slave    
INFO Successfully deleted deployment: redis-slave
INFO Successfully deleted service: frontend       
INFO Successfully deleted deployment: frontend

Note:

  • Vous devez avoir un cluster Kubernetes en cours d'exécution avec kubectl pré-configuré.

Construire et pousser des images de docker

Kompose permet de construire et de pousser des images Docker. Lorsque vous utilisez la clé build dans votre fichier Docker Compose, votre image sera :

  • Automatiquement construite avec le Docker en utilisant la clé "image" spécifiée dans votre fichier
  • Être poussé vers le bon dépôt Docker en utilisant les identifiants locaux (situés dans .docker/config)

Utilisation d'un exemple de fichier Docker Compose:

version: "2"

services:
    foo:
        build: "./build"
        image: docker.io/foo/bar

En utilisant kompose up avec une clé build :

$ kompose up
INFO Build key detected. Attempting to build and push image 'docker.io/foo/bar'
INFO Building image 'docker.io/foo/bar' from directory 'build'
INFO Image 'docker.io/foo/bar' from directory 'build' built successfully
INFO Pushing image 'foo/bar:latest' to registry 'docker.io'
INFO Attempting authentication credentials 'https://index.docker.io/v1/
INFO Successfully pushed image 'foo/bar:latest' to registry 'docker.io'
INFO We are going to create Kubernetes Deployments, Services and PersistentVolumeClaims for your Dockerized application. If you need different kind of resources, use the 'kompose convert' and 'kubectl apply -f' commands instead.

INFO Deploying application in "default" namespace
INFO Successfully created Service: foo            
INFO Successfully created Deployment: foo         

Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods,pvc' for details.

Afin de désactiver cette fonctionnalité, ou de choisir d'utiliser la génération de BuildConfig (avec OpenShift) --build (local|build-config|none) peut être passé.

# Désactiver la construction/poussée d'images Docker
$ kompose up --build none

# Générer des artefacts de Build Config pour OpenShift
$ kompose up --provider openshift --build build-config

Autres conversions

La transformation par défaut komposer va générer des Déploiements et Services de Kubernetes, au format yaml. Vous avez une autre option pour générer json avec -j. Vous pouvez aussi générer des objets de Replication Controllers, Daemon Sets, ou Helm charts.

$ kompose convert -j
INFO Kubernetes file "redis-svc.json" created
INFO Kubernetes file "web-svc.json" created
INFO Kubernetes file "redis-deployment.json" created
INFO Kubernetes file "web-deployment.json" created

Les fichiers *-deployment.json contiennent les objets Déploiements.

$ kompose convert --replication-controller
INFO Kubernetes file "redis-svc.yaml" created
INFO Kubernetes file "web-svc.yaml" created
INFO Kubernetes file "redis-replicationcontroller.yaml" created
INFO Kubernetes file "web-replicationcontroller.yaml" created

Les fichiers *-replicationcontroller.yaml contiennent les objets du Contrôleur de Réplication. Si vous voulez spécifier des répliques (la valeur par défaut est 1), utilisez l'option --replicas : $ kompose convert --replication-controller --replicas 3

$ kompose convert --daemon-set
INFO Kubernetes file "redis-svc.yaml" created
INFO Kubernetes file "web-svc.yaml" created
INFO Kubernetes file "redis-daemonset.yaml" created
INFO Kubernetes file "web-daemonset.yaml" created

Les fichiers *-daemonset.yaml contiennent les objets du Daemon Set

Si vous voulez générer un Chart à utiliser avec Helm, faites-le simplement :

$ kompose convert -c
INFO Kubernetes file "web-svc.yaml" created
INFO Kubernetes file "redis-svc.yaml" created
INFO Kubernetes file "web-deployment.yaml" created
INFO Kubernetes file "redis-deployment.yaml" created
chart created in "./docker-compose/"

$ tree docker-compose/
docker-compose
├── Chart.yaml
├── README.md
└── templates
    ├── redis-deployment.yaml
    ├── redis-svc.yaml
    ├── web-deployment.yaml
    └── web-svc.yaml

La structure du Chart est destinée à fournir un modèle pour la construction de vos chartes de Helm.

Étiquettes

kompose supporte les étiquettes spécifiques à Kompose dans le fichier docker-compose.yml afin de définir explicitement le comportement d'un service lors de la conversion.

  • Le fichier kompose.service.type définit le type de service à créer.

Par exemple :

version: "2"
services:
  nginx:
    image: nginx
    dockerfile: foobar
    build: ./foobar
    cap_add:
      - ALL
    container_name: foobar
    labels:
      kompose.service.type: nodeport
  • kompose.service.expose définit si le service doit être accessible depuis l'extérieur du cluster ou non. Si la valeur est fixée à "true", le fournisseur définit automatiquement l'extrémité, et pour toute autre valeur, la valeur est définie comme le nom d'hôte. Si plusieurs ports sont définis dans un service, le premier est choisi pour être l'exposé.
    • Pour le fournisseur Kubernetes, une ressource ingress est créée et il est supposé qu'un contrôleur ingress a déjà été configuré.
    • Pour le fournisseur OpenShift, une route est créée.

Par exemple :

version: "2"
services:
  web:
    image: tuna/docker-counter23
    ports:
     - "5000:5000"
    links:
     - redis
    labels:
      kompose.service.expose: "counter.example.com"
  redis:
    image: redis:3.0
    ports:
     - "6379"

Les options actuellement supportées sont :

Key Value
kompose.service.type nodeport / clusterip / loadbalancer
kompose.service.expose true / hostname

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

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 - Injection des données dans les applications

6 - Exécution des applications

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.

Tableau de bord Kubernetes

Déploiement du tableau de bord

L'interface utilisateur du tableau de bord n'est pas déployée par défaut. Pour le déployer, exécutez la commande suivante:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended.yaml

Accès à l'interface utilisateur du tableau de bord

Pour protéger vos données dans le cluster, le tableau de bord se déploie avec une configuration RBAC minimale par défaut. Actuellement, le tableau de bord prend uniquement en charge la connexion avec un jeton de support. Pour créer un jeton pour cette démo, vous pouvez suivre notre guide sur créer un exemple d'utilisateur.

Proxy en ligne de commande

Vous pouvez accéder au tableau de bord à l'aide de l'outil en ligne de commande kubectl en exécutant la commande suivante:

kubectl proxy

Kubectl mettra le tableau de bord à disposition à l'adresse suivante: http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/.

Vous ne pouvez accéder à l'interface utilisateur que depuis la machine sur laquelle la commande est exécutée. Voir kubectl proxy --help pour plus d'options.

Page de bienvenue

Lorsque vous accédez au tableau de bord sur un cluster vide, la page d'accueil s'affiche. Cette page contient un lien vers ce document ainsi qu'un bouton pour déployer votre première application. De plus, vous pouvez voir quelles applications système sont exécutées par défaut dans le namespace kubernetes-dashboard de votre cluster, par exemple le tableau de bord lui-même.

Page d'accueil du tableau de bord Kubernetes

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.

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.

Visualisation de journaux

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.

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

Ajoutez des détails de contexte à votre fichier de configuration:

kubectl config --kubeconfig=config-demo set-context dev-frontend --cluster=development --namespace=frontend --user=developer
kubectl config --kubeconfig=config-demo set-context dev-storage --cluster=development --namespace=storage --user=developer
kubectl config --kubeconfig=config-demo set-context exp-scratch --cluster=scratch --namespace=default --user=experimenter

Ouvrez votre fichier config-demo pour voir les détails ajoutés. Au lieu d'ouvrir le fichier config-demo, vous pouvez utiliser la commande kubectl config view.

kubectl config --kubeconfig=config-demo view

La sortie montre les deux clusters, deux utilisateurs et trois contextes:

apiVersion: v1
clusters:
- cluster:
    certificate-authority: fake-ca-file
    server: https://1.2.3.4
  name: development
- cluster:
    insecure-skip-tls-verify: true
    server: https://5.6.7.8
  name: scratch
contexts:
- context:
    cluster: development
    namespace: frontend
    user: developer
  name: dev-frontend
- context:
    cluster: development
    namespace: storage
    user: developer
  name: dev-storage
- context:
    cluster: scratch
    namespace: default
    user: experimenter
  name: exp-scratch
current-context: ""
kind: Config
preferences: {}
users:
- name: developer
  user:
    client-certificate: fake-cert-file
    client-key: fake-key-file
- name: experimenter
  user:
    password: some-password
    username: exp

Le fake-ca-file, fake-cert-file et fake-key-file ci-dessus sont les espaces réservés pour les noms de chemin des fichiers de certificat. Vous devez les remplacer par les noms de chemin réels des fichiers de certificat dans votre environnement.

Parfois, vous souhaiterez peut-être utiliser des données encodées en Base64 incorporées ici au lieu de fichiers de certificat séparés; dans ce cas, vous devez ajouter le suffixe -data aux clés, par exemple, certificate-Authority-data, client-certificate-data, client-key-data.

Chaque contexte est un triplet (cluster, utilisateur, namespace). Par exemple, le contexte dev-frontend dit, "Utilisez les informations d'identification de l'utilisateur developer pour accéder au namespace frontend du cluster development".

Définissez le contexte actuel:

kubectl config --kubeconfig=config-demo use-context dev-frontend

Maintenant, chaque fois que vous entrez une commande kubectl, l'action s'appliquera au cluster et au namespace répertorié dans le contexte dev-frontend. Et la commande utilisera les informations d'identification de l'utilisateur répertoriées dans le contexte dev-frontend.

Pour voir uniquement les informations de configuration associées au contexte actuel, utilisez l'indicateur --minify.

kubectl config --kubeconfig=config-demo view --minify

La sortie affiche les informations de configuration associées au contexte dev-frontend:

apiVersion: v1
clusters:
- cluster:
    certificate-authority: fake-ca-file
    server: https://1.2.3.4
  name: development
contexts:
- context:
    cluster: development
    namespace: frontend
    user: developer
  name: dev-frontend
current-context: dev-frontend
kind: Config
preferences: {}
users:
- name: developer
  user:
    client-certificate: fake-cert-file
    client-key: fake-key-file

Supposons maintenant que vous souhaitiez travailler pendant un certain temps dans le cluster scratch.

Changez le contexte actuel en exp-scratch:

kubectl config --kubeconfig=config-demo use-context exp-scratch

Maintenant, toute commande kubectl que vous donnez s'appliquera au namespace par défaut du cluster scratch. Et la commande utilisera les informations d'identification de l'utilisateur répertoriées dans le contexte exp-scratch.

Afficher la configuration associée au nouveau contexte actuel, exp-scratch.

kubectl config --kubeconfig=config-demo view --minify

Enfin, supposons que vous vouliez travailler pendant un certain temps dans le namespace storage du cluster development.

Changez le contexte actuel en dev-storage:

kubectl config --kubeconfig=config-demo use-context dev-storage

Afficher la configuration associée au nouveau contexte actuel, dev-storage.

kubectl config --kubeconfig=config-demo view --minify

Créer un deuxième fichier de configuration

Dans votre répertoire config-exercice, créez un fichier nommé config-demo-2 avec ce contenu:

apiVersion: v1
kind: Config
preferences: {}

contexts:
- context:
    cluster: development
    namespace: ramp
    user: developer
  name: dev-ramp-up

Le fichier de configuration précédent définit un nouveau contexte nommé dev-ramp-up.

Définissez la variable d'environnement KUBECONFIG

Vérifiez si vous avez une variable d'environnement nommée KUBECONFIG. Si tel est le cas, enregistrez la valeur actuelle de votre variable d'environnement KUBECONFIG, afin de pouvoir la restaurer ultérieurement. Par exemple:

Linux

export KUBECONFIG_SAVED=$KUBECONFIG

Windows PowerShell

$Env:KUBECONFIG_SAVED=$ENV:KUBECONFIG

La variable d'environnement KUBECONFIG est une liste de chemins vers les fichiers de configuration. La liste est délimitée par deux-points pour Linux et Mac et par des points-virgules pour Windows. Si vous avez une variable d'environnement KUBECONFIG, familiarisez-vous avec les fichiers de configuration de la liste.

Ajoutez temporairement deux chemins à votre variable d'environnement KUBECONFIG. Par exemple:

Linux

export KUBECONFIG=$KUBECONFIG:config-demo:config-demo-2

Windows PowerShell

$Env:KUBECONFIG=("config-demo;config-demo-2")

Dans votre répertoire config-exercice, entrez cette commande:

kubectl config view

La sortie affiche les informations fusionnées de tous les fichiers répertoriés dans votre variable d'environnement KUBECONFIG. En particulier, notez que les informations fusionnées ont le contexte dev-ramp-up du fichier config-demo-2 et les trois contextes du fichier config-demo:

contexts:
- context:
    cluster: development
    namespace: frontend
    user: developer
  name: dev-frontend
- context:
    cluster: development
    namespace: ramp
    user: developer
  name: dev-ramp-up
- context:
    cluster: development
    namespace: storage
    user: developer
  name: dev-storage
- context:
    cluster: scratch
    namespace: default
    user: experimenter
  name: exp-scratch

Pour plus d'informations sur la manière dont les fichiers kubeconfig sont fusionnés, consultez Organisation de l'accès au cluster à l'aide des fichiers kubeconfig

Explorez le répertoire $HOME/.kube

Si vous avez déjà un cluster, et vous pouvez utiliser kubectl pour interagir avec le cluster, alors vous avez probablement un fichier nommé config dans le repertoire $HOME/.kube.

Allez dans $ HOME/.kube, et voyez quels fichiers sont là. En règle générale, il existe un fichier nommé config. Il peut également y avoir d'autres fichiers de configuration dans ce répertoire. Familiarisez-vous brièvement avec le contenu de ces fichiers.

Ajoutez $HOME/.kube/config à votre variable d'environnement KUBECONFIG

Si vous avez un fichier $ HOME/.kube/config, et qu'il n'est pas déjà répertorié dans votre variable d'environnement KUBECONFIG, ajoutez-le maintenant à votre variable d'environnement KUBECONFIG. Par exemple:

Linux

export KUBECONFIG=$KUBECONFIG:$HOME/.kube/config

Windows Powershell

$Env:KUBECONFIG="$Env:KUBECONFIG;$HOME\.kube\config"

Affichez les informations de configuration fusionnées à partir de tous les fichiers qui sont maintenant répertoriés dans votre variable d'environnement KUBECONFIG. Dans votre répertoire config-exercice, entrez:

kubectl config view

Nettoyage

Remettez votre variable d'environnement KUBECONFIG à sa valeur d'origine.

Par exemple:

Linux

export KUBECONFIG=$KUBECONFIG_SAVED

Windows PowerShell

$Env:KUBECONFIG=$ENV:KUBECONFIG_SAVED

A suivre

8.3 - Lister toutes les images de conteneur exécutées dans un cluster

Cette page montre comment utiliser kubectl pour répertorier toutes les images de conteneur pour les pods s'exécutant dans un cluster.

Pré-requis

Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:

Pour consulter la version, 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

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 - Monitoring, Logging et Debugging

9.1 - Obtenez un shell dans un conteneur en cours d'exécution

Cette page montre comment utiliser kubectl exec pour obtenir un shell dans un conteneur en cours d'exécution.

Pré-requis

Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:

Pour consulter la version, 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

Dans votre shell, listez le répertoire racine:

root@shell-demo:/# ls /

Dans votre shell, testez d'autres commandes. Voici quelques exemples:

root@shell-demo:/# ls /
root@shell-demo:/# cat /proc/mounts
root@shell-demo:/# cat /proc/1/maps
root@shell-demo:/# apt-get update
root@shell-demo:/# apt-get install -y tcpdump
root@shell-demo:/# tcpdump
root@shell-demo:/# apt-get install -y lsof
root@shell-demo:/# lsof
root@shell-demo:/# apt-get install -y procps
root@shell-demo:/# ps aux
root@shell-demo:/# ps aux | grep nginx

Écriture de la page racine de nginx

Regardez à nouveau le fichier de configuration de votre Pod. Le pod a un volume emptyDir et le conteneur monte le volume dans /usr/share/nginx/html.

Dans votre shell, créez un fichier index.html dans le répertoire /usr/share/nginx/html:

root@shell-demo:/# echo Hello shell demo > /usr/share/nginx/html/index.html

Dans votre shell, envoyez une requête GET au serveur nginx:

root@shell-demo:/# apt-get update
root@shell-demo:/# apt-get install curl
root@shell-demo:/# curl localhost

La sortie affiche le texte que vous avez écrit dans le fichier index.html:

Hello shell demo

Lorsque vous avez terminé avec votre shell, entrez exit.

Exécution de commandes individuelles dans un conteneur

Dans une fenêtre de commande ordinaire, pas votre shell, répertoriez les variables d'environnement dans le conteneur en cours d'exécution:

kubectl exec shell-demo env

Essayez d'exécuter d'autres commandes. Voici quelques exemples:

kubectl exec shell-demo ps aux
kubectl exec shell-demo ls /
kubectl exec shell-demo cat /proc/1/mounts

Ouverture d'un shell lorsqu'un pod possède plusieurs conteneurs

Si un pod a plusieurs conteneurs, utilisez --container ou -c pour spécifier un conteneur dans la commande kubectl exec. Par exemple, supposons que vous ayez un pod nommé my-pod et que le pod ait deux conteneurs nommés main-app et helper-app. La commande suivante ouvrirait un shell sur le conteneur de l'application principale.

kubectl exec -it my-pod --container main-app -- /bin/bash

A suivre

10 - Extensions de Kubernetes

10.1 - Utilisation des ressources personnalisées

11 - TLS

12 - Fédération

12.1 - Administration du Control Plane de la fédération

13 - Gestion des démons du cluster

14 - Installation du catalogue de services