Installer et automatiser les déploiements RHEL

Red Hat Enterprise LinuxBeginner
Pratiquer maintenant

Introduction

Dans ce laboratoire, vous apprendrez les bases du déploiement et de l'automatisation des conteneurs Red Hat Enterprise Linux (RHEL) 9 en utilisant Docker. Les déploiements modernes cloud-natifs reposent de plus en plus sur des environnements RHEL conteneurisés plutôt que sur des machines virtuelles traditionnelles. Vous commencerez par explorer les Universal Base Images (UBI) de Red Hat, qui fournissent des environnements RHEL de qualité entreprise au format conteneur.

Vous examinerez comment les concepts traditionnels de Kickstart se traduisent en automatisation de conteneurs, créerez des Dockerfiles personnalisés qui reflètent les configurations d'installation, et construirez des scripts de déploiement automatisés. À la fin de ce laboratoire, vous comprendrez comment déployer efficacement des conteneurs RHEL et automatiser le processus pour des déploiements cohérents et reproductibles dans les environnements cloud modernes.

Explorer les Red Hat Universal Base Images (UBI)

Dans cette étape, vous explorerez les Universal Base Images (UBI) de Red Hat, qui sont des images de conteneurs de qualité entreprise basées sur RHEL. Contrairement aux installations RHEL traditionnelles qui nécessitent des machines virtuelles complètes, les images UBI fournissent des environnements RHEL dans des conteneurs légers et portables. Ces images sont librement redistribuables et conçues pour les applications cloud-natives modernes.

Red Hat fournit plusieurs variantes UBI optimisées pour différents cas d'utilisation. L'image redhat/ubi9 fournit un environnement de conteneur complet basé sur RHEL avec le gestionnaire de paquets dnf, ce qui la rend adaptée aux applications nécessitant l'installation de logiciels et l'automatisation du système.

Tout d'abord, examinons le modèle de configuration de conteneur Red Hat qui a été préparé pour ce laboratoire. Ce fichier démontre comment les concepts traditionnels de Kickstart se traduisent en environnements de conteneurs.

sudo cat /etc/labex/rhel-container-config.cfg

Vous verrez une sortie montrant une configuration de style Dockerfile qui reflète les concepts d'installation traditionnels :

## RHEL Container Configuration Template
## Based on traditional Kickstart concepts adapted for containers

## Base image specification
FROM redhat/ubi9

## System locale and timezone
ENV LANG=en_US.UTF-8
ENV TZ=America/New_York

## User configuration
ENV CONTAINER_USER=labex
ENV ROOT_PASSWORD=redhat

## Package installation
## Packages: httpd, curl (container-appropriate equivalents)
RUN dnf install -y --allowerasing httpd curl && \
    dnf clean all

## Service configuration
EXPOSE 80

## Startup command
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

Maintenant, explorons les images UBI Red Hat disponibles. Tout d'abord, vérifiez si Docker est en cours d'exécution et accessible :

docker --version

Tirez l'image Red Hat UBI 9, qui fournit un environnement de conteneur complet basé sur RHEL :

docker pull redhat/ubi9

Vous devriez voir une sortie similaire à :

Using default tag: latest
latest: Pulling from redhat/ubi9
Digest: sha256:...
Status: Downloaded newer image for redhat/ubi9:latest
docker.io/redhat/ubi9:latest

Listez les images téléchargées pour confirmer que le tirage a réussi :

docker images redhat/ubi9

La sortie affichera les détails de l'image :

REPOSITORY      TAG       IMAGE ID       CREATED      SIZE
redhat/ubi9     latest    b1c2d3e4f5g6   5 days ago   216MB

Maintenant, exécutons un conteneur de base pour explorer l'environnement RHEL :

docker run -it --rm redhat/ubi9 /bin/bash

À l'intérieur du conteneur, explorez l'environnement RHEL en vérifiant la version du système d'exploitation :

cat /etc/redhat-release

Vous devriez voir quelque chose comme :

Red Hat Enterprise Linux release 9.6 (Plow)

Vérifiez le gestionnaire de paquets disponible :

dnf --version

Quittez le conteneur en tapant :

exit

Copiez la configuration du modèle dans votre répertoire de projet pour la personnalisation :

sudo cp /etc/labex/rhel-container-config.cfg ~/project/rhel-container.dockerfile
sudo chown labex:labex ~/project/rhel-container.dockerfile

Vérifiez que le fichier a été copié avec succès :

ls -l ~/project/rhel-container.dockerfile

