Introduction
Les exercices de déploiement précédents utilisaient des images qui existaient déjà dans un registre ou dans le cache du cluster. Les développeurs d'applications doivent également comprendre le flux de travail des images locales : construire une image à partir de fichiers d'application, rendre cette image disponible sur le nœud Kubernetes et configurer un déploiement pour l'utiliser.
Dans ce laboratoire, vous allez construire localement une petite image d'application web avec Minikube, la déployer avec imagePullPolicy: Never, puis reconstruire l'application sous une seconde balise d'image pour effectuer une mise à jour progressive (rolling update). Cela reflète une tâche courante de type CKAD : connecter l'artefact de l'application à la charge de travail Kubernetes qui l'exécute.
Préparer un espace de travail pour l'image locale
Dans cette étape, vous allez préparer un espace de noms (namespace) propre et confirmer que le chemin de construction de l'image est disponible.
Commencez dans /home/labex/project. Vous créerez les fichiers de l'application, les fichiers de construction d'image et les manifestes Kubernetes dans ce répertoire.
mkdir -p /home/labex/project
cd /home/labex/project
Vérifiez que le serveur API Kubernetes est accessible. Si la machine virtuelle vient de démarrer et que le nœud n'est pas encore prêt, attendez quelques secondes et relancez la commande.
kubectl get nodes --request-timeout=5s
La sortie attendue inclut :
NAME STATUS ROLES AGE VERSION
labex-v135 Ready control-plane ... v1.35...
Attendez que le Pod réseau du cluster soit prêt (Ready). L'application sera testée via un Service, le réseau doit donc être opérationnel.
kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s
Sortie attendue :
pod/calico-node-... condition met
Créez un espace de noms nommé ckad-prep-local-image et définissez-le comme espace de noms actuel :
kubectl create namespace ckad-prep-local-image
kubectl config set-context --current --namespace=ckad-prep-local-image
Confirmez l'espace de noms et vérifiez la commande d'image Minikube. La commande minikube image build construit une image directement pour le profil Minikube, afin que les Pods puissent l'utiliser sans avoir besoin de la pousser vers un registre.
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
minikube image build --help | sed -n '1,4p'
La sortie attendue inclut :
ckad-prep-local-image
Build a container image...
Construire la première image locale
Dans cette étape, vous allez créer une petite application web et la construire sous le nom local-message-app:v1.
L'image utilisera httpd de BusyBox pour servir un fichier statique. Le contenu du fichier représente la version visible de l'application, ce qui vous permettra de vérifier ultérieurement quelle balise d'image est en cours d'exécution dans Kubernetes.
Créez le répertoire de l'application et la première page web :
mkdir -p local-message-app/www
cat > local-message-app/www/index.html <<'EOF'
local-image-v1
EOF
Créez un Dockerfile. L'instruction COPY place votre fichier local www/index.html dans l'image, et CMD démarre le serveur web BusyBox sur le port 8080 lorsqu'un conteneur est lancé à partir de cette image.
cat > local-message-app/Dockerfile <<'EOF'
FROM busybox:1.36
COPY www/index.html /www/index.html
EXPOSE 8080
CMD ["httpd", "-f", "-p", "8080", "-h", "/www"]
EOF
Construisez l'image pour le profil Minikube actif. L'option -t donne une balise locale à l'image, et le chemin final correspond au répertoire de contexte de construction.
minikube image build --profile labex-v135 -t local-message-app:v1 ./local-message-app
La sortie attendue inclut :
naming to docker.io/library/local-message-app:v1 done
Listez les images connues de Minikube et recherchez votre nouvelle balise :
minikube image ls --profile labex-v135 | grep local-message-app
Sortie attendue :
docker.io/library/local-message-app:v1
Déployer l'image locale
Dans cette étape, vous allez exécuter l'image locale dans Kubernetes.
Comme local-message-app:v1 n'est pas poussée vers un registre distant, le déploiement utilise imagePullPolicy: Never. Cela indique au kubelet d'utiliser une image qui existe déjà sur le nœud au lieu d'essayer de la récupérer depuis le réseau.
Créez local-image-app.yaml :
cat > local-image-app.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: local-message-app
spec:
replicas: 2
selector:
matchLabels:
app: local-message-app
template:
metadata:
labels:
app: local-message-app
spec:
terminationGracePeriodSeconds: 0
containers:
- name: web
image: local-message-app:v1
imagePullPolicy: Never
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 1
periodSeconds: 2
---
apiVersion: v1
kind: Service
metadata:
name: local-message-app
spec:
selector:
app: local-message-app
ports:
- port: 80
targetPort: 8080
EOF
Appliquez le manifeste et attendez le déploiement :
kubectl apply -f local-image-app.yaml
kubectl rollout status deployment/local-message-app --timeout=120s
La sortie attendue inclut :
deployment.apps/local-message-app created
service/local-message-app created
deployment "local-message-app" successfully rolled out
Créez un Pod client et testez le Service :
kubectl run image-client --image=busybox:1.36 --restart=Never --command -- sleep 3600
kubectl wait --for=condition=Ready pod/image-client --timeout=120s
kubectl exec image-client -- wget -qO- http://local-message-app
Sortie attendue :
local-image-v1
Reconstruire et déployer une nouvelle image locale
Dans cette étape, vous allez reconstruire l'application sous une seconde balise d'image et mettre à jour le déploiement vers cette balise.
Modifier un fichier sur le disque ne modifie pas une image en cours d'exécution. Vous devez construire une nouvelle balise d'image et mettre à jour le déploiement pour que Kubernetes démarre de nouveaux Pods à partir de cette balise. Cela permet de rendre le changement de version visible et d'éviter de dépendre de contenus d'images locales mutables.
Remplacez le contenu de la page web par la version deux :
cat > local-message-app/www/index.html <<'EOF'
local-image-v2
EOF
Construisez la seconde balise d'image :
minikube image build --profile labex-v135 -t local-message-app:v2 ./local-message-app
La sortie attendue inclut :
naming to docker.io/library/local-message-app:v2 done
Mettez à jour l'image du déploiement et attendez le déploiement progressif :
kubectl set image deployment/local-message-app web=local-message-app:v2
kubectl rollout status deployment/local-message-app --timeout=120s
La sortie attendue inclut :
deployment.apps/local-message-app image updated
deployment "local-message-app" successfully rolled out
Confirmez à la fois la balise de l'image et la réponse de l'application :
kubectl get deployment local-message-app -o jsonpath='{.spec.template.spec.containers[0].image}'; echo
kubectl exec image-client -- wget -qO- http://local-message-app
Sortie attendue :
local-message-app:v2
local-image-v2
Résumé
Vous avez construit une petite image d'application pour le profil Minikube, l'avez déployée avec imagePullPolicy: Never, l'avez testée via un Service Kubernetes, puis avez reconstruit l'application sous une nouvelle balise d'image et mis à jour le déploiement. Le flux de travail clé consiste à rendre l'image disponible sur le nœud avant de demander aux Pods de l'exécuter.



