피드 구독

Red Hat Enterprise Linux(RHEL)용 이미지 모드는 컨테이너화된 애플리케이션과 동일한 툴, 기술, 패턴을 사용하여 구축, 제공, 실행이 더 쉬운 운영 체제를 제공합니다. 이 게시물은 이미지 모드의 개념을 다루며, Open Container Initiative(OCI) 컨테이너 이미지에서 운영 체제를 패키징하는 데 필요한 기본 개념을 사용자에게 소개하는 데 유용합니다.

아래 단계와 프로세스는 사용자 정의 이미지를 빌드하고 배포하여 핸즈온 관점에서 RHEL용 이미지 모드의 개념을 더 잘 이해할 수 있도록 돕습니다.

요구 사항:

  1. 모든 명령은 구독한 RHEL 9.x 시스템(노트북, 가상 머신(VM) 등이 작동함) 및 최소 10GB의 사용 가능한 디스크 공간에서 실행됩니다. 생성되는 이미지의 크기와 양에 따라 더 많은 디스크 공간이 필요할 수 있습니다.
  2. 프로덕션 또는 개발자 서브스크립션이 포함된 Red Hat 계정(무료 개발자 서브스크립션은 여기에서 이용 가능).

컨테이너 레지스트리 - 이 예제에서는 quay.io를 레지스트리 콘텐츠가 게시되는 대상으로 사용하지만, 다른 호스팅된 레지스트리 서비스를 사용하거나 레지스트리를 로컬로 실행하도록 선택할 수 있습니다. quay.io 계정은 여기에서 빠르고 쉽게 생성할 수 있습니다.

시작하기

먼저 시스템에 RHEL 콘텐츠를 가져올 수 있는 서브스크립션이 있는지 확인합니다.

$ sudo subscription-manager register

다음으로 Podman을 설치합니다. 사용 가능한 최신 버전을 사용하는 것이 좋지만 v4.* 이상 버전도 작동합니다. Docker 또는 컨테이너 파이프라인 툴링과 같은 다른 컨테이너 툴은 프로덕션 환경에서 작동할 수 있습니다. 이 예제에서는 Podman을 사용하여 개념을 설명하지만, 환경에 더 적합한 다른 툴이 있을 수 있다는 점을 기억하세요.

$ sudo dnf -y install podman

이제 registry.redhat.io를 통해 인증할 차례입니다. 먼저 https://access.redhat.com/terms-based-registry에서 'New service account(새 서비스 계정)'를 클릭하세요. 여기에서 새 항목의 이름을 클릭하고 'docker 로그인' 지침을 터미널에 복사하여 붙여넣은 다음 docker 명령을 podman으로 바꿉니다. 자세한 정보가 필요한 경우 전체 지침은 여기에서 확인할 수 있습니다. 이미지 빌더를 사용하여 컨테이너 이미지를 디스크 이미지로 변환하려면 Podman을 사용한 상승된 권한이 필요합니다. 계속 진행하여 sudo를 사용하거나 사용하지 않고 레지스트리를 인증합니다.

$ podman login registry.redhat.io
#repeat with sudo
$ sudo podman login registry.redhat.io

Bootc 컨테이너 이미지는 기술적으로 두 가지 중요한 점에서 애플리케이션 컨테이너와 다릅니다.

  • bootc 이미지는 컨테이너 내부에서 OSTree를 사용합니다.
  • bootc 이미지에는 물리 또는 가상 머신을 부팅하는 데 필요한 커널과 충분한 기타 패키지가 있습니다.

애플리케이션 컨테이너 기본 이미지에는 일반적으로 하드웨어 관리와 관련이 없는 최소한의 패키지 세트가 포함됩니다. 또한 Red Hat Universal Base Image(UBI)와 달리 RHEL bootc 이미지는 RHEL과 동일한 라이센스 조건에 따라 배포됩니다.

 rhel-bootc 기본 이미지를 풀링하겠습니다.

$ podman pull registry.redhat.io/rhel9/rhel-bootc:9.4

Containerfile 생성

이제 Containerfile의 예를 살펴보겠습니다. 이러한 파일은 Dockerfile으로 알려져 있을 수도 있습니다. 간단하게 시작하여 램프 스택을 설치하겠습니다.  Containerfile

이라는 새 파일을 사용하여 아래 텍스트를 저장합니다.

FROM registry.redhat.io/rhel9/rhel-bootc:9.4