Vous avez maintenant exploré avec succès les images Red Hat UBI et êtes prêt à créer des configurations de conteneurs personnalisées à l'étape suivante.

Créer une Configuration de Conteneur RHEL Personnalisée

Dans cette étape, vous créerez un Dockerfile personnalisé basé sur l'image Red Hat UBI. Ce processus reflète la façon dont vous personnaliseriez un fichier Kickstart pour les installations automatisées, mais adapté aux environnements de conteneurs. Le Dockerfile sert de modèle d'automatisation pour la création de déploiements de conteneurs RHEL cohérents.

Tout d'abord, assurez-vous d'être dans votre répertoire de projet :

cd ~/project

Créez un nouveau Dockerfile plus spécifique pour notre déploiement de conteneur RHEL automatisé :

cp rhel-container.dockerfile rhel9-automated.dockerfile

Vérifiez que les deux fichiers existent :

ls -l *.dockerfile

Vous devriez voir les deux fichiers :

-rw-r--r--. 1 labex labex 423 Jul 22 10:30 rhel-container.dockerfile
-rw-r--r--. 1 labex labex 423 Jul 22 10:35 rhel9-automated.dockerfile

Maintenant, ouvrez le nouveau Dockerfile pour examiner sa structure avant la personnalisation :

nano rhel9-automated.dockerfile

À l'intérieur du fichier, vous verrez l'équivalent conteneur des directives Kickstart :

  • Directive FROM : Spécifie l'image RHEL de base (équivalent au support d'installation)
  • Directives ENV : Définissent les variables d'environnement (équivalent à la configuration du système)
  • Directives RUN : Exécutent des commandes pendant la construction de l'image (équivalent à l'installation de paquets)
  • EXPOSE et CMD : Configurent les services et le démarrage (équivalent à la configuration des services)

Pour l'instant, quittez simplement l'éditeur en appuyant sur Ctrl+X pour passer à l'étape de personnalisation.

Comprendre cette structure vous prépare pour l'étape suivante où vous personnaliserez la configuration du conteneur pour répondre aux exigences spécifiques du déploiement, tout comme vous personnaliseriez un fichier Kickstart pour les installations de VM automatisées.

Personnaliser la Configuration du Conteneur pour un Déploiement Automatisé

Dans cette étape, vous remplacerez le contenu du fichier rhel9-automated.dockerfile par une configuration personnalisée pour le déploiement automatisé de conteneurs RHEL. Ce processus est parallèle à la personnalisation d'un fichier Kickstart, mais utilise l'approche déclarative de Docker pour définir l'environnement et les services du conteneur.

Tout d'abord, assurez-vous d'être dans le répertoire du projet :

cd ~/project

Maintenant, créez le Dockerfile personnalisé complet en remplaçant l'intégralité du contenu de rhel9-automated.dockerfile :

cat > rhel9-automated.dockerfile << 'EOF'
## RHEL 9 Automated Container Deployment
## Based on Red Hat Universal Base Image 9
FROM redhat/ubi9:latest

## Container metadata
LABEL maintainer="LabEx Admin"
LABEL description="Automated RHEL 9 container with web services"
LABEL version="1.0"

## System locale and timezone configuration
ENV LANG=en_US.UTF-8
ENV TZ=America/New_York
ENV CONTAINER_USER=labex
ENV CONTAINER_UID=1001

## Package installation and system configuration
RUN dnf update -y \
  && dnf install -y --allowerasing \
    httpd \
    curl \
    tar \
    gzip \
  && dnf clean all \
  && rm -rf /var/cache/dnf

## Create non-root user for security
RUN useradd -u ${CONTAINER_UID} -m -s /bin/bash ${CONTAINER_USER} \
  && echo "${CONTAINER_USER}:labex" | chpasswd

## Configure Apache for container environment
RUN sed -i 's/Listen 80/Listen 8080/' /etc/httpd/conf/httpd.conf \
  && chown -R ${CONTAINER_USER}:${CONTAINER_USER} /var/log/httpd /var/run/httpd

## Create startup script
RUN echo '#!/bin/bash' > /start.sh \
  && echo 'echo "RHEL Container started on $(date)" > /var/www/html/index.html' >> /start.sh \
  && echo 'echo "<h1>RHEL 9 Container</h1><p>Deployed via automated configuration</p>" >> /var/www/html/index.html' >> /start.sh \
  && echo 'exec /usr/sbin/httpd -D FOREGROUND' >> /start.sh \
  && chmod +x /start.sh

## Switch to non-root user
USER ${CONTAINER_USER}

## Expose port and define startup
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:8080/ || exit 1

