RHEL デプロイメントのインストールと自動化

Red Hat Enterprise LinuxBeginner
オンラインで実践に進む

はじめに

この実験(Lab)では、Docker を使用して Red Hat Enterprise Linux (RHEL) 9 コンテナをデプロイし、自動化するための基礎を学びます。近代的なクラウドネイティブなデプロイメントでは、従来の仮想マシンよりもコンテナ化された RHEL 環境に依存する傾向が強まっています。まず、コンテナ形式でエンタープライズグレードの RHEL 環境を提供する Red Hat の Universal Base Images (UBI) について探求します。

従来の Kickstart の概念がコンテナの自動化にどのように変換されるかを検証し、インストール設定を反映したカスタム Dockerfile を作成し、自動デプロイメントスクリプトを構築します。この実験の終わりには、RHEL コンテナを効率的にデプロイし、最新のクラウド環境における一貫性のある、再現可能なデプロイメントのためにプロセスを自動化する方法を理解できるようになります。

Red Hat Universal Base Images (UBI) の探索

このステップでは、RHEL をベースとしたエンタープライズグレードのコンテナイメージである Red Hat の Universal Base Images (UBI) について探求します。フル仮想マシンを必要とする従来の RHEL インストールとは異なり、UBI イメージは軽量でポータブルなコンテナで RHEL 環境を提供します。これらのイメージは自由に再配布可能で、最新のクラウドネイティブアプリケーション向けに設計されています。

Red Hat は、さまざまなユースケース向けに最適化されたいくつかの UBI バリアントを提供しています。 redhat/ubi9 イメージは、dnf パッケージマネージャーを備えた完全な RHEL ベースのコンテナ環境を提供し、ソフトウェアのインストールとシステム自動化を必要とするアプリケーションに適しています。

まず、この実験(Lab)のために準備された Red Hat コンテナ設定テンプレートを調べてみましょう。このファイルは、従来の Kickstart の概念がコンテナ環境にどのように変換されるかを示しています。

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

従来のインストール概念を反映した Dockerfile スタイルの設定が表示されます。

## 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"]

次に、利用可能な Red Hat UBI イメージを調べてみましょう。まず、Docker が実行されていてアクセス可能かどうかを確認します。

docker --version

完全な RHEL ベースのコンテナ環境を提供する Red Hat UBI 9 イメージをプルします。

docker pull redhat/ubi9

次のような出力が表示されるはずです。

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

プルが成功したことを確認するために、ダウンロードしたイメージを一覧表示します。

docker images redhat/ubi9

出力には、イメージに関する詳細が表示されます。

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

次に、基本的なコンテナを実行して RHEL 環境を調べてみましょう。

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

コンテナ内で、オペレーティングシステムのバージョンを確認して RHEL 環境を調べます。

cat /etc/redhat-release

次のようなものが表示されるはずです。

Red Hat Enterprise Linux release 9.6 (Plow)

利用可能なパッケージマネージャーを確認します。

dnf --version

次のように入力してコンテナを終了します。

exit

カスタマイズのために、テンプレート設定をプロジェクトディレクトリにコピーします。

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

ファイルが正常にコピーされたことを確認します。

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

これで、Red Hat UBI イメージの探索が正常に完了し、次のステップでカスタムコンテナ設定を作成する準備ができました。

カスタム RHEL コンテナ設定の作成

このステップでは、Red Hat UBI イメージに基づいてカスタム Dockerfile を作成します。このプロセスは、自動インストール用に Kickstart ファイルをカスタマイズする方法を反映していますが、コンテナ環境向けに調整されています。Dockerfile は、一貫性のある RHEL コンテナデプロイメントを作成するための自動化テンプレートとして機能します。

まず、プロジェクトディレクトリにいることを確認します。

cd ~/project

自動化された RHEL コンテナデプロイメント用に、より具体的な新しい Dockerfile を作成します。

cp rhel-container.dockerfile rhel9-automated.dockerfile

両方のファイルが存在することを確認します。

ls -l *.dockerfile

両方のファイルが表示されるはずです。

-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

次に、カスタマイズする前に、新しい Dockerfile を開いてその構造を調べます。

nano rhel9-automated.dockerfile

ファイル内には、Kickstart ディレクティブに相当するコンテナが表示されます。

  • FROM ディレクティブ: 基本 RHEL イメージを指定します (インストールメディアに相当)。
  • ENV ディレクティブ: 環境変数を設定します (システム設定に相当)。
  • RUN ディレクティブ: イメージのビルド中にコマンドを実行します (パッケージのインストールに相当)。
  • EXPOSE および CMD: サービスと起動を構成します (サービス設定に相当)。

