Notes sur Katacoda relatives à l'orchestrateur de conteneur Kubernetes
By WORMS David
14 déc. 2017
- Catégories
- Orchestration de conteneurs
- Formation
- Tags
- Helm
- Ingress
- Kubeadm
- CNI
- Micro Services
- Minikube
- Kubernetes [plus][moins]
Ne ratez pas nos articles sur l'open source, le big data et les systèmes distribués, fréquence faible d’un email tous les deux mois.
Il y a quelques semaines, j’ai consacré deux jours pour suivre les cours relatifs à la solution d’orchestration de *container Kubernetes mis à disposition sur la plateforme Katacoda. Je partage ces notes qui, à l’usage, me servent de pense bête.
Si vous ne connaissez pas ou si vous n’avez pas eu le temps d’essayer Katacoda, et si vous avez un intérêt pour Kubernetes, Docker ou n’importe lequel des cours offerts, vous serez surpris par comment Katacode rend simple, rapide et efficace l’appropriation de nouveaux savoirs sur un large choix de technologies. En complément des cours, ils offrent des bacs à sable, appelés playgrounds, contenant une installation de CoreOS, DC/OS et Kubernetes. En moins de temps qu’il ne faut pour le prononcer, vous serez devant une invite de commande prêt à lancer des commandes pour tester ces technologies.
Lancement d’un cluster composé d’un noeud unique
Apprendre comment lancer un cluster d’un noeud avec Minikube installé en incluant les DNS et Kube UI
L’installation implique :
- un hyperviser, ici VirtualBox
- kubectl
- minikube
Minikube s’exécute sur un noeud unique Kubernetes isolé à l’intérieur d’une VM sur votre poste :
minikube version
minikube start
À ce stade, Kubernetes est disponible :
kubectl cluster-info
kubectl get nodes
Démarrer un conteneur est similaire à la commande Docker :
kubectl run first-deployment --image=katacoda/docker-http-server --port=80
Kubernetes gère nativement le routage TCP / HTTP :
kubectl expose deployment first-deployment --port=80 --type=NodePort
Comme avec Docker, pour obtenir des informations sur un conteneur telle que la valeur PORT, utilisez lesgo templates :
service=first-deployment
export PORT=$(kubectl get svc ${service} -o go-template='{{range.spec.ports}}{{if .nodePort}}{{.nodePort}}{{"\n"}}{{end}}{{end}}')
curl host01:$PORT
Le tableau de bord Kubernetes est disponible sur le port 8080.
Lancement d’un cluster multi noeud avec Kubeadm
Initialiser un cluster Kubernetes avec Kubeadm
Kubeadm gère la configuration du chiffrement TLS, déploie les composants principaux de Kubernetes et s’assure que d’autres nœuds peuvent facilement rejoindre le cluster.
Vous trouverez ici une description détaillée de l’architecture de Kubernetes.
Pour initialiser le cluster :
# From master
kubeadm init
kubeadm token list
# From the node (previously called minion), get stdout
kubeadm join --token=102952.1a7dd4cc8d1f4cc5 172.17.0.9:6443
Pour configurer et connecter le client :
# Copy et export configuration
sudo cp /etc/kubernetes/admin.conf $HOME/
sudo chown $(id -u):$(id -g) $HOME/admin.conf
export KUBECONFIG=$HOME/admin.conf
# Contact the server
kubectl get nodes
Une alternative consiste à exporter une variable d’environnement pointant sur l’adresse du Kubernetes master :
export KUBERNETES_MASTER=HTTP://${k8s_host}:${k8s_port}
Le standard CNI ou Container Network Interface définit la manière dont les différents nœuds et leurs charges de travail doivent communiquer.
Une liste de fournisseurs de réseau implémentant CNI est disponible ici.
Installation de Weave Net :
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
# Show Weave Net pods
kubectl get pod -n kube-system
# Or
kubectl get pod --all-namespaces
Déploiement d’un pod :
kubectl run http --image=katacoda/docker-http-server:latest --replicas=1
# Show the pod
kubectl get pods
docker ps | grep docker-http-server
Installation du tableau de bord web pour piloter Kubernetes :
kubectl apply -f dashboard.yaml
kubectl get pods -n kube-system
kubectl get svc -n kybe-system kubernetes-dashboard
curl {host}:{ip}
Deploiement d’une application web d’exemple
Comment déployer un serveur web d’exemple avec Kubernetes
Cette installation manipule des déclarations de type Pods, Replication Controllers, Services, NodePorts en installant Redis avec un maître pour le stockage et un ensemble répliqué d’esclaves Redis.
Le script de lancement installe ce qui suit :
- etcd avec l’image Docker ”grc.io/google_container/etcd”
- API service avec l’image Docker image ”grc.io/google_container/hypercube” et la commande
/hypercube apiserver
- Kubelet agent avec l’image Docker ”grc.io/google_container/hypercube” et la commande
/hypercube kubelet
- Kubernetes server avec kubectl cluster-info
- Proxy service avec l’image Docker ”grc.io/google_container/hypercube” et la commande
/hypercube proxy
- DNS discovery
Le Kubelet est l’agent primaire qui s’exécute sur chaque noeud. Le programme Kurnetes est directement téléchargé depuis Internet (curl suivi chmod u + x)
Le proxy réseau Kubernetes s’exécute sur chaque noeud et est utilisé pour atteindre les services. Il fait TCP, UDP stream forwarding ou round robin TCP, le transfert UDP à travers un ensemble de backends.
La résolution DNS est un service intégré. Kubernetes DNS planifie un Pod et un service DNS sur le cluster et configure les kubelets pour indiquer aux conteneurs individuels d’utiliser l’adresse IP du service DNS pour résoudre les noms DNS.
Pour activer la découverte DNS :
kubectl -s http://host01:8080 create -f ~/kube-system.json
kubectl -s http://host01:8080 create -f ~/skydns-rc.json
kubectl -s http://host01:8080 create -f ~/skydns-svc.json
Une fois installé, l’environnement client est disponible :
export KUBERNETES_MASTER=http://host01:8080
kubectl cluster-info
Le déploiement du service Kubernetes possède à minima deux définitions :
- contrôleur de réplication (RC - replication controller) : s’assure qu’un pod ou un ensemble homogène de pods est toujours actif et disponible. Il définit le nombre d’instances à exécuter, l’image Docker à utiliser et un nom permettant d’identifier le service.
- service : définit un ensemble logique de Pods et une politique par laquelle y accéder - parfois appelé un micro-service.
La définition RC connecte les esclaves Redis à son agent en utilisant GET_HOSTS_FROM
avec la valeur dns
pour rechercher les informations d’hôtes de service à partir de DNS lors de l’exécution.
Le service défini comme NodePort
provisionne des ports connus et partagés sur l’ensemble du cluster. C’est comme -p 80:80
dans Docker.
Pour trouver le NodePort
affecté en utilisant kubectl
:
kubectl describe service frontend | grep NodePort
Lancement de Conteneurs avec Kubectl
Utiliser Kubectl pour démarrer des conteneurs et les rendre accessible
Kubectl permet d’enregistrer et de lancer des définitions de type Deployments, Replication Controllers et de les exposer en tant que définition de type Services sans avoir à écrire de définition en YAML.
Un contrôleur de déploiement est un objet Kubernetes qui fournit des mises à jour déclaratives pour Pods et ReplicaSets.
Sa définition décrit un état souhaité dans un objet Déploiement et le contrôleur applique la transition de l’état actuel à l’état souhaité à un rythme qu’il contrôle. Les déploiements sont utilisés pour créer de nouveaux ReplicaSets ou pour supprimer des déploiements existants et adopter toutes leurs ressources avec de nouveaux déploiements.
L’exécution de Kubectl est similaire à l’exécution de Docker mais au niveau du cluster et permet de créer un déploiement.
Afficher l’état des déploiements :
kubectl get deployments
Décrire le processus de déploiement (éventuellement avec le nom de la capsule à la fin) :
kubectl describe deployment
Exposer un port depuis l’IP externe de l’hôte :
kubectl expose deployment http --external-ip="172.17.0.9" --port=8000 --target-port=80
Cette dernière commande crée un service exposant le port 8000
:
kubectl get svc
Lorsque vous utilisez le Docker avec l’option hostport, le pod n’est pas un service et est exposé via un mappage de port Docker.Avec Docker ls, on voit que ce n’est pas le container qui expose les ports mais le pod. Les autres conteneurs du pod partagent le même espace de noms de réseau. Cela améliore les performances du réseau et permet à plusieurs conteneurs de communiquer sur la même interface réseau.
kubectl run ${name} --image=${image} --replicas=1 --port=80 --hostport=8001
# Pod is not a service
kubectl get svc
# Show the container and its associated pod
docker ls | grep ${name}
Changer l’échelle du nombre de pods en cours d’exécution pour un déploiement ou un contrôleur de réplication particulier :
kubectl scale --replicas=3 deployment http
Déployer des conteneurs à l’aide de YAML
Découvrir comment utiliser les définitions YAML pour déployer des conteneurs
Les définitions YAML définissent les objets Kubernetes planifiés pour le déploiement. Les objets peuvent être mis à jour et redéployés dans le cluster pour modifier la configuration.
Une définition de service correspond à des applications utilisant des étiquettes (“label” en anglais) :
# Note, only the most relevant lines are displayed
sed -n '2,2p;4,10p' deployment.yaml
# kind: Deployment
# spec:
# replicas: 1
# template:
# metadata:
# labels:
# app: webapp1
sed -n '2,6p;7p;12,13p' service.yaml
# kind: Service
# metadata:
# name: webapp1-svc
# labels:
# app: webapp1
# spec:
# selector:
# app: webapp1
Les capacités de mise en réseau sont contrôlées via la définition du service avec nodePort
:
# Note, only the most relevant lines are displayed
sed -n '2,2p;7,11p' service.yaml
# kind: Service
# spec:
# type: NodePort
# ports:
# - port: 80
# nodePort: 30080
Utilisez kubectl apply
pour refléter les modifications apportées à un fichier de définition :
# eg, update number of replica
kubectl apply -f deployment.yaml
# eg, update the exposed port with nodePort
kubectl apply -f service.yaml
Creation de routes Ingress
Définir le routage Ingress basé sur l’hôte et le chemin
Ingress contrôle les connexions entrantes au cluster, permettant au trafic externe d’atteindre le Pod souhaité.Les fonctionnalités permettent d’accéder à des URL externes, de gérer le trafic de balancement de la charge, d’activer SSL, d’offrir un hébergement virtuel basé sur le nom …
Ingress est synonyme de connexions entrantes, tandis que egress correspond aux connexions sortantes.Kubernetes, dans sa dernière version, prend en charge les stratégies pour les deux types.
Les règles d’entrée peuvent être basées sur un hôte (domaine), ou le chemin de la requête, ou une combinaison des deux.
Pour déployer les types d’objet ingress :
kubectl create -f ingress-rules.yaml
Pour visualiser toutes les règles Ingress :
kubectl get ing
Je viens d’apprendre une nouvelle astuce avec HTTP et curl utile pour les tests. Au lieu de créer une nouvelle entrée dans “/etc/hosts” pour simuler un nom d’hôte HTTP, passez l’en-tête “Host” :
# Instead of
echo '127.0.0.1 adaltas.com' >> /etc/hosts
curl adaltas.com/en/home/
# Do
curl -H 'Host: adaltas.com' 127.0.0.1/en/home/
Utiliser Kubernetes pour la gestion de Secrets et de mots de passe
Conserver vos secrets en toute sécurité
Kubernetes vous permet de créer des secrets qui sont montés dans un pod via des variables d’environnement ou un volume. Cela permet aux secrets, tels que les certificats SSL ou les mots de passe, d’être gérés de manière sécurisée par une équipe d’infrastructure au lieu d’avoir les mots de passe stockés dans les artefacts de déploiement de l’application.
Les secrets sont créés en tant qu’objets Kubernetes.
Voici à quoi ils ressemblent :
apiVersion: v1
kind: Secret
metadata:
name: test-secret
type: Opaque
data:
username: $username
password: $password
Créer et visualiser des secrets :
kubectl create -f secret.yaml
kubectl get secrets
Si vous utilisez docker ps
et que vous vous demandez quels sont les conteneurs de pause, voici comment Eric Paris les décrit :
Le conteneur de pause est un conteneur qui contient l’espace de noms du réseau pour le pod. Cela ne fait rien d’utile. (C’est en fait juste un peu d’assemblage qui s’endort et ne se réveille jamais)
Cela signifie que votre conteneur ‘apache’ peut mourir, et revenir à la vie, et toute la configuration du réseau sera toujours là. Normalement, si le dernier processus dans un espace de noms réseau meurt, l’espace de noms serait détruit et la création d’un nouveau conteneur Apache nécessiterait la création de toute nouvelle configuration réseau. Avec pause, vous aurez toujours cette dernière chose dans l’espace de noms.
Un pod dont les variables d’environnement sont remplies comprend quelque chose comme :
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: test-secret
key: username
kubectl exec
est conçu sur l’exemple de docker exec
.
Pour afficher les variables environnementales peuplées :
kubectl exec -it ${pod_name} env | grep SECRET_
Pour monter le fichier secret, créez le pod avec un volume et montez-le :
# Note, only the most relevant lines are displayed
# sed -n "2p;5,9p;10p;14,17p" pod.yaml
# kind: Pod
# spec:
# volumes:
# - name: secret-volume
# secret:
# secretName: test-secret
# container:
# volumeMounts:
# - name: secret-volume
# mountPath: /etc/secret-volume
Attention, les autorisations doivent être correctement appliquées, la valeur par défaut est ‘444’.
Bilans de santé Liveness et Readiness
Assurer la santé des conteneurs en utilisant des sondes Liveness et Readiness
La sonde Readiness Probes vérifie si une application est prête à commencer le traitement du trafic. Cette sonde résout le problème au démarrage d’un conteneur, quand le processus continue de se préparer et de se configurer, ce qui signifie qu’il n’est pas prêt à recevoir du trafic.
Les sondes Liveness Probes garantissent que l’application est saine et capable de traiter les demandes.
Déploiement de vos sources jusqu’à Kubernetes
Partir du code source jusqu’au lancement de services dans Kubernetes
La propriété .spec.revisionHistoryLimit
spécifie le nombre d’anciens ReplicaSets à conserver pour permettre un rollback.
La propriété imagePullPolicy
accepte comme valeur “Always” (default), “Never” ou “IfNotPresent”.
La propriété dnsPolicy
accepte comme valeur ClusterFirst
(default), ClusterFirstWithHostNet
ou Default
.
Un registre de conteneur est un service central qui héberge des images.
Pour insérer un conteneur local dans un registre de conteneur personnalisé :
# Build an image
cat Dockerfile
docker build -t hello-webapp:v1 .
# Create a tag for the Docker image that contains the Docker repository name
docker tag hello-webapp:v1 $REGISTRY/hello-webapp:v1
# Push the Docker image to the registry
docker push $REGISTRY/hello-webapp:v1
Le registre peut être référencé dans le nom de l’image Docker lors de la définition d’un déploiement :
- image: my_registry_server/my_image:my_tag
Kubernetes kubectl
lit automatiquement ”~ / .kube / config”.
Forge automatise le déploiement de services dans Kubernetes et effectue les opérations suivantes :
- Construire le Dockerfile
- Pousser l’image dans un registre
- Définition du déploiement
- Déployer le conteneur dans Kubernetes
Le gestionnaire de packages/pods Helm
Utilisation du gestionnaire de paquets Helm pour déployer Redis dans Kubernetes
Helm est le gestionnaire de paquets pour Kubernetes.Les packages sont appelés charts (diagrammes) et sont constitués de ressources Kubernetes préconfigurées.
Helm a deux parties : un client (helm) et un serveur (tiller) ; Tiller s’exécute à l’intérieur de votre cluster Kubernetes et gère les versions (installations) de vos charts.
Pour installer Helm :
# Manually
curl -LO https://storage.googleapis.com/kubernetes-helm/helm-v2.6.1-linux-amd64.tar.gz
tar -xvf helm-v2.6.1-linux-amd64.tar.gz
mv linux-amd64/helm /usr/local/bin/
# On Arch
yaourt -S kubernetes-helm
# Init
helm init
helm repo update
Pour récupérer des informations sur des packages :
# Find charts
helm search {package}
# Get chart information
helm inspect {chart}
Monocular est une interface Web permettant de gérer les applications Kubernetes sous forme de charts Helm.