CMD ["/start.sh"]
EOF

Examinons maintenant la structure de ce Dockerfile personnalisé et comprenons comment chaque section sert le même objectif que les différentes parties d'une configuration Kickstart :

1. Section Image de base et métadonnées :

## RHEL 9 Automated Container Deployment
## Based on Red Hat Universal Base Image 9
FROM redhat/ubi9:latest

## Container metadata
LABEL maintainer="LabEx Admin"
LABEL description="Automated RHEL 9 container with web services"
LABEL version="1.0"

Cette section équivaut à spécifier le support d'installation et les informations système de base dans un fichier Kickstart. La directive FROM spécifie notre image RHEL de base, tandis que les directives LABEL fournissent des métadonnées sur le conteneur.

2. Configuration de l'environnement :

## System locale and timezone configuration
ENV LANG=en_US.UTF-8
ENV TZ=America/New_York
ENV CONTAINER_USER=labex
ENV CONTAINER_UID=1001

Cela est parallèle aux directives timezone et lang dans les fichiers Kickstart. Nous définissons les paramètres régionaux du système, le fuseau horaire et définissons des variables pour la création d'utilisateurs.

3. Installation des paquets :

## Package installation and system configuration
RUN dnf update -y \
  && dnf install -y --allowerasing \
    httpd \
    curl \
    tar \
    gzip \
  && dnf clean all \
  && rm -rf /var/cache/dnf

Cette section remplit la même fonction que la section %packages dans Kickstart. Nous mettons à jour le système, installons les paquets requis en utilisant --allowerasing pour gérer les conflits et nettoyons les caches de paquets pour réduire la taille de l'image.

4. Configuration de l'utilisateur et de la sécurité :

## Create non-root user for security
RUN useradd -u ${CONTAINER_UID} -m -s /bin/bash ${CONTAINER_USER} \
  && echo "${CONTAINER_USER}:labex" | chpasswd

## Configure Apache for container environment
RUN sed -i 's/Listen 80/Listen 8080/' /etc/httpd/conf/httpd.conf \
  && chown -R ${CONTAINER_USER}:${CONTAINER_USER} /var/log/httpd /var/run/httpd

Cela reflète la directive user et la configuration post-installation dans Kickstart. Nous créons un utilisateur non root pour la sécurité et configurons Apache pour qu'il s'exécute sur le port 8080 (adapté aux environnements de conteneurs).

5. Configuration du démarrage :

## Create startup script
RUN echo '#!/bin/bash' > /start.sh \
  && echo 'echo "RHEL Container started on $(date)" > /var/www/html/index.html' >> /start.sh \
  && echo 'echo "<h1>RHEL 9 Container</h1><p>Deployed via automated configuration</p>" >> /var/www/html/index.html' >> /start.sh \
  && echo 'exec /usr/sbin/httpd -D FOREGROUND' >> /start.sh \
  && chmod +x /start.sh

## Switch to non-root user
USER ${CONTAINER_USER}

## Expose port and define startup
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:8080/ || exit 1

CMD ["/start.sh"]

Cette dernière section équivaut à la section %post et à la configuration des services dans Kickstart. Nous créons un script de démarrage, passons à l'utilisateur non root, exposons le port du service web, définissons des contrôles de santé et spécifions la commande de démarrage du conteneur.

Vérifiez que le nouveau Dockerfile a été créé correctement :

cat rhel9-automated.dockerfile

Vous devriez voir le contenu complet du Dockerfile qui démontre comment les concepts d'automatisation Kickstart traditionnels se traduisent en déploiements RHEL modernes basés sur des conteneurs.

Valider la Configuration du Conteneur et Construire l'Image

Dans cette étape, vous validerez votre Dockerfile personnalisé et construirez l'image du conteneur RHEL. Ce processus est similaire à la validation d'un fichier Kickstart avec ksvalidator, mais utilise la validation intégrée de Docker pendant le processus de construction. Docker vérifiera la syntaxe et tentera d'exécuter chaque instruction, fournissant un retour immédiat sur tout problème.

Tout d'abord, assurez-vous d'être dans le répertoire du projet où se trouve votre Dockerfile :

cd ~/project

Avant de construire, effectuons une vérification de syntaxe de base en examinant la structure du Dockerfile. Docker fournit un moyen de valider la syntaxe de base sans construire :

docker build --no-cache --progress=plain -f rhel9-automated.dockerfile -t rhel9-test:validation . --target ""