今のところ、Ctrl+X を押してエディターを終了し、カスタマイズステップに進みます。

この構造を理解することで、自動化された VM インストール用に Kickstart ファイルをカスタマイズする場合と同様に、特定のデプロイメント要件を満たすようにコンテナ設定をカスタマイズする次のステップに備えることができます。

自動デプロイメント用のコンテナ設定のカスタマイズ

このステップでは、rhel9-automated.dockerfile の内容を、自動化された RHEL コンテナデプロイメント用のカスタム設定に置き換えます。このプロセスは Kickstart ファイルのカスタマイズに似ていますが、Docker の宣言的なアプローチを使用して、コンテナ環境とサービスを定義します。

まず、プロジェクトディレクトリにいることを確認します。

cd ~/project

次に、rhel9-automated.dockerfile の内容全体を置き換えて、完全なカスタム 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

次に、このカスタマイズされた Dockerfile の構造を調べ、各セクションが Kickstart 設定のさまざまな部分と同じ目的をどのように果たしているかを理解しましょう。

1. 基本イメージとメタデータセクション:

## 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"

このセクションは、Kickstart ファイルでインストールメディアと基本的なシステム情報を指定することに相当します。 FROM ディレクティブは基本 RHEL イメージを指定し、LABEL ディレクティブはコンテナに関するメタデータを提供します。

2. 環境設定:

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

これは、Kickstart ファイルの timezone および lang ディレクティブに相当します。システムロケール、タイムゾーンを設定し、ユーザー作成用の変数を定義しています。

3. パッケージのインストール:

## 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

このセクションは、Kickstart の %packages セクションと同じ機能を実行します。システムを更新し、必要なパッケージを --allowerasing を使用して競合を処理し、パッケージキャッシュをクリーンアップしてイメージサイズを削減します。

4. ユーザーとセキュリティの設定:

## 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

これは、Kickstart の user ディレクティブとインストール後の設定を反映しています。セキュリティのために非 root ユーザーを作成し、コンテナ環境に適したポート 8080 で Apache を実行するように設定します。

5. 起動設定:

## 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"]

この最後のセクションは、Kickstart の %post セクションとサービス設定に相当します。起動スクリプトを作成し、非 root ユーザーに切り替え、Web サービスポートを公開し、ヘルスチェックを定義し、コンテナの起動コマンドを指定します。

新しい Dockerfile が正しく作成されたことを確認します。

cat rhel9-automated.dockerfile

従来の Kickstart 自動化の概念が、最新のコンテナベースの RHEL デプロイメントにどのように変換されるかを示す完全な Dockerfile の内容が表示されるはずです。

コンテナ設定の検証とイメージのビルド

このステップでは、カスタム Dockerfile を検証し、RHEL コンテナイメージをビルドします。このプロセスは、ksvalidator を使用して Kickstart ファイルを検証することに似ていますが、ビルドプロセス中に Docker の組み込み検証を使用します。Docker は構文をチェックし、各命令の実行を試み、問題があれば即座にフィードバックを提供します。

まず、Dockerfile があるプロジェクトディレクトリにいることを確認します。

cd ~/project

ビルドする前に、Dockerfile の構造を調べて基本的な構文チェックを実行しましょう。Docker には、ビルドせずに基本的な構文を検証する方法が用意されています。

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

ただし、最も効果的な検証は、実際にイメージをビルドすることです。構文エラーやコマンドの問題がある場合、Docker はビルドプロセス中にそれらを報告します。基本 UBI9 イメージに存在する curlcurl-minimal の間のパッケージの競合を処理するために、dnf install--allowerasing フラグを使用することに注意してください。

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

ビルドプロセスの各ステップを示す出力が表示されるはずです。

[+] 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

ビルドが正常に完了した場合、Dockerfile の構文が正しく、すべてのコマンドが正常に実行されたことを意味します。ビルドプロセス中に、ロケール設定とサブスクリプション管理に関するいくつかの警告メッセージが表示される場合があります。これらは UBI コンテナでは正常であり、機能には影響しません。

イメージが作成されたことを確認します。

docker images rhel9-automated

新しくビルドされたイメージが表示されるはずです。

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

次に、コンテナが期待どおりに動作することを確認するために、コンテナをテストしましょう。デタッチモードでコンテナを実行します。

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

コンテナが実行されているかどうかを確認します。

docker ps

リストにコンテナが表示されるはずです。

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

コンテナにリクエストを送信して、Web サービスをテストします。

curl http://localhost:8080

自動化された RHEL コンテナからの HTML 出力が表示されるはずです。

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

最後に、テストコンテナを停止して削除してクリーンアップします。