#install the lamp components
RUN dnf module enable -y php:8.2 nginx:1.22 && dnf install -y httpd mariadb mariadb-server php-fpm php-mysqlnd && dnf clean all

#start the services automatically on boot
RUN systemctl enable httpd mariadb php-fpm

#create an awe inspiring home page!
RUN echo '<h1 style="text-align:center;">Welcome to image mode for RHEL</h1> <?php phpinfo(); ?>' >> /var/www/html/index.php

지금까지 포트 80에서 웹 서버를 실행하고 데이터베이스 및 php도 사용 가능하도록 하는 간단한 운영 체제에 대해 설명했습니다. 컨테이너 이미지를 빌드해 보겠습니다.

이미지 빌드

$ podman build -f Containerfile -t quay.io/[my_account]/lamp-bootc:latest

참고:

-t는 이미지에 태그를 지정합니다. 이 예제에서는 quay.io가 사용 중인 레지스트리라고 가정합니다. 사용 중인 레지스트리에 맞게 조정하세요.

-f는 Podman에 Containerfile을 사용하도록 지시합니다.

이미지 테스트

이미지가 준비되었으므로 빠르게 테스트해 보겠습니다. 이미지는 컨테이너이므로 빠르게 실행할 수 있으며 오류가 표시되므로 오타가 있는지 확인할 수 있습니다. 편의를 위해 다음과 같이 짧은 이름(lamp)을 지정하겠습니다.

$ podman run -d --rm --name lamp -p 8080:80 quay.io/[my_account]/lamp-bootc:latest /sbin/init

컨테이너가 시작되며, 지금은 로그인에 대해 걱정할 필요가 없습니다. 브라우저를 열고 http://[your_ip_address]:8080에서 제공되는 웹 페이지를 볼 수 있는지 확인합니다. 페이지가 로드되지 않으면 방화벽 룰을 다시 확인합니다. 로컬 시스템을 사용하는 경우 루프백 주소가 정상적으로 작동해야 합니다. 이 예제에서는 systemd를 시작합니다. 그러나 대부분의 테스트 시나리오에서는 단순히 애플리케이션을 시작하는 것이 더 효율적입니다. 빠른 테스트와 검증을 수행하는 것은 컨테이너를 사용하여 운영 체제 이미지를 정의할 때 가장 중요한 부분 중 하나입니다.

위에서 설정한 이름을 사용하여 podman exec를 통해 실행 중인 컨테이너 인스턴스에 셸을 제공할 수 있습니다.

$ podman exec -it lamp /bin/bash

동일한 이름을 사용하여 인스턴스를 중지합니다.

$ podman stop lamp

레지스트리로 푸시

다음으로 quay.io에 로그인하여 인증하고, 이미지를 레지스트리로 푸시하고, 공개적으로 액세스할 수 있도록 리포지토리를 구성합니다.

$ podman login quay.io
$ podman push quay.io/[my_account]/lamp-bootc:latest

이제 배포할 수 있는 계층화된 이미지를 생성했으며 몇 가지 방법으로 이를 호스트에 설치할 수 있습니다. RHEL의 설치 프로그램을 사용하고 베어 메탈 시스템(USB, PXE 등을 통해 배포)을 Kickstart하거나, 이미지 빌더를 사용하여 컨테이너 이미지를 부팅 가능한 이미지로 변환할 수 있습니다. 이 컨테이너가 '설치'되면 향후 업데이트가 게시될 때 컨테이너 레지스트리에서 직접 적용됩니다. 따라서 설치 프로세스는 한 번만 발생합니다.

Qcow2 디스크 이미지를 사용하여 KVM/QEMU를 통해 배포

이 예제에서는 이미지 빌더를 사용하여 컨테이너 이미지를 qcow2 형식의 디스크로 변환합니다. 이 예제에서는 이미지가 공개적으로 액세스할 수 있는 리포지토리에 있다고 가정합니다. 프라이빗 리포지토리의 이미지를 활용하는 방법은 이미지 빌더 설명서를 참조하세요. qcow2 이외의 다른 이미지 형식도 사용할 수 있습니다.

먼저 결과 디스크의 구성을 활성화하는 config.json 파일을 생성합니다. 이 예제의 경우 config.json에는 생성하려는 사용자가 포함됩니다. 소유한 SSH 키와 비밀번호를 이 예제에 붙여넣으세요.

{
 "blueprint": {
   "customizations": {
     "user": [
       {
         "name": "cloud-user",
         "password": "changeme",
         "key": "ssh-rsa AAAAB3Nz..........",
         "groups": [
           "wheel"
         ]
       }
     ]
   }
 }
}