Cependant, la validation la plus efficace consiste à réellement construire l'image. S'il y a des erreurs de syntaxe ou des problèmes avec les commandes, Docker les signalera pendant le processus de construction. Notez que nous utilisons l'indicateur --allowerasing avec dnf install pour gérer les conflits de paquets entre curl et curl-minimal qui existent dans l'image UBI9 de base :

docker build -t rhel9-automated:latest -f rhel9-automated.dockerfile .

Vous devriez voir une sortie montrant chaque étape du processus de construction :

[+] Building 45.2s (12/12) FINISHED
 => [internal] load build definition from rhel9-automated.dockerfile
 => => transferring dockerfile: 1.23kB
 => [internal] load .dockerignore
 => => transferring context: 2B
 => [internal] load metadata for docker.io/redhat/ubi9:latest
 => [1/8] FROM docker.io/redhat/ubi9:latest@sha256:...
 => [2/8] RUN dnf update -y &&     dnf install -y --allowerasing         httpd         curl         tar         gzip &&     dnf clean all &&     rm -rf /var/cache/dnf
 => [3/8] RUN useradd -u 1001 -m -s /bin/bash labex &&     echo "labex:labex" | chpasswd
 => [4/8] RUN sed -i 's/Listen 80/Listen 8080/' /etc/httpd/conf/httpd.conf &&     chown -R labex:labex /var/log/httpd /var/run/httpd
 => [5/8] RUN echo '#!/bin/bash' > /start.sh &&     echo 'echo "RHEL Container started on $(date)" > /var/www/html/index.html' >> /start.sh &&     echo 'echo "<h1>RHEL 9 Container</h1><p>Deployed via automated configuration</p>" >> /var/www/html/index.html' >> /start.sh &&     echo 'exec /usr/sbin/httpd -D FOREGROUND' >> /start.sh &&     chmod +x /start.sh
 => [6/8] USER labex
 => exporting to image
 => => exporting layers
 => => writing image sha256:a1b2c3d4e5f6...
 => => naming to docker.io/library/rhel9-automated:latest

Si la construction se termine avec succès, cela signifie que la syntaxe de votre Dockerfile est correcte et que toutes les commandes se sont exécutées correctement. Vous pouvez voir des messages d'avertissement concernant les paramètres régionaux et la gestion des abonnements pendant le processus de construction - ceux-ci sont normaux pour les conteneurs UBI et n'affectent pas la fonctionnalité.

Vérifiez que l'image a été créée :

docker images rhel9-automated

Vous devriez voir votre image nouvellement construite :

REPOSITORY       TAG       IMAGE ID       CREATED          SIZE
rhel9-automated  latest    a1b2c3d4e5f6   2 minutes ago    280MB

Testons maintenant le conteneur pour nous assurer qu'il fonctionne comme prévu. Exécutez le conteneur en mode détaché :

docker run -d --name rhel9-test -p 8080:8080 rhel9-automated:latest

Vérifiez si le conteneur est en cours d'exécution :

docker ps

Vous devriez voir votre conteneur dans la liste :

CONTAINER ID   IMAGE                     COMMAND      CREATED         STATUS         PORTS                    NAMES
a1b2c3d4e5f6   rhel9-automated:latest   "/start.sh"  30 seconds ago  Up 30 seconds  0.0.0.0:8080->8080/tcp   rhel9-test

Testez le service web en effectuant une requête vers le conteneur :

curl http://localhost:8080

Vous devriez voir la sortie HTML de votre conteneur RHEL automatisé :

RHEL Container started on Wed Jul 22 14:30:15 UTC 2024
<h1>RHEL 9 Container</h1><p>Deployed via automated configuration</p>

Enfin, nettoyez en arrêtant et en supprimant le conteneur de test :

docker stop rhel9-test
docker rm rhel9-test

Votre configuration de conteneur RHEL a été validée et testée avec succès, démontrant les capacités de déploiement automatisé.

Créer un Script de Déploiement Automatisé

Dans cette étape, vous créerez un script d'automatisation qui démontre comment déployer des conteneurs RHEL de manière cohérente et répétée. Ce script sert le même objectif que l'utilisation de fichiers Kickstart pour l'automatisation des machines virtuelles, mais est adapté aux déploiements RHEL conteneurisés. Le script gérera la construction d'images, le déploiement de conteneurs et les vérifications de base de l'état de santé.

Tout d'abord, assurez-vous d'être dans votre répertoire de projet :

cd ~/project

Créez un script d'automatisation du déploiement qui imite les capacités d'automatisation que vous obtiendriez avec Kickstart et virt-install :

nano deploy-rhel-container.sh

