Construire et exécuter une image d'application locale

DockerBeginner
Pratiquer maintenant

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.