그런 다음 config.json을 램프 컨테이너와 함께 이미지 빌더에 전달합니다.

$ sudo podman run --rm -it --privileged \
-v .:/output \
-v $(pwd)/config.json:/config.json \
--pull newer \
registry.redhat.io/rhel9/bootc-image-builder:9.4 \
--type qcow2 \
--config /config.json \
quay.io/[my_account]/lamp-bootc:latest

이미지를 사용할 수 있게 되면 libvirt를 사용하여 실행할 수 있습니다(또는 qemu를 직접).

virt-install \
 --name lamp-bootc \
 --memory 4096 \
 --vcpus 2 \
 --disk qcow2/disk.qcow2 \
 --import \
 --os-variant rhel9.4

VM이 실행 중이면 브라우저에서  http://[your_instance_ip_address]를 확인하여 사이트가 실행 중인지 확인할 수 있어야 합니다.

AMI 디스크 이미지를 사용하여 AWS에 배포

이 예제에서는 이전에 만든 램프 Containerfile에서 cloud-init를 사용할 수 있는지 확인해야 합니다. 이 경우 컨테이너 워크플로우가 도움이 되며, 활용 사례에 맞는 계층화된 이미지를 쉽게 생성할 수 있습니다. 계층화된 빌드를 시연하지만 더 쉬운 경우 cloud-init를 포함하도록 원본 Containerfile을 자유롭게 편집할 수 있습니다.

FROM quay.io/[my_account]/lamp-bootc:latest
#install cloud-init for AWS
RUN dnf install -y cloud-init && dnf clean all

이미지를 빌드하고 푸시합니다.

$ podman build -f Containerfile -t quay.io/[my_account]/lamp-bootc-aws:latest
$ podman push quay.io/[my_account]/lamp-bootc-aws:latest

위의 KVM 예제에서 config.json 단계를 건너뛸 수 있는 cloud-init를 사용하여 사용자 및 ssh 키를 삽입하겠습니다(cloud-init 구성 생성은 이 문서에서 다루는 범위를 벗어남). cloud-init를 사용하면 이미지에 하드 코딩된 자격 증명이 포함되지 않으므로 보안 상태가 강화됩니다. 그런 다음 이미지 빌더를 실행하여 AMI를 생성합니다.

$ sudo podman run --rm -it --privileged \
 --pull=newer \
 --security-opt label=type:unconfined_t \
 -v $XDG_RUNTIME_DIR/containers/auth.json:/run/containers/0/auth.json \
 -v $HOME/.aws:/root/.aws:ro \
 --env AWS_PROFILE=default \
 registry.redhat.io/rhel9/bootc-image-builder:9.4:latest \
 --type ami \
 --aws-ami-name lamp-bootc-aws \
 --aws-bucket bootc-bucket \
 --aws-region us-east-1 \
 quay.io/[my_account]/lamp-cloud-init-bootc:latest

추가 옵션을 사용하여 AWS의 속성을 구성할 수 있습니다.  자세한 내용은 이 링크를 참조하세요.

게시 프로세스가 성공적으로 완료되면 이미지를 시작하고 브라우저에서 http://[your_instance_ip_address]를 확인합니다.

Kickstart를 통해 베어 메탈에 설치

앞서 살펴본 바와 같이 컨테이너를 설치하는 방법에는 여러 가지가 있습니다. 이 섹션에서는 ISO, PXE 또는 USB 드라이브를 사용하는 베어 메탈 배포에 매우 널리 사용되는 Kickstart 사용에 대해 설명합니다. 이 가이드에서는 자세히 다루지 않으므로 Kickstart 개념을 어느 정도 잘 알고 있다고 가정합니다. 아래 예제에서 사용자, 비밀번호 및 ssh 키와 관련된 세부 정보를 삽입합니다. 추가 옵션을 추가할 수 있지만, 인스턴스를 컨테이너 이미지로 교체하므로 이 워크플로우를 사용하여 %packages 섹션을 사용할 수 없습니다.  이 사이트에서 아키텍처에 대한 9.4 Boot ISO를 다운로드하세요.