Ajoutez le contenu suivant pour créer un script de déploiement complet :

#!/bin/bash

## RHEL Container Automated Deployment Script
## This script demonstrates container-based RHEL deployment automation
## Similar to Kickstart automation for VMs, but for containers

set -e ## Exit on any error

## Configuration variables
IMAGE_NAME="rhel9-automated"
IMAGE_TAG="latest"
CONTAINER_NAME="rhel9-production"
HOST_PORT="8080"
CONTAINER_PORT="8080"
DOCKERFILE="rhel9-automated.dockerfile"

## Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' ## No Color

## Function to print colored output
print_status() {
  echo -e "${BLUE}[INFO]${NC} $1"
}

print_success() {
  echo -e "${GREEN}[SUCCESS]${NC} $1"
}

print_warning() {
  echo -e "${YELLOW}[WARNING]${NC} $1"
}

print_error() {
  echo -e "${RED}[ERROR]${NC} $1"
}

## Function to check if Docker is running
check_docker() {
  print_status "Checking Docker availability..."
  if ! docker info > /dev/null 2>&1; then
    print_error "Docker is not running or not accessible"
    exit 1
  fi
  print_success "Docker is available"
}

## Function to build the image
build_image() {
  print_status "Building RHEL container image..."
  if [ ! -f "$DOCKERFILE" ]; then
    print_error "Dockerfile '$DOCKERFILE' not found"
    exit 1
  fi

  docker build -t "${IMAGE_NAME}:${IMAGE_TAG}" -f "$DOCKERFILE" .
  print_success "Image '${IMAGE_NAME}:${IMAGE_TAG}' built successfully"
}

## Function to stop and remove existing container
cleanup_existing() {
  print_status "Checking for existing container..."
  if docker ps -a | grep -q "$CONTAINER_NAME"; then
    print_warning "Stopping and removing existing container '$CONTAINER_NAME'"
    docker stop "$CONTAINER_NAME" > /dev/null 2>&1 || true
    docker rm "$CONTAINER_NAME" > /dev/null 2>&1 || true
  fi
}

## Function to deploy the container
deploy_container() {
  print_status "Deploying RHEL container..."
  docker run -d \
    --name "$CONTAINER_NAME" \
    -p "${HOST_PORT}:${CONTAINER_PORT}" \
    --restart unless-stopped \
    "${IMAGE_NAME}:${IMAGE_TAG}"

  print_success "Container '$CONTAINER_NAME' deployed successfully"
}

## Function to verify deployment
verify_deployment() {
  print_status "Verifying container deployment..."

  ## Wait for container to start
  sleep 5

  ## Check if container is running
  if ! docker ps | grep -q "$CONTAINER_NAME"; then
    print_error "Container is not running"
    docker logs "$CONTAINER_NAME"
    exit 1
  fi

  ## Check if web service is responding
  print_status "Testing web service..."
  for i in {1..10}; do
    if curl -s "http://localhost:${HOST_PORT}" > /dev/null; then
      print_success "Web service is responding"
      break
    fi
    if [ $i -eq 10 ]; then
      print_error "Web service is not responding after 10 attempts"
      exit 1
    fi
    sleep 2
  done
}

## Function to display deployment information
show_deployment_info() {
  print_success "=== RHEL Container Deployment Complete ==="
  echo "Container Name: $CONTAINER_NAME"
  echo "Image: ${IMAGE_NAME}:${IMAGE_TAG}"
  echo "Port Mapping: ${HOST_PORT}:${CONTAINER_PORT}"
  echo "Access URL: http://localhost:${HOST_PORT}"
  echo ""
  print_status "Container Status:"
  docker ps | grep "$CONTAINER_NAME"
  echo ""
  print_status "Sample Content:"
  curl -s "http://localhost:${HOST_PORT}" | head -2
}

## Main deployment process
main() {
  echo "=== RHEL Container Automated Deployment ==="
  echo "This script automates RHEL container deployment"
  echo "Similar to Kickstart automation for traditional installations"
  echo ""

  check_docker
  build_image
  cleanup_existing
  deploy_container
  verify_deployment
  show_deployment_info

  print_success "Automated RHEL container deployment completed successfully!"
}

