# 🇫🇷 Kit de survie Kubernetes pour les développeurs avec K3S - Partie 3: Automatiser le déploiement
Il est 5h du matin, avant de prendre la route pour les montagnes enneigées, je vais essayer d'écrire cette partie 3, qui va juste consister en trouver un moyen de nous simplifier la vie pour les déploiements de notre application (cela nous aidera pour les chapitres suivants).
👋 mais avant de commencer, chez fait quelques modifications dans les articles précédents suite à des remarques pertinentes de Louis Tournayre (opens new window)
# Addenda (🐛 fix) aux articles précédents
Dans l'article sur comment créer son cluster (opens new window), j'ai changé le script de création:
multipass launch -n ${node1_name} --cpus 2 --mem 2G
multipass launch -n ${node2_name} --cpus 2 --mem 2G
multipass launch -n ${node3_name} --cpus 2 --mem 2G
- j'ai diminué la taille des nodes en cpu et en mémoire et j'ai mis les même valeurs aussi pour chacune des nodes (je pense que l'on peut faire moins, tout dépend de ce que vous allez déployez et de la puissance de votre machine)
- par contre 😢 il va falloir supprimer votre cluster et le re-créer (une future version de multipass devrait permettre de le faire dynamiquement)
Dans l'article sur le déploiement (opens new window):
- j'ai précisé que quand j'utilise
k33g
dansk33g/amazing-img:0.0.0
,k33g
c'est mon user sur le Docker Hub- et aussi que j'utilise un projet publique sur Docker Hub (pour pas avoir à gérer la notion de credentials dans le cluster)
Voilà, ça c'est fait. On peut passer à la suite. Mais avant "d'outiller" notre déploiement, nous allons procéder à quelques améliorations.
# Un peu de rangement: utilisons des namespaces
Un namespace Kubernetes, c'est comme un "cluster virtuel" au sein de votre cluster "physique". C'est un moyen de "rangement" de vos pods par projets par exemple (mais ça peut être par équipes, ou tout autre chose)
Pour cela, nous allons tout d'abord supprimer l'application que nous avons déployée, de la manière suivante:
cd amazing-web-app
export KUBECONFIG=../create-cluster/k3s.yaml # n'oubliez pas de préciser où est le fichier de conf de votre cluster
kubectl delete -f ./kube/deploy.yaml
Ensuite, nous allons créer le namespace training
:
kubectl create namespace training
Et maintenant, allons modifier notre fichier ./kube/deploy.yaml
:
il suffit d'ajouter la ligne
namespace: training
dans chacune des rubriquesmetadata
(au nombre de 3) du fichier (donc pour Service, Deployment et Ingress).
Votre nouveau fichier devrait ressembler à ceci:
---
# Service
apiVersion: v1
kind: Service
metadata:
name: amazing-web-app
namespace: training
spec:
selector:
app: amazing-web-app
ports:
- port: 80
targetPort: 8080
---
# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: amazing-web-app
namespace: training
spec:
replicas: 3
selector:
matchLabels:
app: amazing-web-app
template:
metadata:
labels:
app: amazing-web-app
spec:
containers:
- name: amazing-web-app
image: k33g/amazing-img:0.0.1
ports:
- containerPort: 8080
imagePullPolicy: Always
---
# Ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: amazing-web-app
namespace: training
spec:
rules:
- host: amazing-web-app.192.168.64.17.nip.io
http:
paths:
- backend:
serviceName: amazing-web-app
servicePort: 80
Sauvegardez, mais ne déployez pas tout de suite.
# Fixer les ressources de vos pods
Il est aussi possible de fixer la taille mémoire et cpus de vos pod avec ceci (vous pouvez modifier les valeurs):
resources:
limits:
cpu: "1"
memory: "128Mi"
requests:
cpu: "1"
memory: "128Mi"
Vous devez ajouter ceci à la fin de la partie déploiement de votre fichier, dans la rubrique containers
:
---
# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: amazing-web-app
namespace: training
spec:
replicas: 3
selector:
matchLabels:
app: amazing-web-app
template:
metadata:
labels:
app: amazing-web-app
spec:
containers:
- name: amazing-web-app
image: k33g/amazing-img:0.0.1
ports:
- containerPort: 8080
imagePullPolicy: Always
resources:
limits:
cpu: "1"
memory: "128Mi"
requests:
cpu: "1"
memory: "128Mi"
Maintenant vous pouvez redéployer votre application:
export KUBECONFIG=../create-cluster/k3s.yaml
kubectl apply -f ./kube/deploy.yaml
Et vous pouvez voir que vos pods s'exécutent bien dans un nouveau namespace training
Vous trouverez la nouvelle version du fichier
deploy.yaml
par ici: https://gitlab.com/learn-k3s/amazing-web-app/-/blob/second-steps/kube/deploy.yaml (opens new window)
# Amélioration et bonne pratique: remarque d'Aurélie Vache (23/02/2020)
Aurélie Vache (opens new window) me disait sur Twitter: "c'est bien d'éviter de mettre le namespace dans les manifest yaml
, Et du coup le préciser lors de l'apply
avec l'option -n
" et elle ajoutait aussi que cela permettait de déployer le même manifeste dans plusieurs namespaces, cela permet à la CD de piloter la destination.
Donc, je fais une dernière modification de mon fichier yaml
et finalement j'enlève toutes les lignes namespace: training
Et maintenant j'utiliserais plutôt:
export KUBECONFIG=../create-cluster/k3s.yaml
kubectl apply -f ./kube/deploy.yaml -n training
👋 Pub: Aurélie Vache (opens new window) et Kevin Davin (opens new window) ont fait une superbe présentation sur le sujet Docker, Kubernetes & Istio (opens new window)
# Les redéploiements c'est c...
A chaque fois que vous modifiez votre application, il faut reconstruire l'image, incrémenter un tag, ... sauvegarder, etc... Personnellement, je trouve ceci pénible, je vous propose donc de mettre en place un système de template.
je suis preneur de toute solution différente bien sûr 🙂
Nous allons modifier notre fichier deploy.yaml
en utilisant des variables d'environnement, et nous effectuerons les substitutions des valeurs à l'aide de l'utilitaire envsubst
. Normalement sous Ubuntu envsubst
est présent de base, pour les autres linux je ne sais pas, mais ça s'installe facilement; pour OSX, vous pouvez l'installer avec brew install gettext; brew link --force gettext
(envsubst
est présent dans le package gettext
) et pour Windows, je ne saurais que vous conseiller d'utiliser le shell fournit avec l'installation de git (je n'ai pas de poste Windows, donc ami lecteur, si tu es sous Windows, n'hésite pas à me contacter... Ou attendez que je me décide à m'acheter une Surface).
Renommez le fichier ./kube/deploy.yaml
en ./kube/deploy.template.yaml
et changez son contenu avec ceci:
# second steps
---
# Service
apiVersion: v1
kind: Service
metadata:
name: ${APPLICATION_NAME}
spec:
selector:
app: ${APPLICATION_NAME}
ports:
- port: ${EXPOSED_PORT}
targetPort: ${CONTAINER_PORT}
---
# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: ${APPLICATION_NAME}
spec:
replicas: 3
selector:
matchLabels:
app: ${APPLICATION_NAME}
template:
metadata:
labels:
app: ${APPLICATION_NAME}
spec:
containers:
- name: ${APPLICATION_NAME}
image: ${IMAGE}
ports:
- containerPort: ${CONTAINER_PORT}
imagePullPolicy: Always
resources:
limits:
cpu: "1"
memory: "128Mi"
requests:
cpu: "1"
memory: "128Mi"
---
# Ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ${APPLICATION_NAME}
spec:
rules:
- host: ${HOST}
http:
paths:
- backend:
serviceName: ${APPLICATION_NAME}
servicePort: ${EXPOSED_PORT}
Donc par exemple pour déployer, nous pourrions donc faire quelque chose comme ceci:
export CONTAINER_PORT=8080
export EXPOSED_PORT=80
export APPLICATION_NAME="amazing-web-app"
export DOCKER_USER="k33g"
export NAMESPACE="training"
export IMAGE_NAME="amazing-img"
export TAG="0.0.1"
export IMAGE="${DOCKER_USER}/${IMAGE_NAME}:${TAG}"
export HOST="amazing-web-app.192.168.64.17.nip.io"
docker build -t ${IMAGE_NAME} .
docker tag ${IMAGE_NAME} ${IMAGE}
docker push ${IMAGE}
envsubst < ./deploy.template.yaml > ./kube/deploy.${TAG}.yaml
kubectl apply -f ./kube/deploy.${TAG}.yaml -n ${NAMESPACE}
Mais il faut encore gérer le TAG
😕. Mais si vous êtes bien élevé, votre application est dans un repository git (si ce n'est pas le cas faites-le: git init
😉), et:
- si vous tapez
git rev-parse --short HEAD
(dans le répertoire de l'application) vous obtiendrez lecommit SHA
court (quelque chose comme ceciace7f26
) - si vous tapez
git symbolic-ref --short HEAD
vous obtiendrez la branche courante - si vous tapez
basename $(git rev-parse --show-toplevel)
vous obtiendrez le nom de votre projet git
Je vous propose donc de faire ceci:
export CONTAINER_PORT=8080
export EXPOSED_PORT=80
export APPLICATION_NAME=$(basename $(git rev-parse --show-toplevel)) # ✋
export DOCKER_USER="k33g"
export NAMESPACE="training"
export IMAGE_NAME="${APPLICATION_NAME}-img" # ✋
export TAG=$(git rev-parse --short HEAD) # ✋
export IMAGE="${DOCKER_USER}/${IMAGE_NAME}:${TAG}"
export CLUSTER_IP="192.168.64.17" # ✋
export BRANCH=$(git symbolic-ref --short HEAD) # ✋
export HOST="${APPLICATION_NAME}.${BRANCH}.${CLUSTER_IP}.nip.io" # ✋
docker build -t ${IMAGE_NAME} .
docker tag ${IMAGE_NAME} ${IMAGE}
docker push ${IMAGE}
envsubst < ./kube/deploy.template.yaml > ./kube/deploy.${TAG}.yaml
export KUBECONFIG=../create-cluster/k3s.yaml
kubectl apply -f ./kube/deploy.${TAG}.yaml -n ${NAMESPACE}
echo "http://${HOST}"
👋 Remarque au début j'avais variabilisé les réplicas, mais comme me l'a fait justement remarqué Kevin Davin (opens new window), c'est plus simple (et plus élégant) d'utiliser:
kubectl scale deploy name --replicas=2
- Exemple:
kubectl scale --replicas=1 deploy amazing-web-app -n training
Donc modifiez votre code, fait un git add .
puis un git commit -m "🚀 new deployment"
et lancez les commandes ci-dessus.
La nouvelle url de votre webapp devrait ressembler à ceci: http://amazing-web-app.third-steps.192.168.64.17.nip.io (opens new window)
✋ j'utilise la branche, comme ça je peux faire facilement des previews de mes développements
Donc maintenant, il vous suffit de faire un commit et de re-utiliser les même commandes (pensez à supprimer les fichiers de déploiement générés)
✋ vous trouverez la nouvelle version ici: https://gitlab.com/learn-k3s/amazing-web-app/-/blob/third-steps/kube/deploy.template.yaml (opens new window)
# Un dernier pour la route: en faire un plugin kubectl
Il est très facile de créer un plugin pour kubectl
: exemple de création de plugin avec un script shell (opens new window).
Nous allons donc transformer nos commandes précédentes en plugin kubectl
Dans un autre dossier (easy-deploy
par exemple), créez un fichier kubectl-easy.sh
#!/bin/sh
if [[ "$1" == "version" ]]; then
echo "1.0.0"
exit 0
fi
if [[ "$1" == "config" ]]; then
echo "$KUBECONFIG"
exit 0
fi
if [[ "$1" == "deploy" ]]; then
export CONTAINER_PORT=${CONTAINER_PORT:-8080}
export EXPOSED_PORT=${EXPOSED_PORT:-80}
export APPLICATION_NAME=$(basename $(git rev-parse --show-toplevel))
export DOCKER_USER="${DOCKER_USER}"
export NAMESPACE="${NAMESPACE}"
export IMAGE_NAME="${APPLICATION_NAME}-img"
export TAG=$(git rev-parse --short HEAD)
export IMAGE="${DOCKER_USER}/${IMAGE_NAME}:${TAG}"
export CLUSTER_IP="${CLUSTER_IP}"
export BRANCH=$(git symbolic-ref --short HEAD)
export HOST="${APPLICATION_NAME}.${BRANCH}.${CLUSTER_IP}.nip.io"
docker build -t ${IMAGE_NAME} .
docker tag ${IMAGE_NAME} ${IMAGE}
docker push ${IMAGE}
envsubst < ./kube/deploy.template.yaml > ./kube/deploy.${TAG}.yaml
kubectl apply -f ./kube/deploy.${TAG}.yaml -n ${NAMESPACE}
echo "🌍 http://${HOST}"
exit 0
fi
Pour l'installer c'est simple:
sudo chmod +x ./kubectl-easy.sh
cp ./kubectl-easy.sh ./kubectl-easy
sudo mv ./kubectl-easy /usr/local/bin
Et maintenant pour déployer votre webapp c'est encore plus simple:
cd amazing-web-app
git add .
git commit -m "🎉 wow!"
export KUBECONFIG=../create-cluster/k3s.yaml
NAMESPACE="training" \
DOCKER_USER="k33g" \
CLUSTER_IP="192.168.64.17" \
kubectl easy deploy
👋 le code du plugin est ici: https://gitlab.com/learn-k3s/easy-deploy (opens new window)
Et c'est tout pour aujourd'hui 😃. N'hésitez pas à faire des remarques. Je dois aller charger le coffre de la voiture. A bientôt 👋 pour la suite.
Last Articles
- 🇫🇷 Type Result en Kotlin | 2020-10-31 | Kotlin
- 🇫🇷 Type Result en Kotlin | 2020-10-31 | Kotlin
- 🇬🇧 Every GitLab Page deserves a real CI/CD | 2020-07-23 | GitLab CI
- 🇫🇷 Lit-Element, commencer doucement | 2020-07-20 | WebComponent
- 🇬🇧 Build quickly and host easily your Docker images with GitLab and GitLab CI | 2020-06-02 | GitLab CI
- 🇬🇧 Deploy quickly on Clever Cloud with GitLab CI | 2020-05-31 | GitLab CI
- 🇫🇷 Borg Collective, mes jouets pour apprendre Knative | 2020-05-30 | Knative
- 🇬🇧 Borg Collective, Toys to learn Knative | 2020-05-30 | Knative
- 🇫🇷 M5Stack, une petit device IOT bien sympathique, programmable en Python | 2020-05-09 | IOT
- 🇫🇷 Knative, l'outil qui rend Kubernetes sympathique | 2020-05-02 | kubernetes