docker stop rhel9-test
docker rm rhel9-test

RHEL コンテナ設定は正常に検証およびテストされ、自動デプロイメント機能が実証されました。

自動デプロイメントスクリプトの作成

このステップでは、RHEL コンテナを一貫して繰り返しデプロイする方法を示す自動化スクリプトを作成します。このスクリプトは、VM の自動化に Kickstart ファイルを使用するのと同じ目的を果たしますが、コンテナ化された RHEL デプロイメント向けに調整されています。スクリプトは、イメージのビルド、コンテナのデプロイ、および基本的なヘルスチェックを処理します。

まず、プロジェクトディレクトリにいることを確認します。

cd ~/project

Kickstart ファイルと virt-install で実現できる自動化機能を模倣したデプロイメント自動化スクリプトを作成します。

nano deploy-rhel-container.sh

包括的なデプロイメントスクリプトを作成するために、次の内容を追加します。

#!/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

ファイルを保存して nano を終了します (Ctrl+X、次に Y、次に Enter)。

デプロイメントスクリプトの構造を理解する

スクリプトを実行する前に、この自動化スクリプトがどのように機能するかを理解しましょう。このセクションでは、各コンポーネントの詳細な説明を提供し、初心者でもシェルスクリプトとコンテナ自動化の概念を理解しやすくします。

スクリプトヘッダーとエラー処理

#!/bin/bash
set -e ## Exit on any error
  • #!/bin/bash: これは「shebang」と呼ばれ、システムに Bash シェルを使用してこのスクリプトを実行するように指示します
  • set -e: これにより、コマンドが失敗した場合にスクリプトがすぐに終了し、スクリプトが潜在的に壊れた状態のまま続行するのではなく、最初のエラーで停止することが保証されます

設定変数

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

これらの変数は、デプロイメントのすべての主要なパラメーターを定義します。これらを先頭に配置することで、スクリプトロジックを変更することなく、デプロイメント設定を簡単に変更できます。これは、Kickstart ファイルが構成パラメーターを使用する方法と同様です。

ユーザーフレンドリーな出力システム

## 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"
}

これにより、色付きの出力を持つプロフェッショナルなロギングシステムが作成されます。

  • \033[0;31m: 色の ANSI エスケープコード (31 = 赤、32 = 緑など)
  • echo -e: -e フラグは、色のバックスラッシュエスケープの解釈を有効にします
  • $1: 関数に渡された最初の引数を参照します

コアデプロイメント機能

1. 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: docker info を実行し、出力 (>) とエラー (2>&1) の両方を /dev/null にリダイレクトします (破棄します)
  • !: 結果を否定します - docker info が失敗した場合 (ゼロ以外を返す)、条件は true になります
  • これは、従来の VM デプロイメントで仮想化が利用可能かどうかを確認することと同等です

2. イメージビルド機能

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" ]: Dockerfile が存在しないかどうかをテストします (! は否定、-f はファイルの存在をテストします)
  • docker build -t: タグ (name:version) を使用してコンテナイメージを作成します
  • これは、ISO メディアからの従来のインストールプロセスを置き換えます

3. クリーンアップ機能

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: すべてのコンテナをリストし、コンテナ名を静かに検索します
  • || true: コンテナが存在しない場合でも、コマンドが常に成功すること (0 を返すこと) を保証します
  • これにより、既存のデプロイメントとの競合が防止されます

4. コンテナのデプロイ

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: コンテナをデタッチモード (バックグラウンド) で実行します
  • -p "${HOST_PORT}:${CONTAINER_PORT}": ホストポートをコンテナポートにマッピングします
  • --restart unless-stopped: 停止した場合 (手動停止を除く) にコンテナを自動的に再起動します
  • \: マルチラインコマンドの行継続文字

5. ヘルス検証

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}: Bash ブレース展開 - シーケンス 1、2、3... 10 を作成します
  • curl -s: サイレントモード HTTP リクエスト
  • break: サービスが応答したときにループを早期に終了します
  • これは、タイムアウト付きの再試行メカニズムを実装します

コマンドラインインターフェイス

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}: パラメーター展開 - $1 (最初の引数) または "deploy" をデフォルトとして使用します
  • case ステートメント:他の言語の switch/case に似ています
  • ;;: 各ケースブランチを終了します
  • $0: スクリプト名自体を参照します

これにより、システム管理者がデプロイ、メンテナンス、および監視にさまざまなツールを使用するのと同様に、複数の操作に使用できる多用途のスクリプトが作成されます。

スクリプトを実行可能にします。

chmod +x deploy-rhel-container.sh

次に、自動デプロイメントスクリプトを実行して、完全な自動化プロセスを確認します。