## Handle script arguments
case "${1:-deploy}" in
  "deploy" | "")
    main
    ;;
  "cleanup")
    print_status "Cleaning up deployment..."
    cleanup_existing
    docker rmi "${IMAGE_NAME}:${IMAGE_TAG}" 2> /dev/null || true
    print_success "Cleanup completed"
    ;;
  "status")
    docker ps | grep "$CONTAINER_NAME" || print_warning "Container not running"
    ;;
  *)
    echo "Usage: $0 [deploy|cleanup|status]"
    echo "  deploy  - Build and deploy RHEL container (default)"
    echo "  cleanup - Stop container and remove image"
    echo "  status  - Show container status"
    exit 1
    ;;
esac

Enregistrez le fichier et quittez nano (Ctrl+X, puis Y, puis Entrée).

Comprendre la structure du script de déploiement

Avant d'exécuter le script, comprenons comment ce script d'automatisation fonctionne. Cette section fournit une explication détaillée de chaque composant, ce qui facilite la compréhension des concepts de script shell et d'automatisation de conteneurs pour les débutants.

En-tête du script et gestion des erreurs

#!/bin/bash
set -e ## Exit on any error
  • #!/bin/bash : Ceci est appelé un "shebang" - il indique au système d'utiliser le shell Bash pour exécuter ce script
  • set -e : Cela fait que le script se ferme immédiatement si une commande échoue, garantissant que le script s'arrête à la première erreur plutôt que de continuer avec un état potentiellement corrompu

Variables de configuration

## Configuration variables
IMAGE_NAME="rhel9-automated"
IMAGE_TAG="latest"
CONTAINER_NAME="rhel9-production"
HOST_PORT="8080"
CONTAINER_PORT="8080"
DOCKERFILE="rhel9-automated.dockerfile"

Ces variables définissent tous les paramètres clés de notre déploiement. En les plaçant en haut, nous pouvons facilement modifier la configuration du déploiement sans modifier la logique du script. Ceci est similaire à la façon dont les fichiers Kickstart utilisent les paramètres de configuration.

Système de sortie convivial

## Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' ## No Color

## Function to print colored output
print_status() {
  echo -e "${BLUE}[INFO]${NC} $1"
}

Cela crée un système de journalisation professionnel avec une sortie colorée :

  • \033[0;31m : Codes d'échappement ANSI pour les couleurs (31 = rouge, 32 = vert, etc.)
  • echo -e : L'indicateur -e permet l'interprétation des échappements de barre oblique inversée pour les couleurs
  • $1 : Fait référence au premier argument passé à la fonction

Fonctions de déploiement de base

1. Vérification de l'environnement Docker

check_docker() {
  print_status "Checking Docker availability..."
  if ! docker info > /dev/null 2>&1; then
    print_error "Docker is not running or not accessible"
    exit 1
  fi
  print_success "Docker is available"
}
  • docker info > /dev/null 2>&1 : Exécute docker info et redirige à la fois la sortie (>) et les erreurs (2>&1) vers /dev/null (les ignore)
  • ! : Négation du résultat - si docker info échoue (renvoie une valeur non nulle), la condition devient vraie
  • Ceci équivaut à vérifier si la virtualisation est disponible dans les déploiements de machines virtuelles traditionnels

2. Fonction de construction d'image

build_image() {
  print_status "Building RHEL container image..."
  if [ ! -f "$DOCKERFILE" ]; then
    print_error "Dockerfile '$DOCKERFILE' not found"
    exit 1
  fi

  docker build -t "${IMAGE_NAME}:${IMAGE_TAG}" -f "$DOCKERFILE" .
  print_success "Image '${IMAGE_NAME}:${IMAGE_TAG}' built successfully"
}
  • [ ! -f "$DOCKERFILE" ] : Teste si le Dockerfile n'existe PAS (! nie, -f teste l'existence du fichier)
  • docker build -t : Crée une image de conteneur avec une balise (nom:version)
  • Ceci remplace le processus d'installation traditionnel à partir du support ISO

3. Fonction de nettoyage

cleanup_existing() {
  print_status "Checking for existing container..."
  if docker ps -a | grep -q "$CONTAINER_NAME"; then
    print_warning "Stopping and removing existing container '$CONTAINER_NAME'"
    docker stop "$CONTAINER_NAME" > /dev/null 2>&1 || true
    docker rm "$CONTAINER_NAME" > /dev/null 2>&1 || true
  fi
}
  • docker ps -a | grep -q : Liste tous les conteneurs et recherche discrètement notre nom de conteneur
  • || true : Garantit que la commande réussit toujours (renvoie 0) même si le conteneur n'existe pas
  • Cela empêche les conflits avec les déploiements existants

4. Déploiement du conteneur