text
network --bootproto=dhcp --device=link --activate
# Basic partitioning
clearpart --all --initlabel --disklabel=gpt
reqpart --add-boot
part / --grow --fstype xfs
# Here's where we reference the container image to install - notice the kickstart
# has no `%packages` section!  What's being installed here is a container image.
ostreecontainer --url quay.io/[my_account]/lamp-bootc:latest
firewall --disabled
services --enabled=sshd
# optionally add a user
user --name=cloud-user --groups=wheel --plaintext --password=changemme
sshkey --username cloud-user "ssh-ed25519 AAAAC3Nza....."
# if desired, inject a SSH key for root
rootpw --iscrypted locked
sshkey --username root "ssh-ed25519 AAAAC3Nza....." #paste your ssh key here
reboot

이 구성 파일을 웹 서버에 복사하고, 비밀번호 및 SSH 키를 업데이트하고, 설치 미디어를 사용하여 물리 또는 가상 시스템을 부팅하고, 커널 인수에 다음을 추가합니다.

inst.ks=http://path_to_my_kickstart

이 옵션을 사용하여 부팅하려면 Ctrl-x를 누릅니다.

HTTP 서버를 바로 사용할 수 없는 경우 대부분의 python 설치에서 사용할 수 있는 http 서버 모듈을 사용할 수 있습니다. Kickstart 파일이 있는 디렉터리에서 다음을 실행합니다.

$ python -m http.server

HTTP 서버를 사용하여 Kickstart 파일을 호스팅하지 않는 또 다른 방법은 Kickstart를 설치 프로그램 ISO에 삽입합니다. lorax 패키지에는 ISO에 이 파일을 임베드할 수 있는 mksiso라는 유틸리티가 포함되어 있습니다. 이는 썸 드라이브에서 직접 부팅하는 데 유용하며 부팅 메뉴를 편집할 수 없도록  합니다. 다음을 실행합니다. mksiso --ks /PATH/TO/KICKSTART /PATH/TO/ISO /PATH/TO/NEW-ISO

업데이트 푸시

이 사례의 주요 요소는 install 또는 deploy가 일회성 작업이라는 것입니다. 이 모델의 가치 중 많은 부분이 이미지를 레지스트리로 푸시하여 변경을 수행할 수 있는 'Day 2'에 발생합니다. 자동 업데이트는 기본적으로 활성화되어 있습니다! 물론 유지 관리 기간에 맞게 간단하게 구성하거나 완전히 비활성화할 수 있습니다. 자동 업데이트를 사용해 보려면 Containerfile을 변경하고 빌드 & 푸시 단계를 반복하여 레지스트리에서 새 이미지를 사용할 수 있도록 합니다.  systemd 유닛의 기본 타이머는 가동 시간 1시간 후에 시작되지만, 업데이트를 가져오기 위해 그보다 먼저 'bootc 업그레이드'할 수도 있습니다.

다음 단계

지금까지 RHEL에 이미지 모드를 사용하는 간단한 예제를 살펴보았습니다. 몇 가지 고유한 활용 사례를 살펴보고, 컨테이너 툴을 사용하여 운영 체제 배포의 버전을 지정하고 관리할 때 얻을 수 있는 가능성과 운영 효율성을 고려하는 것이 좋습니다. 다양한 플랫폼과 유용한 시나리오를 사용하는 데 도움이 될 bootc 예시 리포지토리를 살펴보세요. 또한 자세히 알아볼 준비가 되면 전체 설명서 를 확인하는 것이 좋습니다. 


저자 소개

Ben Breard is a Senior Principal Product Manager at Red Hat, focusing on Red Hat Enterprise Linux and Edge Offerings.

Read full bio
UI_Icon-Red_Hat-Close-A-Black-RGB

채널별 검색

automation icon

오토메이션

기술, 팀, 인프라를 위한 IT 자동화 최신 동향

AI icon

인공지능

고객이 어디서나 AI 워크로드를 실행할 수 있도록 지원하는 플랫폼 업데이트

open hybrid cloud icon

오픈 하이브리드 클라우드

하이브리드 클라우드로 더욱 유연한 미래를 구축하는 방법을 알아보세요

security icon

보안

환경과 기술 전반에 걸쳐 리스크를 감소하는 방법에 대한 최신 정보

edge icon

엣지 컴퓨팅

엣지에서의 운영을 단순화하는 플랫폼 업데이트

Infrastructure icon

인프라

세계적으로 인정받은 기업용 Linux 플랫폼에 대한 최신 정보

application development icon

애플리케이션

복잡한 애플리케이션에 대한 솔루션 더 보기

Original series icon

오리지널 쇼

엔터프라이즈 기술 분야의 제작자와 리더가 전하는 흥미로운 스토리