./deploy-rhel-container.sh

完全なデプロイメントプロセスを示す出力が表示されるはずです。

=== 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

さまざまなスクリプトオプションをテストします。

./deploy-rhel-container.sh status

スクリプト実行のウォークスルー

スクリプトを実行すると、次のシーケンスが自動的に実行されます。

1. 環境検証フェーズ

スクリプトは最初に、Docker が利用可能でアクセス可能かどうかを確認します。コンテナのデプロイには、VM のデプロイに動作するハイパーバイザーが必要なのと同様に、動作する Docker 環境が必要であるため、これは非常に重要です。

2. イメージビルドフェーズ

スクリプトは、Dockerfile から新しいコンテナイメージをビルドします。このプロセスは次のとおりです。

  • rhel9-automated.dockerfile を読み取ります
  • まだ存在しない場合は、ベース UBI9 イメージをダウンロードします
  • Dockerfile の各命令を実行します
  • rhel9-automated:latest としてタグ付けされた新しいイメージを作成します

3. クリーンアップフェーズ

デプロイする前に、スクリプトは同じ名前の既存のコンテナがないか確認し、削除します。これにより、名前の競合のないクリーンなデプロイメントが保証されます。

4. デプロイメントフェーズ

スクリプトは、次のものを使用して新しいコンテナを作成して起動します。

  • デタッチモード: コンテナはバックグラウンドで実行されます
  • ポートマッピング: ホストポート 8080 はコンテナポート 8080 にマッピングされます
  • 再起動ポリシー: コンテナは、予期せず停止した場合に自動的に再起動します
  • 名前付きコンテナ: 簡単な識別と管理

5. 検証フェーズ

スクリプトは、正常なデプロイメントを保証するためにヘルスチェックを実行します。

  • コンテナステータスチェック: コンテナが実行されていることを確認します
  • サービス可用性チェック: HTTP サービス応答をテストします
  • 再試行メカニズム: 2 秒間隔で最大 10 回試行します
  • 自動障害検出: 検証が失敗した場合にエラーで終了します

6. 情報表示フェーズ

最後に、スクリプトは、コンテナの詳細、アクセス URL、サンプルコンテンツなど、包括的なデプロイメント情報を表示します。

従来のメソッドに対する利点

この自動化アプローチは、従来の Kickstart + VM デプロイメントと比較して、いくつかの利点を提供します。

  1. 速度: コンテナの起動は、VM の起動よりも通常 10 ~ 100 倍高速です
  2. リソース効率: コンテナはホストカーネルを共有し、より少ないメモリと CPU を使用します
  3. 一貫性: 同じコンテナが、さまざまな環境で同一に実行されます
  4. スケーラビリティ: 複数のインスタンスを簡単に作成したり、水平方向にスケーリングしたりできます
  5. ポータビリティ: Docker がインストールされているすべてのシステムで実行できます
  6. バージョン管理: コンテナイメージはバージョン管理され、レジストリに保存できます

この自動化スクリプトは、最新のコンテナベースの RHEL デプロイメントが、従来の Kickstart ベースの VM インストールと同じレベルの自動化と一貫性を実現できることを示していますが、より高速なデプロイメント、より優れたリソース利用率、最新のクラウド環境でのより簡単なスケーリングなど、コンテナ化の追加の利点があります。

まとめ

この実験では、Docker コンテナと Red Hat Universal Base Images (UBI) を使用して、Red Hat Enterprise Linux (RHEL) 9 のデプロイメントを自動化する最新のアプローチを検討しました。従来の RHEL デプロイメントが Kickstart ファイルと仮想マシンに依存していたのに対し、最新のクラウドネイティブ環境では、redhat/ubi9 のような UBI イメージを通じてコンテナ化された RHEL をますます使用していることを学びました。

システム構成、パッケージのインストール、ユーザー管理、およびサービス構成を定義するカスタム Dockerfile を作成することにより、従来の Kickstart の概念をコンテナ自動化に変換する練習を行いました。Kickstart ファイルに ksvalidator を使用する代わりに、Docker のビルドプロセスを通じてコンテナ構成を検証することを学びました。これにより、構文と実行エラーに関する即時フィードバックが得られます。

最後に、VM の自動化に Kickstart ファイルで virt-install を使用するのと同様に、エンドツーエンドのコンテナデプロイメントを示す包括的な自動化スクリプトを作成しました。このアプローチは、従来のメソッドと同じレベルの自動化と一貫性を提供しながら、コンテナ化の利点 (より高速なデプロイメント、より優れたリソース利用率、ポータビリティ、および最新のクラウド環境でのより簡単なスケーリング) を提供します。