deploy_container() {
  print_status "Deploying RHEL container..."
  docker run -d \
    --name "$CONTAINER_NAME" \
    -p "${HOST_PORT}:${CONTAINER_PORT}" \
    --restart unless-stopped \
    "${IMAGE_NAME}:${IMAGE_TAG}"

  print_success "Container '$CONTAINER_NAME' deployed successfully"
}
  • -d : Exécute le conteneur en mode détaché (arrière-plan)
  • -p "${HOST_PORT}:${CONTAINER_PORT}" : Mappe le port hôte vers le port du conteneur
  • --restart unless-stopped : Redémarre automatiquement le conteneur s'il s'arrête (sauf arrêts manuels)
  • \ : Caractère de continuation de ligne pour les commandes multilignes

5. Vérification de l'état de santé

verify_deployment() {
  print_status "Verifying container deployment..."

  ## Wait for container to start
  sleep 5

  ## Check if container is running
  if ! docker ps | grep -q "$CONTAINER_NAME"; then
    print_error "Container is not running"
    docker logs "$CONTAINER_NAME"
    exit 1
  fi

  ## Check if web service is responding
  print_status "Testing web service..."
  for i in {1..10}; do
    if curl -s "http://localhost:${HOST_PORT}" > /dev/null; then
      print_success "Web service is responding"
      break
    fi
    if [ $i -eq 10 ]; then
      print_error "Web service is not responding after 10 attempts"
      exit 1
    fi
    sleep 2
  done
}
  • {1..10} : Expansion des accolades Bash - crée la séquence 1, 2, 3... 10
  • curl -s : Mode silencieux de la requête HTTP
  • break : Quitte la boucle prématurément lorsque le service répond
  • Ceci met en œuvre un mécanisme de nouvelle tentative avec un délai d'attente

Interface de ligne de commande

case "${1:-deploy}" in
  "deploy" | "")
    main
    ;;
  "cleanup")
    print_status "Cleaning up deployment..."
    cleanup_existing
    docker rmi "${IMAGE_NAME}:${IMAGE_TAG}" 2> /dev/null || true
    print_success "Cleanup completed"
    ;;
  "status")
    docker ps | grep "$CONTAINER_NAME" || print_warning "Container not running"
    ;;
  *)
    echo "Usage: $0 [deploy|cleanup|status]"
    echo "  deploy  - Build and deploy RHEL container (default)"
    echo "  cleanup - Stop container and remove image"
    echo "  status  - Show container status"
    exit 1
    ;;
esac
  • ${1:-deploy} : Expansion de paramètre - utilise $1 (premier argument) ou "deploy" par défaut
  • Instruction case : Similaire à switch/case dans d'autres langages
  • ;; : Termine chaque branche de cas
  • $0 : Fait référence au nom du script lui-même

Cela crée un script polyvalent qui peut être utilisé pour plusieurs opérations, de la même manière que les administrateurs système utilisent différents outils pour le déploiement, la maintenance et la surveillance.

Rendez le script exécutable :

chmod +x deploy-rhel-container.sh

Maintenant, exécutez le script de déploiement automatisé pour voir le processus d'automatisation complet :

./deploy-rhel-container.sh

Vous devriez voir une sortie montrant le processus de déploiement complet :

=== RHEL Container Automated Deployment ===
This script automates RHEL container deployment
Similar to Kickstart automation for traditional installations

[INFO] Checking Docker availability...
[SUCCESS] Docker is available
[INFO] Building RHEL container image...
[SUCCESS] Image 'rhel9-automated:latest' built successfully
[INFO] Checking for existing container...
[INFO] Deploying RHEL container...
[SUCCESS] Container 'rhel9-production' deployed successfully
[INFO] Verifying container deployment...
[INFO] Testing web service...
[SUCCESS] Web service is responding
[SUCCESS] === RHEL Container Deployment Complete ===
Container Name: rhel9-production
Image: rhel9-automated:latest
Port Mapping: 8080:8080
Access URL: http://localhost:8080

Testez les différentes options de script :

./deploy-rhel-container.sh status

Procédure pas à pas de l'exécution du script

Lorsque vous exécutez le script, il exécute automatiquement la séquence suivante :

1. Phase de validation de l'environnement

Le script vérifie d'abord si Docker est disponible et accessible. Ceci est crucial car le déploiement de conteneurs nécessite un environnement Docker fonctionnel, de la même manière que le déploiement de machines virtuelles nécessite un hyperviseur fonctionnel.

2. Phase de construction de l'image

Le script construit une nouvelle image de conteneur à partir de votre Dockerfile. Ce processus :

  • Lit le rhel9-automated.dockerfile
  • Télécharge l'image UBI9 de base si elle n'est pas déjà présente
  • Exécute chaque instruction dans le Dockerfile
  • Crée une nouvelle image taguée comme rhel9-automated:latest

3. Phase de nettoyage

Avant le déploiement, le script vérifie et supprime tout conteneur existant portant le même nom. Cela garantit un déploiement propre sans conflits de noms.

4. Phase de déploiement

Le script crée et démarre le nouveau conteneur avec :

  • Mode détaché : Le conteneur s'exécute en arrière-plan
  • Mappage de port : Le port hôte 8080 est mappé vers le port du conteneur 8080
  • Politique de redémarrage : Le conteneur redémarre automatiquement s'il s'arrête de manière inattendue
  • Conteneur nommé : Identification et gestion faciles

5. Phase de vérification

Le script effectue des contrôles de santé pour garantir un déploiement réussi :

  • Vérification de l'état du conteneur : Vérifie que le conteneur est en cours d'exécution
  • Vérification de la disponibilité du service : Teste la réponse du service HTTP
  • Mécanisme de nouvelle tentative : Tente jusqu'à 10 fois avec des intervalles de 2 secondes
  • Détection automatique des pannes : Quitte avec une erreur si la vérification échoue

6. Phase d'affichage des informations

Enfin, le script affiche des informations de déploiement complètes, notamment les détails du conteneur, les URL d'accès et l'exemple de contenu.

Exemples d'utilisation pratique

Vous pouvez utiliser ce script de différentes manières :

Déploiement normal :

./deploy-rhel-container.sh
## or explicitly
./deploy-rhel-container.sh deploy

Vérifier l'état du déploiement :

./deploy-rhel-container.sh status

Nettoyer les ressources :

./deploy-rhel-container.sh cleanup

Afficher l'aide du script :

./deploy-rhel-container.sh help

Avantages par rapport aux méthodes traditionnelles

Cette approche d'automatisation offre plusieurs avantages par rapport aux déploiements Kickstart + VM traditionnels :

  1. Vitesse : Le démarrage du conteneur est généralement 10 à 100 fois plus rapide que le démarrage de la machine virtuelle
  2. Efficacité des ressources : Les conteneurs partagent le noyau de l'hôte, utilisant moins de mémoire et de CPU
  3. Cohérence : Le même conteneur s'exécute de manière identique dans différents environnements
  4. Évolutivité : Facile de créer plusieurs instances ou d'évoluer horizontalement
  5. Portabilité : Peut s'exécuter sur n'importe quel système avec Docker installé
  6. Contrôle de version : Les images de conteneurs peuvent être versionnées et stockées dans des registres

Ce script d'automatisation démontre comment les déploiements RHEL modernes basés sur des conteneurs peuvent atteindre le même niveau d'automatisation et de cohérence que les installations de machines virtuelles traditionnelles basées sur Kickstart, mais avec les avantages supplémentaires de la conteneurisation tels qu'un déploiement plus rapide, une meilleure utilisation des ressources et une mise à l'échelle plus facile dans les environnements cloud modernes.

Résumé

Dans ce laboratoire, vous avez exploré l'approche moderne pour automatiser les déploiements de Red Hat Enterprise Linux (RHEL) 9 en utilisant les conteneurs Docker et les Red Hat Universal Base Images (UBI). Vous avez appris que, bien que les déploiements RHEL traditionnels reposaient sur des fichiers Kickstart et des machines virtuelles, les environnements modernes cloud-native utilisent de plus en plus RHEL conteneurisé via des images UBI comme redhat/ubi9.

Vous vous êtes entraîné à traduire les concepts Kickstart traditionnels en automatisation de conteneurs en créant des Dockerfiles personnalisés qui définissent la configuration du système, l'installation des paquets, la gestion des utilisateurs et la configuration des services. Au lieu d'utiliser ksvalidator pour les fichiers Kickstart, vous avez appris à valider les configurations de conteneurs via le processus de construction de Docker, qui fournit un retour d'information immédiat sur la syntaxe et les erreurs d'exécution.

Enfin, vous avez créé un script d'automatisation complet qui démontre le déploiement de conteneurs de bout en bout, similaire à l'utilisation de virt-install avec des fichiers Kickstart pour l'automatisation des machines virtuelles. Cette approche offre le même niveau d'automatisation et de cohérence que les méthodes traditionnelles tout en offrant les avantages de la conteneurisation : un déploiement plus rapide, une meilleure utilisation des ressources, la portabilité et une mise à l'échelle plus facile dans les environnements cloud modernes.