<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>chhanz&apos;s Tech Blog</title>
    <description>소소하게 기술 자료 공유하고 있습니다.
</description>
    <link>https://tech.chhanz.xyz/</link>
    <atom:link href="https://tech.chhanz.xyz/rss" rel="self" type="application/rss+xml"/>
    <pubDate>Fri, 10 Apr 2026 11:03:41 +0900</pubDate>
    <lastBuildDate>Fri, 10 Apr 2026 11:03:41 +0900</lastBuildDate>
    <generator>Jekyll v4.2.2</generator>
    
      <item>
        <title>[AWS] Amazon S3 Files - S3 버킷을 파일 시스템으로 마운트하기</title>
        <description>&lt;hr /&gt;

&lt;p&gt;&lt;img src=&quot;https://docs.aws.amazon.com/images/AmazonS3/latest/userguide/images/S3Files_EC2_dataflow.png&quot; alt=&quot;S3 Files EC2 dataflow&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;개요&quot;&gt;개요&lt;/h1&gt;
&lt;p&gt;Amazon S3 버킷을 NFS 파일 시스템으로 마운트하여 일반 파일 명령어(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ls&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cp&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cat&lt;/code&gt; 등)로 접근할 수 있는 &lt;strong&gt;Amazon S3 Files&lt;/strong&gt; 기능이 2026년 4월에 출시되었습니다. &lt;br /&gt;
이번 포스트에서는 S3 Files 의 개념과 EC2 에서 마운트하는 방법을 기록하도록 하겠습니다.&lt;/p&gt;

&lt;h1 id=&quot;s3-files-란&quot;&gt;S3 Files 란?&lt;/h1&gt;
&lt;p&gt;S3 Files 는 S3 버킷을 &lt;strong&gt;NFS v4.1/v4.2&lt;/strong&gt; 파일 시스템으로 마운트할 수 있게 해주는 기능입니다. &lt;br /&gt;
내부적으로 Amazon EFS 기반의 고성능 스토리지를 활용하며, 활성 데이터에 대해 약 &lt;strong&gt;~1ms&lt;/strong&gt; 수준의 지연시간을 제공합니다.&lt;/p&gt;

&lt;p&gt;데이터는 S3 를 떠나지 않으며, &lt;strong&gt;S3 API 와 파일 API 를 동시에 사용&lt;/strong&gt;할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;지원하는-컴퓨팅-서비스&quot;&gt;지원하는 컴퓨팅 서비스&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Amazon EC2&lt;/li&gt;
  &lt;li&gt;Amazon ECS&lt;/li&gt;
  &lt;li&gt;Amazon EKS&lt;/li&gt;
  &lt;li&gt;AWS Lambda&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;성능-스펙&quot;&gt;성능 스펙&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;항목&lt;/th&gt;
      &lt;th&gt;수치&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;지연시간 (활성 데이터, 소파일)&lt;/td&gt;
      &lt;td&gt;~1ms&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;최대 읽기 IOPS (파일시스템당)&lt;/td&gt;
      &lt;td&gt;250,000&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;최대 쓰기 IOPS (파일시스템당)&lt;/td&gt;
      &lt;td&gt;50,000&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;집계 읽기 처리량&lt;/td&gt;
      &lt;td&gt;수 TB/s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;집계 쓰기 처리량&lt;/td&gt;
      &lt;td&gt;1~5 GiB/s (리전별)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;최대 클라이언트당 읽기 처리량&lt;/td&gt;
      &lt;td&gt;3 GiB/s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;동시 연결&lt;/td&gt;
      &lt;td&gt;최대 25,000개&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h1 id=&quot;파일-시스템-기능&quot;&gt;파일 시스템 기능&lt;/h1&gt;
&lt;p&gt;S3 Files 는 아래와 같은 파일 시스템 기능을 지원합니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;NFS v4.1 / v4.2&lt;/strong&gt; 프로토콜 지원&lt;/li&gt;
  &lt;li&gt;POSIX 권한 (UID/GID 를 오브젝트 메타데이터에 저장)&lt;/li&gt;
  &lt;li&gt;NFS close-to-open 일관성&lt;/li&gt;
  &lt;li&gt;파일 잠금(locking) 지원&lt;/li&gt;
  &lt;li&gt;디렉토리 / 서브디렉토리 탐색&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;작동-원리&quot;&gt;작동 원리&lt;/h1&gt;

&lt;h2 id=&quot;읽기&quot;&gt;읽기&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;소파일 (&amp;lt; 128KB)&lt;/strong&gt; → 고성능 스토리지에서 저지연 서빙&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;대파일 (≥ 128KB, S3 동기화된 데이터)&lt;/strong&gt; → S3 에서 직접 스트리밍 (S3 Files 요금 없음)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;쓰기&quot;&gt;쓰기&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;고성능 스토리지에 먼저 기록 → &lt;strong&gt;60초 배치 윈도우&lt;/strong&gt; 후 S3 자동 동기화&lt;/li&gt;
  &lt;li&gt;60초 내 연속 쓰기는 단일 S3 PUT 으로 통합&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;미접근-데이터&quot;&gt;미접근 데이터&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;30일&lt;/strong&gt; (기본값, 1~365일 설정 가능) 동안 접근이 없으면 고성능 스토리지에서 자동 삭제&lt;/li&gt;
  &lt;li&gt;이후 접근 시 S3 에서 다시 로드&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;보안&quot;&gt;보안&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;전송: TLS 1.3&lt;/li&gt;
  &lt;li&gt;저장: SSE-S3 / SSE-KMS&lt;/li&gt;
  &lt;li&gt;접근 제어: IAM + POSIX 권한&lt;/li&gt;
  &lt;li&gt;모니터링: CloudWatch / CloudTrail&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;파일-시스템-생성&quot;&gt;파일 시스템 생성&lt;/h1&gt;

&lt;h2 id=&quot;콘솔에서-생성&quot;&gt;콘솔에서 생성&lt;/h2&gt;
&lt;p&gt;S3 콘솔에서 파일 시스템을 생성하는 방법은 아래와 같습니다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1)&lt;/strong&gt; S3 콘솔 좌측 메뉴에서 &lt;strong&gt;파일&lt;/strong&gt; → &lt;strong&gt;파일 시스템&lt;/strong&gt; 을 클릭합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-04-09-aws-s3-files/1.png&quot; alt=&quot;S3 콘솔 파일 시스템 메뉴&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2)&lt;/strong&gt; &lt;strong&gt;파일 시스템 생성&lt;/strong&gt; 버튼을 클릭한 후, 범용 버킷 또는 접두사를 입력합니다. &lt;br /&gt;
형식: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s3://버킷명&lt;/code&gt; 또는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s3://버킷명/접두사/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-04-09-aws-s3-files/2.png&quot; alt=&quot;파일 시스템 생성 화면&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3)&lt;/strong&gt; VPC 를 선택하고 &lt;strong&gt;파일 시스템 생성&lt;/strong&gt; 을 클릭합니다. &lt;br /&gt;
생성 완료 후 모든 AZ 에 마운트 타겟이 자동으로 생성됩니다. (수 분 소요)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-04-09-aws-s3-files/3.png&quot; alt=&quot;생성된 파일 시스템 및 탑재 대상 목록&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위와 같이 파일 시스템이 생성되고, 탑재 대상(Mount Target) 목록을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h1 id=&quot;ec2-에서-마운트하기&quot;&gt;EC2 에서 마운트하기&lt;/h1&gt;

&lt;h2 id=&quot;사전-조건&quot;&gt;사전 조건&lt;/h2&gt;
&lt;p&gt;EC2 에서 S3 Files 파일 시스템을 마운트하기 위해서는 아래 조건이 필요합니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;amazon-efs-utils 버전 3.0.0 이상&lt;/strong&gt; 필요 (S3 Files 지원)
    &lt;ul&gt;
      &lt;li&gt;⚠️ Amazon Linux 2023 기본 패키지 버전은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2.4.2&lt;/code&gt; 로 &lt;strong&gt;S3 Files 를 지원하지 않습니다.&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;별도의 efs-utils 전용 리포지토리에서 설치해야 합니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;S3 버킷 Versioning 활성화&lt;/strong&gt; 필요 (S3 Files 필수 요건)&lt;/li&gt;
  &lt;li&gt;EC2 IAM Role 에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AmazonS3FilesClientFullAccess&lt;/code&gt; 정책 추가&lt;/li&gt;
  &lt;li&gt;보안 그룹 설정 (아래 참조)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;보안-그룹-설정&quot;&gt;보안 그룹 설정&lt;/h2&gt;
&lt;p&gt;EC2 인스턴스와 마운트 타겟 간 NFS 통신을 위해 보안 그룹을 아래와 같이 설정해야 합니다.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;대상&lt;/th&gt;
      &lt;th&gt;방향&lt;/th&gt;
      &lt;th&gt;프로토콜&lt;/th&gt;
      &lt;th&gt;포트&lt;/th&gt;
      &lt;th&gt;소스/대상&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;EC2 보안 그룹&lt;/td&gt;
      &lt;td&gt;Outbound&lt;/td&gt;
      &lt;td&gt;TCP&lt;/td&gt;
      &lt;td&gt;2049&lt;/td&gt;
      &lt;td&gt;마운트 타겟 보안 그룹&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;마운트 타겟 보안 그룹&lt;/td&gt;
      &lt;td&gt;Inbound&lt;/td&gt;
      &lt;td&gt;TCP&lt;/td&gt;
      &lt;td&gt;2049&lt;/td&gt;
      &lt;td&gt;EC2 보안 그룹&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-04-09-aws-s3-files/4.png&quot; alt=&quot;탑재 대상 보안 그룹 설정&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위와 같이 마운트 타겟의 보안 그룹에서 EC2 보안 그룹으로부터의 TCP 2049 Inbound 를 허용해야 합니다.&lt;/p&gt;

&lt;h2 id=&quot;amazon-efs-utils-300-이상-설치&quot;&gt;amazon-efs-utils 3.0.0 이상 설치&lt;/h2&gt;
&lt;p&gt;앞서 언급한 바와 같이 Amazon Linux 2023 기본 패키지는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amazon-efs-utils 2.4.2&lt;/code&gt; 버전이므로 S3 Files 를 지원하지 않습니다. &lt;br /&gt;
아래 두 가지 방법 중 하나로 3.0.0 이상 버전을 설치할 수 있습니다.&lt;/p&gt;

&lt;h3 id=&quot;방법-1-전용-installer-스크립트-사용&quot;&gt;방법 1: 전용 installer 스크립트 사용&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl https://amazon-efs-utils.aws.com/efs-utils-installer.sh | &lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;sh &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;방법-2-efs-utils-리포지토리-추가-후-직접-설치&quot;&gt;방법 2: efs-utils 리포지토리 추가 후 직접 설치&lt;/h3&gt;
&lt;p&gt;installer 스크립트 실행 후 전용 리포지토리가 추가됩니다. 아래와 같이 패키지를 확인하고 설치합니다.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;yum list | &lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;efs-utils
&lt;span class=&quot;go&quot;&gt;amazon-efs-utils.x86_64          3.0.1-1.amzn2023          efs-utils

&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;yum &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;amazon-efs-utils-3.0.1-1.amzn2023
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;설치가 완료되면 아래와 같이 확인 할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;rpm &lt;span class=&quot;nt&quot;&gt;-qa&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;efs
&lt;span class=&quot;go&quot;&gt;amazon-efs-utils-3.0.1-1.amzn2023.x86_64
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;마운트&quot;&gt;마운트&lt;/h2&gt;
&lt;p&gt;마운트 디렉토리를 생성하고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mount&lt;/code&gt; 명령어로 S3 Files 파일 시스템을 마운트합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; ./s3files
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;mount &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; s3files fs-0f6284xxxxxxxxx:/ /root/s3files
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;마운트가 완료되면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;df -hT&lt;/code&gt; 명령어로 확인 할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-hT&lt;/span&gt; /root/s3files/
&lt;span class=&quot;go&quot;&gt;Filesystem   Type  Size  Used Avail Use% Mounted on
127.0.0.1:/  nfs4  8.0E     0  8.0E   0% /root/s3files
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mount&lt;/code&gt; 명령어로도 NFS4 프로토콜로 마운트된 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;mount | &lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;s3files
&lt;span class=&quot;go&quot;&gt;127.0.0.1:/ on /root/s3files type nfs4 (rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,...,addr=127.0.0.1)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nfs4&lt;/code&gt; 타입으로 마운트되었으며, NFS v4.2 프로토콜을 사용하는 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;파일-생성-및-s3-동기화-확인&quot;&gt;파일 생성 및 S3 동기화 확인&lt;/h2&gt;
&lt;p&gt;마운트된 디렉토리에서 파일을 생성하면 S3 버킷에 자동으로 동기화됩니다.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;touch &lt;/span&gt;s3files/s3-test.txt
&lt;span class=&quot;go&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt; s3files/
&lt;span class=&quot;go&quot;&gt;total 4
-rw-r--r-- 1 root root 0 Apr 10 00:53 s3-test.txt
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;S3 콘솔에서 확인하면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s3-test.txt&lt;/code&gt; 오브젝트가 자동으로 생성된 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-04-09-aws-s3-files/5.png&quot; alt=&quot;S3 버킷에서 오브젝트 동기화 확인&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위와 같이 파일 시스템에서 생성한 파일이 S3 버킷에 자동으로 동기화되는 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h1 id=&quot;기술-제약-및-참고-사항&quot;&gt;기술 제약 및 참고 사항&lt;/h1&gt;
&lt;p&gt;S3 Files 사용 시 아래 사항을 참고하시기 바랍니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;내부적으로 &lt;strong&gt;Amazon EFS&lt;/strong&gt; 기반으로 구현&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Linux 기반 컴퓨팅만 지원&lt;/strong&gt; (Windows 미지원)&lt;/li&gt;
  &lt;li&gt;파일 크기 임계값 기본값: &lt;strong&gt;128KB&lt;/strong&gt; (설정 가능)&lt;/li&gt;
  &lt;li&gt;데이터 보존 기간: &lt;strong&gt;1~365일&lt;/strong&gt; (기본 30일, 설정 가능)&lt;/li&gt;
  &lt;li&gt;VPC 내 마운트 타겟 필요 (&lt;strong&gt;AZ 당 최대 1개&lt;/strong&gt;)&lt;/li&gt;
  &lt;li&gt;S3 버킷 변경 → 파일 시스템 반영: &lt;strong&gt;수 초 ~ 수 분&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;파일 시스템 변경 → S3 동기화: &lt;strong&gt;수 분 이내&lt;/strong&gt; (60초 배치 윈도우)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;기존-서비스와-비교&quot;&gt;기존 서비스와 비교&lt;/h1&gt;
&lt;p&gt;S3 Files 와 기존 AWS 파일 스토리지 서비스를 비교하면 아래와 같습니다.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;서비스&lt;/th&gt;
      &lt;th&gt;주요 용도&lt;/th&gt;
      &lt;th&gt;프로토콜&lt;/th&gt;
      &lt;th&gt;적합한 워크로드&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;S3 Files&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;S3 데이터를 파일로 접근&lt;/td&gt;
      &lt;td&gt;NFS v4.1/v4.2&lt;/td&gt;
      &lt;td&gt;AI/ML, 데이터 분석, S3 데이터 파일 접근&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;EFS&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;일반 공유 파일 스토리지&lt;/td&gt;
      &lt;td&gt;NFS v4.0/v4.1&lt;/td&gt;
      &lt;td&gt;웹 서버, CMS, 공유 홈 디렉토리&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;FSx for Lustre&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;고성능 병렬 파일 시스템&lt;/td&gt;
      &lt;td&gt;Lustre&lt;/td&gt;
      &lt;td&gt;HPC, GPU 클러스터, 대규모 연산&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;FSx for NetApp ONTAP&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;엔터프라이즈 NAS&lt;/td&gt;
      &lt;td&gt;NFS, SMB, iSCSI&lt;/td&gt;
      &lt;td&gt;온프레미스 NAS 마이그레이션&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;S3 Files 의 핵심 장점은 기존에 S3 와 파일 시스템을 이중으로 관리하던 워크로드에서 파일 시스템 복사본을 제거할 수 있다는 점입니다. &lt;br /&gt;
AWS 에 따르면 기존 S3 ↔ 파일 시스템 이중 관리 대비 &lt;strong&gt;최대 90% 비용 절감&lt;/strong&gt;이 가능하다고 합니다.&lt;/p&gt;

&lt;h1 id=&quot;주요-활용-사례&quot;&gt;주요 활용 사례&lt;/h1&gt;

&lt;h2 id=&quot;ai-에이전트-워크플로우&quot;&gt;AI 에이전트 워크플로우&lt;/h2&gt;
&lt;p&gt;여러 AI 에이전트가 Python 라이브러리, CLI 도구, 쉘 스크립트를 사용하여 공유 S3 데이터에 동시 접근하고, 중간 결과를 교환하거나 컨텍스트를 유지할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;ml-훈련-파이프라인&quot;&gt;ML 훈련 파이프라인&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;기존 방식&lt;/strong&gt;: S3 → 로컬 파일 시스템으로 복사 → 전처리 → 훈련 → 결과를 S3 에 업로드&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;S3 Files 사용&lt;/strong&gt;: S3 데이터를 그대로 파일 시스템으로 접근 → 복사 단계 제거&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;데이터-분석--공동-작업&quot;&gt;데이터 분석 / 공동 작업&lt;/h2&gt;
&lt;p&gt;연구원, 분석가, 데이터 과학자가 최대 25,000개 동시 연결로 동일한 S3 버킷 데이터에 접근하여 협업할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;미디어-제작&quot;&gt;미디어 제작&lt;/h2&gt;
&lt;p&gt;VFX 스튜디오, 렌더팜에서 기존 파일 기반 도구를 그대로 사용하면서 S3 에 저장된 영상 및 에셋에 직접 접근할 수 있습니다.&lt;/p&gt;

&lt;h1 id=&quot;참고-자료&quot;&gt;참고 자료&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/ko/blogs/aws/launching-s3-files-making-s3-buckets-accessible-as-file-systems/&quot;&gt;AWS Blog - Launching S3 Files&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/userguide/s3-files-prereq-policies.html&quot;&gt;S3 Files Prerequisites&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/userguide/s3-files-mounting.html&quot;&gt;Mounting S3 file systems on EC2&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-files.html&quot;&gt;S3 Files Documentation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/s3/pricing/&quot;&gt;S3 Pricing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 09 Apr 2026 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/aws/2026/04/09/aws-s3-files/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/aws/2026/04/09/aws-s3-files/</guid>
        
        <category>aws</category>
        
        <category>linux</category>
        
        
        <category>aws</category>
        
      </item>
    
      <item>
        <title>[Docker] Traefik 기본 사용법</title>
        <description>&lt;h1 id=&quot;traefik-기본-사용법&quot;&gt;Traefik 기본 사용법&lt;/h1&gt;

&lt;p&gt;이번 포스팅에서는 Docker 환경에서 &lt;strong&gt;Traefik&lt;/strong&gt;을 구성하고 사용하는 방법에 대해 기록하도록 하겠습니다.&lt;/p&gt;

&lt;h2 id=&quot;traefik-이란&quot;&gt;Traefik 이란?&lt;/h2&gt;

&lt;p&gt;Traefik은 클라우드 네이티브 환경을 위한 리버스 프록시 / 로드 밸런서입니다. &lt;br /&gt;
Nginx나 HAProxy와 같은 전통적인 프록시와 달리, 서비스를 자동으로 감지하고 라우팅 설정을 동적으로 업데이트하는 것이 특징입니다.&lt;/p&gt;

&lt;p&gt;특히 Docker 환경에서 컨테이너에 레이블(Label)만 추가하면 자동으로 라우팅이 설정되어, 별도로 설정 파일을 관리할 필요가 없습니다.&lt;/p&gt;

&lt;h2 id=&quot;테스트-환경&quot;&gt;테스트 환경&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;테스트 환경 : Amazon Linux 2023&lt;/li&gt;
  &lt;li&gt;Traefik : v3.3&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;핵심-개념&quot;&gt;핵심 개념&lt;/h2&gt;

&lt;p&gt;Traefik 은 4가지 핵심 컴포넌트로 구성됩니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-02-27-traefik-basic-usage/1.png&quot; alt=&quot;Traefik 핵심 개념 흐름도&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;entrypoints&quot;&gt;EntryPoints&lt;/h3&gt;
&lt;p&gt;외부에서 들어오는 네트워크 포트를 정의합니다.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;entryPoints&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;web&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;:80&quot;&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;websecure&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;:443&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;routers&quot;&gt;Routers&lt;/h3&gt;
&lt;p&gt;요청을 규칙에 따라 분류하여 적절한 서비스로 연결합니다.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Host 기반 라우팅&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;rule&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Host(`example.com`)&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Path 기반 라우팅&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;rule&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;PathPrefix(`/api`)&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 복합 조건&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;rule&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Host(`example.com`)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;PathPrefix(`/api`)&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;middlewares&quot;&gt;Middlewares&lt;/h3&gt;
&lt;p&gt;라우터와 서비스 사이에서 요청/응답을 변환하는 플러그인입니다.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;미들웨어&lt;/th&gt;
      &lt;th&gt;용도&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;basicAuth&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;HTTP Basic 인증&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;redirectScheme&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;HTTP → HTTPS 리다이렉트&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stripPrefix&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;URL 경로 앞부분 제거&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rateLimit&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;요청 속도 제한&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;headers&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;헤더 추가/수정&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;providers&quot;&gt;Providers&lt;/h3&gt;
&lt;p&gt;Traefik이 라우팅 설정을 읽어오는 소스입니다.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Provider&lt;/th&gt;
      &lt;th&gt;설명&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Docker 컨테이너 레이블 자동 감지&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;file&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;정적 YAML/TOML 파일&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kubernetes&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Kubernetes Ingress&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;설치-docker-compose&quot;&gt;설치 (Docker Compose)&lt;/h2&gt;

&lt;p&gt;아래와 같은 방법으로 Traefik 을 구성합니다.&lt;/p&gt;

&lt;h3 id=&quot;디렉토리-구조&quot;&gt;디렉토리 구조&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;traefik/
├── docker-compose.yml
├── traefik.yml        ← 정적 설정 (Static Config)
└── dynamic.yml        ← 동적 설정 (Dynamic Config)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;traefikyml-정적-설정&quot;&gt;traefik.yml (정적 설정)&lt;/h3&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# traefik.yml&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;api&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;dashboard&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;insecure&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;# 대시보드 인증 없이 접근 (개발용)&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;entryPoints&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;web&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;:80&quot;&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;providers&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;exposedByDefault&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# 레이블 없는 컨테이너는 노출 안 함&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/etc/traefik/dynamic.yml&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;watch&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;               &lt;span class=&quot;c1&quot;&gt;# 파일 변경 자동 감지&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;INFO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;docker-composeyml&quot;&gt;docker-compose.yml&lt;/h3&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;traefik&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;traefik:v3.3&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;container_name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;traefik&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;unless-stopped&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;80:80&quot;&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;127.0.0.1:8888:8080&quot;&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# 대시보드 (로컬 전용)&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/var/run/docker.sock:/var/run/docker.sock:ro&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;./traefik.yml:/etc/traefik/traefik.yml:ro&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;./dynamic.yml:/etc/traefik/dynamic.yml:ro&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;traefik_net&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;traefik_net&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;대시보드 포트(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;8888&lt;/code&gt;)는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;127.0.0.1&lt;/code&gt;에만 바인딩하여 외부 노출을 차단합니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;실전-예시-1--docker-컨테이너-라우팅&quot;&gt;실전 예시 1 — Docker 컨테이너 라우팅&lt;/h2&gt;

&lt;p&gt;컨테이너에 레이블만 추가하면 Traefik 이 자동으로 라우팅 설정을 감지합니다.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;myapp&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;nginx&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;traefik.enable=true&quot;&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;traefik.http.routers.myapp.rule=Host(`myapp.example.com`)&quot;&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;traefik.http.routers.myapp.entrypoints=web&quot;&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;traefik.http.services.myapp.loadbalancer.server.port=80&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;traefik_net&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 레이블을 추가하면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;myapp.example.com&lt;/code&gt; 으로 들어오는 요청이 해당 컨테이너로 자동 라우팅되는 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;실전-예시-2--path-기반-라우팅&quot;&gt;실전 예시 2 — Path 기반 라우팅&lt;/h2&gt;

&lt;p&gt;여러 서비스를 하나의 도메인에서 경로로 분리할 때 아래와 같이 구성합니다.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# docs.example.com/      → open-webui&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;open-webui&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ghcr.io/open-webui/open-webui&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;traefik.enable=true&quot;&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;traefik.http.routers.webui.rule=Host(`docs.example.com`)&quot;&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;traefik.http.routers.webui.entrypoints=web&quot;&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# docs.example.com/docs/ → mkdocs&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;mkdocs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;squidfunk/mkdocs-material&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;traefik.enable=true&quot;&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;traefik.http.routers.mkdocs.rule=Host(`docs.example.com`)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;PathPrefix(`/docs`)&quot;&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;traefik.http.routers.mkdocs.entrypoints=web&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;실전-예시-3--basicauth-미들웨어&quot;&gt;실전 예시 3 — BasicAuth 미들웨어&lt;/h2&gt;

&lt;p&gt;특정 서비스에 HTTP Basic 인증을 추가하는 방법입니다.&lt;/p&gt;

&lt;h3 id=&quot;비밀번호-해시-생성&quot;&gt;비밀번호 해시 생성&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;htpasswd &lt;span class=&quot;nt&quot;&gt;-nb&lt;/span&gt; username password
username:&lt;span class=&quot;nv&quot;&gt;$apr1$xxxxxxxx$hashedpassword&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;dynamicyml-에-미들웨어-정의&quot;&gt;dynamic.yml 에 미들웨어 정의&lt;/h3&gt;

&lt;p&gt;출력된 해시를 그대로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dynamic.yml&lt;/code&gt; 에 붙여넣으면 됩니다.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# dynamic.yml&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;middlewares&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;my-auth&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;basicAuth&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;username:$apr1$xxxxxxxx$hashedpassword&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;컨테이너-레이블에서-참조&quot;&gt;컨테이너 레이블에서 참조&lt;/h3&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;traefik.http.routers.myapp.middlewares=my-auth@file&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;파일 프로바이더의 미들웨어를 Docker 레이블에서 참조할 때는 반드시 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@file&lt;/code&gt; 접미사를 붙여야 합니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;실전-예시-4--elb-헬스체크-처리&quot;&gt;실전 예시 4 — ELB 헬스체크 처리&lt;/h2&gt;

&lt;p&gt;AWS ELB(Elastic Load Balancer) 뒤에 Traefik을 배치할 때, ELB 헬스체크는 Host 헤더를 포함하지 않습니다. &lt;br /&gt;
이 경우 아래와 같이 별도 라우터를 파일 프로바이더로 등록합니다.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# dynamic.yml&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;routers&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;elb-health&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;rule&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Path(`/health`)&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;entryPoints&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;web&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;health-service&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;priority&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;health-service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;loadBalancer&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;servers&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;http://localhost&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 구성하면 Host 조건 없이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/health&lt;/code&gt; 경로만으로 라우팅되어 ELB 헬스체크가 정상 통과됩니다.&lt;/p&gt;

&lt;h2 id=&quot;대시보드&quot;&gt;대시보드&lt;/h2&gt;

&lt;p&gt;Traefik 대시보드를 통해 현재 라우터/서비스/미들웨어 상태를 실시간으로 확인 할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# 로컬에서 접속&lt;/span&gt;
http://localhost:8888/dashboard/

&lt;span class=&quot;c&quot;&gt;# API 로 라우터 목록 확인&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;curl http://localhost:8888/api/http/routers | jq &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;주의-사항&quot;&gt;주의 사항&lt;/h2&gt;

&lt;p&gt;Docker 레이블의 Host rule 작성 시 반드시 백틱(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;`&lt;/code&gt;)을 사용해야 합니다.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# ✅ 올바른 문법&lt;/span&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;traefik.http.routers.myapp.rule=Host(`myapp.example.com`)&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# ❌ 작동 안 함&lt;/span&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;traefik.http.routers.myapp.rule=Host(&quot;myapp.example.com&quot;)&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;참고-자료&quot;&gt;참고 자료&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://doc.traefik.io/traefik/&quot;&gt;Traefik 공식 문서&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://doc.traefik.io/traefik/getting-started/concepts/&quot;&gt;Traefik Concepts&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://doc.traefik.io/traefik/providers/docker/&quot;&gt;Docker Provider&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://doc.traefik.io/traefik/providers/file/&quot;&gt;File Provider&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://doc.traefik.io/traefik/middlewares/http/basicauth/&quot;&gt;BasicAuth Middleware&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/_/traefik&quot;&gt;Docker Hub — traefik&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 27 Feb 2026 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/docker/2026/02/27/traefik-basic-usage/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/docker/2026/02/27/traefik-basic-usage/</guid>
        
        <category>docker</category>
        
        
        <category>docker</category>
        
      </item>
    
      <item>
        <title>[AWS] Firecracker microVM with Amazon EC2 Nested Virtualization</title>
        <description>&lt;h1 id=&quot;firecracker-microvm-with-amazon-ec2-nested-virtualization&quot;&gt;Firecracker microVM with Amazon EC2 Nested Virtualization&lt;/h1&gt;

&lt;h2 id=&quot;firecracker-란&quot;&gt;Firecracker 란?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://firecracker-microvm.github.io/&quot;&gt;Firecracker&lt;/a&gt;는 AWS에서 개발한 오픈소스 VMM(Virtual Machine Monitor)입니다. &lt;br /&gt;
KVM을 사용하여 경량 microVM을 생성하고 관리하며, AWS Lambda와 AWS Fargate의 기반 기술로 사용되고 있습니다.&lt;/p&gt;

&lt;p&gt;Firecracker는 64-bit Intel, AMD, Arm CPU를 지원하며, hardware virtualization 기능이 필요합니다. &lt;br /&gt;
Fly.io, Kata Containers, firecracker-containerd 등 다양한 프로젝트에서 활용되고 있습니다.&lt;/p&gt;

&lt;p&gt;이번 포스팅에서는 AWS EC2 Nested Virtualization 환경에서 Firecracker microVM을 설치하고 실행하는 방법에 대해 기록하도록 하겠습니다.&lt;/p&gt;

&lt;h2 id=&quot;ec2-nested-virtualization&quot;&gt;EC2 Nested Virtualization&lt;/h2&gt;

&lt;p&gt;기존에는 EC2에서 KVM을 사용하기 위해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.metal&lt;/code&gt; 인스턴스 타입을 사용해야 했습니다. &lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.metal&lt;/code&gt; 인스턴스는 비용이 높아 Firecracker와 같은 KVM 기반 기술을 테스트하기에 부담이 되었습니다.&lt;/p&gt;

&lt;p&gt;하지만 AWS Nitro 기반 일반 EC2 인스턴스에서 Nested Virtualization(KVM)을 지원하게 되면서, &lt;strong&gt;C8i, M8i, R8i&lt;/strong&gt; 인스턴스 타입에서도 KVM을 사용할 수 있게 되었습니다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;참고:&lt;/strong&gt; Nested Virtualization은 현재 C8i, M8i, R8i 인스턴스 타입에서만 지원됩니다. (출처: &lt;a href=&quot;https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/amazon-ec2-nested-virtualization.html&quot;&gt;AWS 공식 문서&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;테스트-환경&quot;&gt;테스트 환경&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;테스트 환경: Amazon Linux 2023 (Nitro 기반 EC2 인스턴스)&lt;/li&gt;
  &lt;li&gt;Firecracker 버전: v1.14.1&lt;/li&gt;
  &lt;li&gt;Guest OS: Ubuntu 24.04&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;kvm-지원-확인&quot;&gt;KVM 지원 확인&lt;/h2&gt;

&lt;p&gt;먼저 EC2 인스턴스에서 KVM이 지원되는지 확인합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-53-163 ~]# &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-la&lt;/span&gt; /dev/kvm
crw-rw-rw-. 1 root kvm 10, 232 Feb 23 12:20 /dev/kvm

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-53-163 ~]# lsmod | &lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;kvm
kvm_intel             393216  0
kvm                  1155072  1 kvm_intel
irqbypass              16384  1 kvm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/kvm&lt;/code&gt; 디바이스가 존재하고 KVM 모듈이 로드되어 있으면 Firecracker를 사용할 수 있습니다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;KVM이 지원되지 않는 경우&lt;/strong&gt; &lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/kvm&lt;/code&gt; 디바이스가 없다면 EC2 인스턴스를 생성할 때 &lt;strong&gt;“Enable nested virtualization”&lt;/strong&gt; 옵션이 활성화되어 있는지 확인하세요. &lt;br /&gt;
AWS 콘솔에서 인스턴스 생성 시 → &lt;em&gt;Advanced details&lt;/em&gt; → &lt;em&gt;Enable nested virtualization&lt;/em&gt; 항목을 체크합니다. &lt;br /&gt;
2026년 02월 23일 기준, 지원 인스턴스 타입은 &lt;strong&gt;C8i, M8i, R8i&lt;/strong&gt; 만 해당됩니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-02-23-firecracker-microvm/1.png&quot; alt=&quot;KVM 지원 확인&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;firecracker-설치&quot;&gt;Firecracker 설치&lt;/h2&gt;

&lt;p&gt;아래와 같은 방법으로 Firecracker 바이너리를 다운로드합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ ARCH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;uname&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ release_url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://github.com/firecracker-microvm/firecracker/releases&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ latest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;basename&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;curl &lt;span class=&quot;nt&quot;&gt;-fsSLI&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; /dev/null &lt;span class=&quot;nt&quot;&gt;-w&lt;/span&gt;  %&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;url_effective&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;release_url&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/latest&lt;span class=&quot;si&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;curl &lt;span class=&quot;nt&quot;&gt;-L&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;release_url&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/download/&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;latest&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/firecracker-&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;latest&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;-&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ARCH&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;.tgz &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    | &lt;span class=&quot;nb&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-xz&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mv &lt;/span&gt;release-&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;latest&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;-&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;uname&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;/firecracker-&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;latest&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;-&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ARCH&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; firecracker
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;바이너리가 정상적으로 다운로드 되었는지 확인합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-53-163 ~]# ./firecracker &lt;span class=&quot;nt&quot;&gt;--version&lt;/span&gt;
Firecracker v1.14.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;kernel-및-rootfs-준비&quot;&gt;Kernel 및 RootFS 준비&lt;/h2&gt;

&lt;p&gt;Firecracker microVM을 실행하기 위해서는 Linux kernel과 rootfs 이미지가 필요합니다. &lt;br /&gt;
아래와 같이 Firecracker CI에서 제공하는 테스트용 kernel과 rootfs를 다운로드합니다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Amazon Linux 2023에서 squashfs 처리 및 iptables 관리를 위해 아래 패키지를 먼저 설치합니다.&lt;/p&gt;
  &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# yum -y install squashfs-tools-4.5-3.amzn2023.0.2.x86_64&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# yum -y install iptables-nft-1.8.8-3.amzn2023.0.2.x86_64&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;ARCH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;uname&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;release_url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://github.com/firecracker-microvm/firecracker/releases&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;latest_version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;basename&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;curl &lt;span class=&quot;nt&quot;&gt;-fsSLI&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; /dev/null &lt;span class=&quot;nt&quot;&gt;-w&lt;/span&gt;  %&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;url_effective&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;release_url&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/latest&lt;span class=&quot;si&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;CI_VERSION&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;latest_version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%.*&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Kernel 다운로드&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;latest_kernel_key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;curl &lt;span class=&quot;s2&quot;&gt;&quot;http://spec.ccfc.min.s3.amazonaws.com/?prefix=firecracker-ci/&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$CI_VERSION&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ARCH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/vmlinux-&amp;amp;list-type=2&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    | &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-oP&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;(?&amp;lt;=&amp;lt;Key&amp;gt;)(firecracker-ci/&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$CI_VERSION&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ARCH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/vmlinux-[0-9]+&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]+&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]{1,3})(?=&amp;lt;/Key&amp;gt;)&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    | &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-V&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;tail&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-1&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
wget &lt;span class=&quot;s2&quot;&gt;&quot;https://s3.amazonaws.com/spec.ccfc.min/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;latest_kernel_key&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# RootFS 다운로드 (squashfs → ext4 변환)&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;latest_ubuntu_key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;curl &lt;span class=&quot;s2&quot;&gt;&quot;http://spec.ccfc.min.s3.amazonaws.com/?prefix=firecracker-ci/&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$CI_VERSION&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ARCH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/ubuntu-&amp;amp;list-type=2&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    | &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-oP&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;(?&amp;lt;=&amp;lt;Key&amp;gt;)(firecracker-ci/&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$CI_VERSION&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ARCH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/ubuntu-[0-9]+&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]+&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;squashfs)(?=&amp;lt;/Key&amp;gt;)&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    | &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-V&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;tail&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-1&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;ubuntu_version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;basename&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$latest_ubuntu_key&lt;/span&gt; .squashfs | &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-oE&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;[0-9]+\.[0-9]+&apos;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;

wget &lt;span class=&quot;nt&quot;&gt;-O&lt;/span&gt; ubuntu-&lt;span class=&quot;nv&quot;&gt;$ubuntu_version&lt;/span&gt;.squashfs.upstream &lt;span class=&quot;s2&quot;&gt;&quot;https://s3.amazonaws.com/spec.ccfc.min/&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$latest_ubuntu_key&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# SSH 키 생성 및 rootfs에 삽입&lt;/span&gt;
unsquashfs ubuntu-&lt;span class=&quot;nv&quot;&gt;$ubuntu_version&lt;/span&gt;.squashfs.upstream
ssh-keygen &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; id_rsa &lt;span class=&quot;nt&quot;&gt;-N&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cp&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; id_rsa.pub squashfs-root/root/.ssh/authorized_keys
&lt;span class=&quot;nb&quot;&gt;mv&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; id_rsa ./ubuntu-&lt;span class=&quot;nv&quot;&gt;$ubuntu_version&lt;/span&gt;.id_rsa

&lt;span class=&quot;c&quot;&gt;# ext4 이미지 생성&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo chown&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-R&lt;/span&gt; root:root squashfs-root
&lt;span class=&quot;nb&quot;&gt;truncate&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; 1G ubuntu-&lt;span class=&quot;nv&quot;&gt;$ubuntu_version&lt;/span&gt;.ext4
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;mkfs.ext4 &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; squashfs-root &lt;span class=&quot;nt&quot;&gt;-F&lt;/span&gt; ubuntu-&lt;span class=&quot;nv&quot;&gt;$ubuntu_version&lt;/span&gt;.ext4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;다운로드 완료 후 파일 목록을 확인합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-53-163 ~]# &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt; | egrep &lt;span class=&quot;s2&quot;&gt;&quot;ubuntu|id_rsa|vmlinux&quot;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;-rw-r--r--&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;  1 root root        607 Feb 23 12:47 id_rsa.pub
&lt;span class=&quot;nt&quot;&gt;-rw-r--r--&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;  1 root root 1073741824 Feb 23 13:07 ubuntu-24.04.ext4
&lt;span class=&quot;nt&quot;&gt;-rw-------&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;  1 root root       2655 Feb 23 12:47 ubuntu-24.04.id_rsa
&lt;span class=&quot;nt&quot;&gt;-rw-r--r--&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;  1 root root  107810816 Nov 18 09:37 ubuntu-24.04.squashfs.upstream
&lt;span class=&quot;nt&quot;&gt;-rw-r--r--&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;  1 root root   44278288 Nov 18 09:37 vmlinux-6.1.155
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;!-- 파일 목록은 본문 코드블록으로 대체 --&gt;

&lt;h2 id=&quot;네트워크-설정&quot;&gt;네트워크 설정&lt;/h2&gt;

&lt;p&gt;Firecracker는 TUN/TAP 네트워크 백엔드만 지원합니다. &lt;br /&gt;
microVM을 시작하기 전에 TAP 디바이스와 NAT를 먼저 설정합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;TAP_DEV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tap0&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;TAP_IP&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;192.168.0.1&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;MASK_SHORT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/24&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# TAP 디바이스 생성&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;ip &lt;span class=&quot;nb&quot;&gt;link &lt;/span&gt;del &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TAP_DEV&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; 2&amp;gt; /dev/null &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true
sudo &lt;/span&gt;ip tuntap add dev &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TAP_DEV&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; mode tap
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;ip addr add &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TAP_IP&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MASK_SHORT&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; dev &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TAP_DEV&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;ip &lt;span class=&quot;nb&quot;&gt;link set &lt;/span&gt;dev &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TAP_DEV&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; up

&lt;span class=&quot;c&quot;&gt;# iptables NAT 설정&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;iptables &lt;span class=&quot;nt&quot;&gt;-P&lt;/span&gt; FORWARD ACCEPT
&lt;span class=&quot;nv&quot;&gt;HOST_IFACE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;ip &lt;span class=&quot;nt&quot;&gt;-j&lt;/span&gt; route list default | jq &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;.[0].dev&apos;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;iptables &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; nat &lt;span class=&quot;nt&quot;&gt;-D&lt;/span&gt; POSTROUTING &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOST_IFACE&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-j&lt;/span&gt; MASQUERADE &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true
sudo &lt;/span&gt;iptables &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; nat &lt;span class=&quot;nt&quot;&gt;-A&lt;/span&gt; POSTROUTING &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOST_IFACE&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-j&lt;/span&gt; MASQUERADE
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;vm_configjson-작성&quot;&gt;vm_config.json 작성&lt;/h2&gt;

&lt;p&gt;API 방식 대신 config 파일을 사용하면 한 번에 microVM을 구성하고 시작할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;boot-source&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;kernel_image_path&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;vmlinux-6.1.155&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;boot_args&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;console=ttyS0 reboot=k panic=1&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;drives&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;drive_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;rootfs&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;is_root_device&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;is_read_only&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;path_on_host&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ubuntu-24.04.ext4&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cache_type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Unsafe&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;io_engine&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Sync&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;machine-config&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;vcpu_count&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;mem_size_mib&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;smt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;network-interfaces&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;iface_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;eth0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;host_dev_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tap0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;guest_mac&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;06:00:c0:a8:00:02&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;firecracker-microvm-실행&quot;&gt;Firecracker microVM 실행&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--config-file&lt;/code&gt; 옵션으로 vm_config.json을 지정하여 microVM을 시작합니다. &lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--enable-pci&lt;/code&gt; 플래그는 VirtIO 장치를 PCI transport로 생성하여 높은 처리량과 낮은 지연을 제공합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-53-163 ~]# &lt;span class=&quot;nb&quot;&gt;sudo&lt;/span&gt; ./firecracker &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--api-sock&lt;/span&gt; /tmp/firecracker.socket &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--config-file&lt;/span&gt; vm_config.json &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--enable-pci&lt;/span&gt;
2026-02-23T13:00:50.965053032 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;anonymous-instance:main] Running Firecracker v1.14.1
2026-02-23T13:00:50.965322102 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;anonymous-instance:main] Listening on API socket &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/tmp/firecracker.socket&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
2026-02-23T13:00:51.022688684 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;anonymous-instance:main] pci: adding PCI segment: &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0x0, ...
2026-02-23T13:00:51.023549260 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;anonymous-instance:main] Artificially kick devices
...
Successfully started microvm that was configured from one single json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-02-23-firecracker-microvm/2.png&quot; alt=&quot;실행 완료&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;동작-확인&quot;&gt;동작 확인&lt;/h2&gt;

&lt;p&gt;microVM이 시작되면 Host에서 ping 및 SSH로 접속할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Host에서 microVM ping 확인&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-53-163 ~]# ping 192.168.0.2
PING 192.168.0.2 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;192.168.0.2&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; 56&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;84&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; bytes of data.
64 bytes from 192.168.0.2: &lt;span class=&quot;nv&quot;&gt;icmp_seq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1 &lt;span class=&quot;nv&quot;&gt;ttl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;127 &lt;span class=&quot;nb&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0.299 ms

&lt;span class=&quot;c&quot;&gt;# SSH 접속&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-53-163 ~]# ssh &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; ubuntu-24.04.id_rsa root@192.168.0.2
Welcome to Ubuntu 24.04.3 LTS &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;GNU/Linux 6.1.155 x86_64&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
...
root@ubuntu-fc-uvm:~#
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;microVM 내부에서 외부 네트워크 연결이 가능하도록 설정하고 외부 통신 여부 확인합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# 기본 라우팅 및 DNS 설정&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-53-163 ~]# ssh &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; ubuntu-24.04.id_rsa root@192.168.0.2 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;ip route add default via 192.168.0.1 dev eth0&quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-53-163 ~]# ssh &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; ubuntu-24.04.id_rsa root@192.168.0.2 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;echo &apos;nameserver 8.8.8.8&apos; &amp;gt; /etc/resolv.conf&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# 외부 통신 확인&lt;/span&gt;
root@ubuntu-fc-uvm:~# ping 1.1.1.1
64 bytes from 1.1.1.1: &lt;span class=&quot;nv&quot;&gt;icmp_seq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1 &lt;span class=&quot;nv&quot;&gt;ttl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;49 &lt;span class=&quot;nb&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;3.19 ms

root@ubuntu-fc-uvm:~# curl naver.com
&amp;lt;html&amp;gt;
&amp;lt;&lt;span class=&quot;nb&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&amp;lt;title&amp;gt;301 Moved Permanently&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;tmux-를-이용한-microvm-관리&quot;&gt;tmux 를 이용한 microVM 관리&lt;/h2&gt;

&lt;p&gt;Firecracker microVM을 실행하면 해당 터미널이 VM 콘솔로 점유됩니다. &lt;br /&gt;
tmux를 활용하면 별도 터미널 없이 백그라운드 세션으로 microVM을 관리할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;tmux 세션으로 microVM 시작
&lt;span class=&quot;gp&quot;&gt;[root@ip-172-31-53-163 ~]#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;tmux new-session &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; u24 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    &apos;/root/firecracker --api-sock /tmp/firecracker-u24.socket \
    --config-file vm_config.json --enable-pci&apos;

&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;실행 중인 세션 확인
&lt;span class=&quot;gp&quot;&gt;[root@ip-172-31-53-163 ~]#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;tmux list-session
&lt;span class=&quot;go&quot;&gt;u24: 1 windows (created Mon Feb 23 13:31:49 2026)

&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;세션에 접속 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;VM 콘솔 진입&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;[root@ip-172-31-53-163 ~]#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;tmux attach-session &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; u24
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-02-23-firecracker-microvm/3.png&quot; alt=&quot;tmux 세션 관리&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;참고&quot;&gt;참고&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Firecracker 공식 사이트: &lt;a href=&quot;https://firecracker-microvm.github.io/&quot;&gt;https://firecracker-microvm.github.io/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Firecracker GitHub: &lt;a href=&quot;https://github.com/firecracker-microvm/firecracker&quot;&gt;https://github.com/firecracker-microvm/firecracker&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Firecracker Getting Started: &lt;a href=&quot;https://github.com/firecracker-microvm/firecracker/blob/main/docs/getting-started.md&quot;&gt;https://github.com/firecracker-microvm/firecracker/blob/main/docs/getting-started.md&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Firecracker RootFS &amp;amp; Kernel Setup: &lt;a href=&quot;https://github.com/firecracker-microvm/firecracker/blob/main/docs/rootfs-and-kernel-setup.md&quot;&gt;https://github.com/firecracker-microvm/firecracker/blob/main/docs/rootfs-and-kernel-setup.md&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Firecracker Network Setup: &lt;a href=&quot;https://github.com/firecracker-microvm/firecracker/blob/main/docs/network-setup.md&quot;&gt;https://github.com/firecracker-microvm/firecracker/blob/main/docs/network-setup.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 23 Feb 2026 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/aws/2026/02/23/firecracker-microvm/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/aws/2026/02/23/firecracker-microvm/</guid>
        
        <category>aws</category>
        
        <category>linux</category>
        
        <category>container</category>
        
        
        <category>aws</category>
        
      </item>
    
      <item>
        <title>[AWS] Amazon Bedrock 과 Claude Code 연동 with code-server</title>
        <description>&lt;h1 id=&quot;amazon-bedrock과-claude-code-연동&quot;&gt;Amazon Bedrock과 Claude Code 연동&lt;/h1&gt;

&lt;p&gt;이번 포스팅에서는 AWS EC2 인스턴스에서 Amazon Bedrock을 활용하여 Claude Code를 사용하는 방법에 대해 기록하도록 하겠습니다.&lt;/p&gt;

&lt;p&gt;Claude Code는 Anthropic에서 제공하는 AI 코딩 어시스턴트로, Amazon Bedrock을 통해 AWS 환경에서 안전하게 사용할 수 있습니다. 이를 통해 Anthropic 계정 없이도 AWS IAM 역할 기반 인증으로 Claude Code를 활용할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;테스트-환경&quot;&gt;테스트 환경&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;테스트 환경: Amazon Linux 2023.10.20260202&lt;/li&gt;
  &lt;li&gt;AWS Region: ap-northeast-2&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;iam-역할-생성&quot;&gt;IAM 역할 생성&lt;/h2&gt;

&lt;p&gt;Amazon Bedrock을 사용하기 위해 EC2 인스턴스에 연결할 IAM 역할을 생성합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-02-13-claude/1.png&quot; alt=&quot;IAM 설정 완료 예제&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;trust-policy-json-파일-생성&quot;&gt;Trust Policy JSON 파일 생성&lt;/h3&gt;

&lt;p&gt;아래와 같이 Trust Policy JSON 파일을 생성합니다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;gt; trust-policy.json &amp;lt;&amp;lt; &apos;EOF&apos;
{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Principal&quot;: {
        &quot;Service&quot;: &quot;ec2.amazonaws.com&quot;
      },
      &quot;Action&quot;: &quot;sts:AssumeRole&quot;
    }
  ]
}
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;iam-역할-생성-1&quot;&gt;IAM 역할 생성&lt;/h3&gt;

&lt;p&gt;아래 명령어를 통해 IAM 역할을 생성합니다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;aws iam create-role \
  --role-name Bedrock_Profile \
  --assume-role-policy-document file://trust-policy.json \
  --description &quot;Bedrock_Profile&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;관리형-정책-연결&quot;&gt;관리형 정책 연결&lt;/h3&gt;

&lt;p&gt;Bedrock 및 MCP 서비스 사용을 위한 관리형 정책을 연결합니다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;aws iam attach-role-policy \
  --role-name Bedrock_Profile \
  --policy-arn arn:aws:iam::aws:policy/AmazonBedrockLimitedAccess

aws iam attach-role-policy \
  --role-name Bedrock_Profile \
  --policy-arn arn:aws:iam::aws:policy/AWSMcpServiceActionsFullAccess
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;인스턴스-프로파일-생성&quot;&gt;인스턴스 프로파일 생성&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;aws iam create-instance-profile \
  --instance-profile-name Bedrock_Profile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;역할을-인스턴스-프로파일에-추가&quot;&gt;역할을 인스턴스 프로파일에 추가&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;aws iam add-role-to-instance-profile \
  --instance-profile-name Bedrock_Profile \
  --role-name Bedrock_Profile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 IAM 역할 생성이 완료되면 EC2 인스턴스에 해당 인스턴스 프로파일을 연결합니다.&lt;/p&gt;

&lt;h2 id=&quot;code-server-설치&quot;&gt;code-server 설치&lt;/h2&gt;

&lt;p&gt;브라우저에서 VS Code 환경을 사용하기 위해 code-server를 설치합니다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@ip-172-31-45-222 ~]# curl -fsSL https://code-server.dev/install.sh | sh
Amazon Linux 2023.10.20260202
Installing v4.108.2 of the amd64 rpm package from GitHub.

+ mkdir -p ~/.cache/code-server
+ curl -#fL -o ~/.cache/code-server/code-server-4.108.2-amd64.rpm.incomplete -C - https://github.com/coder/code-server/releases/download/v4.108.2/code-server-4.108.2-amd64.rpm
######################################################################## 100.0%
+ mv ~/.cache/code-server/code-server-4.108.2-amd64.rpm.incomplete ~/.cache/code-server/code-server-4.108.2-amd64.rpm
+ rpm -U ~/.cache/code-server/code-server-4.108.2-amd64.rpm

rpm package has been installed.

To have systemd start code-server now and restart on boot:
  sudo systemctl enable --now code-server@$USER
Or, if you don&apos;t want/need a background service you can run:
  code-server

Deploy code-server for your team with Coder: https://github.com/coder/coder
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;systemd를 통해 code-server 서비스를 활성화합니다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@ip-172-31-45-222 ~]# systemctl enable --now code-server@root
Created symlink /etc/systemd/system/default.target.wants/code-server@root.service → /usr/lib/systemd/system/code-server@.service.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.config/code-server/config.yaml&lt;/code&gt; 에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bind-addr&lt;/code&gt; 를 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0.0.0.0:80&lt;/code&gt; 과 같은 환경에 적합한 설정으로 변경하고 접속을 위한 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;password&lt;/code&gt; 를 확인합니다.&lt;/p&gt;

&lt;h2 id=&quot;claude-code-확장-플러그인-설치&quot;&gt;Claude Code 확장 플러그인 설치&lt;/h2&gt;

&lt;p&gt;위 단계에서 확인 된 정보를 통해 code-server 에 접속하고, code-server의 확장 플러그인에서 Claude Code를 설치합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-02-13-claude/2.png&quot; alt=&quot;Claude Code 확장 플러그인 설치&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-02-13-claude/3.png&quot; alt=&quot;Claude Code 확장 플러그인 설치 완료&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;amazon-bedrock-사용-설정&quot;&gt;Amazon Bedrock 사용 설정&lt;/h2&gt;

&lt;p&gt;먼저 code-server 에 Claude Code가 Amazon Bedrock을 사용하도록 설정합니다. 로그인 프롬프트를 사용안하도록 아래와 같이 설정합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-02-13-claude/4.png&quot; alt=&quot;Disable Login Prompt&quot; /&gt;&lt;/p&gt;

&lt;p&gt;code-server 설정에서 Claude Code가 CLI 모드로 동작하도록 설정하면 브라우저 환경에서도 Claude Code를 사용할 수 있습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-02-13-claude/5.png&quot; alt=&quot;CLI 모드 설정&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Cluade Code CLI 에서 Amazon Bedrock 을 사용하도록 아래 설정을 설정합니다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@ip-172-31-45-222 ~]# cat ~/.claude/settings.json
{
  &quot;$schema&quot;: &quot;https://json.schemastore.org/claude-code-settings.json&quot;,
  &quot;env&quot;: {
    &quot;CLAUDE_CODE_USE_BEDROCK&quot;: &quot;1&quot;,
    &quot;AWS_REGION&quot;: &quot;ap-northeast-2&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;인스턴스 프로파일을 통해 Bedrock에서 Claude 모델이 사용 가능한지 확인합니다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@ip-172-31-45-222 ~]# aws bedrock list-foundation-models | grep &quot;anthropic.claude-opus-4-5-20251101-v1&quot;
            &quot;modelArn&quot;: &quot;arn:aws:bedrock:ap-northeast-2::foundation-model/anthropic.claude-opus-4-5-20251101-v1:0&quot;,
            &quot;modelId&quot;: &quot;anthropic.claude-opus-4-5-20251101-v1:0&quot;,
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;claude-code-cli-설치&quot;&gt;Claude Code CLI 설치&lt;/h2&gt;

&lt;p&gt;터미널에서 Claude Code를 사용하기 위해 CLI를 설치합니다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@ip-172-31-45-222 ~]# curl -fsSL https://claude.ai/install.sh | bash
Setting up Claude Code...

✔ Claude Code successfully installed!

  Version: 2.1.39

  Location: ~/.local/bin/claude


  Next: Run claude --help to get started

✅ Installation complete!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 설치가 완료되면 Claude Code가 정상적으로 로드되는 것을 확인할 수 있습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-02-13-claude/6.png&quot; alt=&quot;code-server with Cluade Code&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;참고&quot;&gt;참고&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Claude Code Third-Party Provider 설정: &lt;a href=&quot;https://code.claude.com/docs/ko/vs-code#use-third-party-providers&quot;&gt;https://code.claude.com/docs/ko/vs-code#use-third-party-providers&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;code-server : &lt;a href=&quot;https://github.com/coder/code-server&quot;&gt;https://github.com/coder/code-server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 13 Feb 2026 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/aws/2026/02/13/claude-code-with-bedrock/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/aws/2026/02/13/claude-code-with-bedrock/</guid>
        
        <category>aws</category>
        
        <category>ai</category>
        
        
        <category>aws</category>
        
      </item>
    
      <item>
        <title>[AI] opencode - Amazon Bedrock과 연동하여 opencode 사용하기</title>
        <description>&lt;h1 id=&quot;opencode-란&quot;&gt;opencode 란?&lt;/h1&gt;

&lt;p&gt;opencode는 터미널에서 사용할 수 있는 AI 기반 코딩 어시스턴트입니다. &lt;br /&gt;
다양한 AI 프로바이더를 지원하며, Amazon Bedrock과 연동하여 AWS 환경에서 손쉽게 AI 코딩 어시스턴트를 활용할 수 있습니다.&lt;/p&gt;

&lt;p&gt;이번 포스팅에서는 opencode를 설치하고 Amazon Bedrock과 연동하여 사용하는 방법에 대해 기록하도록 하겠습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;공식 사이트: &lt;a href=&quot;https://opencode.ai/&quot;&gt;https://opencode.ai/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;테스트-환경&quot;&gt;테스트 환경&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;테스트 환경: Amazon Linux 2023&lt;/li&gt;
  &lt;li&gt;AWS Region: ap-northeast-2&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;설치&quot;&gt;설치&lt;/h1&gt;

&lt;p&gt;아래와 같이 opencode를 설치합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;curl &lt;span class=&quot;nt&quot;&gt;-fsSL&lt;/span&gt; https://opencode.ai/install | bash

Installing opencode version: 1.1.53
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 100%
Successfully added opencode to &lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; /root/.bashrc

                                 ▄
█▀▀█ █▀▀█ █▀▀█ █▀▀▄ █▀▀▀ █▀▀█ █▀▀█ █▀▀█
█░░█ █░░█ █▀▀▀ █░░█ █░░░ █░░█ █░░█ █▀▀▀
▀▀▀▀ █▀▀▀ ▀▀▀▀ ▀  ▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀


OpenCode includes free models, to start:

&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &amp;lt;project&amp;gt;  &lt;span class=&quot;c&quot;&gt;# Open directory&lt;/span&gt;
opencode      &lt;span class=&quot;c&quot;&gt;# Run command&lt;/span&gt;

For more information visit https://opencode.ai/docs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 설치가 완료된 것을 볼 수 있습니다.&lt;/p&gt;

&lt;h1 id=&quot;amazon-bedrock-provider-설정&quot;&gt;Amazon Bedrock Provider 설정&lt;/h1&gt;

&lt;h2 id=&quot;aws-자격-증명-확인&quot;&gt;AWS 자격 증명 확인&lt;/h2&gt;

&lt;p&gt;Amazon Bedrock을 사용하기 위해서는 AWS 자격 증명이 필요합니다. &lt;br /&gt;
저의 경우, EC2 인스턴스 프로파일(IAM Role)을 사용하여 인증하도록 설정하였습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;aws configure list
NAME       : VALUE                    : TYPE             : LOCATION
profile    : &amp;lt;not &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;                : None             : None
access_key : &lt;span class=&quot;k&quot;&gt;****************&lt;/span&gt;1234     : iam-role         :
secret_key : &lt;span class=&quot;k&quot;&gt;****************&lt;/span&gt;5678     : iam-role         :
region     : ap-northeast-2           : imds             :
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;aws-config-설정&quot;&gt;AWS Config 설정&lt;/h2&gt;

&lt;p&gt;아래와 같이 AWS config 파일을 구성합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; ~/.aws/config
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;default]
region &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; ap-northeast-2
credential_source &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; Ec2InstanceMetadata
output &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;opencode-인증-설정&quot;&gt;opencode 인증 설정&lt;/h2&gt;

&lt;p&gt;opencode에서 Amazon Bedrock을 IAM 인증으로 사용하기 위해 아래와 같이 auth.json 파일을 구성합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; ~/.local/share/opencode/auth.json
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;amazon-bedrock&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;type&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;iam&quot;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;opencode-provider-설정&quot;&gt;opencode Provider 설정&lt;/h2&gt;

&lt;p&gt;IAM role 인증이 정상적으로 동작하도록 opencode 설정 파일을 아래와 같이 구성합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; ~/.config/opencode/opencode.json
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$schema&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;https://opencode.ai/config.json&quot;&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;provider&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;amazon-bedrock&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;options&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;region&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;ap-northeast-2&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;profile&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;default&quot;&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;예제-이미지&quot;&gt;예제 이미지&lt;/h2&gt;
&lt;h3 id=&quot;인증-실패&quot;&gt;인증 실패&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-02-09-opencode/fail.png&quot; alt=&quot;인증 실패&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위와 같이 IAM role 인증이 실패하는 경우가 발생하는 경우, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auth.json&lt;/code&gt; 에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;type&lt;/code&gt; 이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iam&lt;/code&gt; 으로 잘 설정이 되어 있는지 확인이 필요합니다.&lt;/p&gt;

&lt;h3 id=&quot;인증-성공&quot;&gt;인증 성공&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-02-09-opencode/done.png&quot; alt=&quot;인증 성공&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위와 같이 API KEY 없이 IAM role 인증으로 Amazon Bedrock 사용이 가능한 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h1 id=&quot;참고&quot;&gt;참고&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;opencode 공식 문서: &lt;a href=&quot;https://opencode.ai/docs&quot;&gt;https://opencode.ai/docs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Amazon Bedrock 문서: &lt;a href=&quot;https://docs.aws.amazon.com/bedrock/&quot;&gt;https://docs.aws.amazon.com/bedrock/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 09 Feb 2026 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/ai/2026/02/09/opencode-with-bedrock/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/ai/2026/02/09/opencode-with-bedrock/</guid>
        
        <category>ai</category>
        
        <category>aws</category>
        
        
        <category>ai</category>
        
      </item>
    
      <item>
        <title>[Linux] ISC DHCP 에서 Kea DHCP 로 마이그레이션 (Docker)</title>
        <description>&lt;h1 id=&quot;isc-dhcp-에서-kea-dhcp-로-마이그레이션-docker&quot;&gt;ISC DHCP 에서 Kea DHCP 로 마이그레이션 (Docker)&lt;/h1&gt;

&lt;h2 id=&quot;isc-dhcp-eol-end-of-life&quot;&gt;ISC DHCP EOL (End of Life)&lt;/h2&gt;

&lt;p&gt;ISC(Internet Systems Consortium) 는 2022년 말에 ISC DHCP (dhcpd) 의 유지보수 종료를 공식 발표하였습니다. &lt;br /&gt;
1995년부터 약 30년간 사용되어 온 ISC DHCP 는 더 이상 업데이트가 제공되지 않으며, 심각한 보안 취약점이 발견되더라도 패치가 제공되지 않습니다.&lt;/p&gt;

&lt;p&gt;ISC 는 후속 DHCP 서버로 Kea DHCP 를 권장하고 있으며, 마이그레이션을 위한 도구인 KeaMA(Kea Migration Assistant) 와 공식 Docker 이미지도 제공하고 있습니다.&lt;/p&gt;

&lt;p&gt;이번 포스팅에서는 기존 ISC DHCP 설정을 Docker 기반의 Kea DHCP 로 마이그레이션하는 방법에 대해 기록하도록 하겠습니다.&lt;/p&gt;

&lt;h2 id=&quot;kea-dhcp-란&quot;&gt;Kea DHCP 란?&lt;/h2&gt;

&lt;p&gt;Kea DHCP 는 ISC 에서 개발한 차세대 오픈소스 DHCP 서버입니다. &lt;br /&gt;
ISC DHCP 와 비교하여 아래와 같은 특징이 있습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;JSON 기반 설정 파일 형식&lt;/li&gt;
  &lt;li&gt;REST API 를 통한 원격 관리 지원 (kea-ctrl-agent)&lt;/li&gt;
  &lt;li&gt;데이터베이스 백엔드 지원 (MySQL, PostgreSQL)&lt;/li&gt;
  &lt;li&gt;멀티스레드 지원으로 높은 성능&lt;/li&gt;
  &lt;li&gt;DHCPv4, DHCPv6, Dynamic DNS 가 별도 프로세스로 분리&lt;/li&gt;
  &lt;li&gt;Hook 라이브러리를 통한 기능 확장&lt;/li&gt;
  &lt;li&gt;High Availability 지원&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;테스트-환경&quot;&gt;테스트 환경&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;테스트 환경: Amazon Linux 2&lt;/li&gt;
  &lt;li&gt;기존 DHCP 서버: ISC DHCP (dhcpd)&lt;/li&gt;
  &lt;li&gt;마이그레이션 대상: Kea DHCP (Docker Container)&lt;/li&gt;
  &lt;li&gt;Kea DHCP 이미지: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker.cloudsmith.io/isc/docker/kea-dhcp4&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;step-1-기존-isc-dhcp-설정-확인-및-백업&quot;&gt;Step 1) 기존 ISC DHCP 설정 확인 및 백업&lt;/h2&gt;

&lt;p&gt;마이그레이션 전 반드시 기존 설정 파일과 Lease 파일을 백업합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo cp&lt;/span&gt; /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.backup
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo cp&lt;/span&gt; /var/lib/dhcpd/dhcpd.leases /var/lib/dhcpd/dhcpd.leases.backup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;기존 ISC DHCP 설정 파일을 확인합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; /etc/dhcp/dhcpd.conf
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# DHCP Server Configuration file.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   see /usr/share/doc/dhcp*/dhcpd.conf.example&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   see dhcpd.conf(5) man page&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Global configuration ####################################&lt;/span&gt;
option domain-name &lt;span class=&quot;s2&quot;&gt;&quot;chhanz.xyz&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
default-lease-time 3600&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
max-lease-time 7200&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
authoritative&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# subnet configuration ####################################&lt;/span&gt;
subnet 10.100.200.0 netmask 255.255.255.0 &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
option routers                  10.100.200.1&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
option subnet-mask              255.255.255.0&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
option domain-name-servers      1.1.1.1&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
option time-offset              &lt;span class=&quot;nt&quot;&gt;-18000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
range 10.100.200.100 10.100.200.200&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

host pve1.chhanz.xyz &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
hardware ethernet BC:24:11:F3:9F:00&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
fixed-address 10.100.200.50&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

host pve2.chhanz.xyz &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
hardware ethernet BC:24:11:D7:AA:55&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
fixed-address 10.100.200.51&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

host pve3.chhanz.xyz &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
hardware ethernet BC:24:11:C9:53:86&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
fixed-address 10.100.200.52&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;10.100.200.0/24&lt;/code&gt; 서브넷에 대한 DHCP 설정과 Proxmox 노드 3대에 대한 고정 IP 할당 설정이 되어 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;step-2-kea-dhcp-docker-이미지-pull&quot;&gt;Step 2) Kea DHCP Docker 이미지 Pull&lt;/h2&gt;

&lt;p&gt;ISC 에서 제공하는 공식 Kea DHCP Docker 이미지를 가져옵니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# docker pull docker.cloudsmith.io/isc/docker/kea-dhcp4
Using default tag: latest
latest: Pulling from isc/docker/kea-dhcp4
f637881d1138: Pull &lt;span class=&quot;nb&quot;&gt;complete
&lt;/span&gt;d39b6622b069: Pull &lt;span class=&quot;nb&quot;&gt;complete
&lt;/span&gt;307f453979a4: Pull &lt;span class=&quot;nb&quot;&gt;complete
&lt;/span&gt;Digest: sha256:fdc40a60b0c392247d2411fb445b88b9d204d929ed4e8431a235edcefbe6a0bd
Status: Downloaded newer image &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;docker.cloudsmith.io/isc/docker/kea-dhcp4:latest
docker.cloudsmith.io/isc/docker/kea-dhcp4:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 이미지가 정상적으로 다운로드 된 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;step-3-keama-docker-를-이용한-설정-변환&quot;&gt;Step 3) KeaMA Docker 를 이용한 설정 변환&lt;/h2&gt;

&lt;p&gt;ISC 에서 제공하는 KeaMA(Kea Migration Assistant) Docker 이미지를 사용하여 기존 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dhcpd.conf&lt;/code&gt; 를 Kea JSON 설정 파일로 자동 변환합니다.&lt;/p&gt;

&lt;p&gt;먼저 KeaMA Docker 이미지를 가져옵니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# docker pull docker.cloudsmith.io/isc/keama/keama:4.5.0
4.5.0: Pulling from isc/keama/keama
4693057ce236: Pull &lt;span class=&quot;nb&quot;&gt;complete
&lt;/span&gt;9ad60c84bfbe: Pull &lt;span class=&quot;nb&quot;&gt;complete
&lt;/span&gt;ce0f4c80e9b7: Pull &lt;span class=&quot;nb&quot;&gt;complete&lt;/span&gt;
...생략
Digest: sha256:1ce87368b16d528a0f6c64b48e5316caaa21bccca99bfe7a3e9b368eaa6b1f1f
Status: Downloaded newer image &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;docker.cloudsmith.io/isc/keama/keama:4.5.0
docker.cloudsmith.io/isc/keama/keama:4.5.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;변환 결과를 저장할 디렉토리를 생성하고 권한을 설정합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# &lt;span class=&quot;nb&quot;&gt;mkdir &lt;/span&gt;convert
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# &lt;span class=&quot;nb&quot;&gt;chown &lt;/span&gt;1000:1000 convert
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;아래와 같이 KeaMA 컨테이너를 실행하여 설정 파일을 변환합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# docker run &lt;span class=&quot;nt&quot;&gt;-ti&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--rm&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; /etc/dhcp/dhcpd.conf:/home/keama/app/dhcpd.conf &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; /root/convert:/home/keama/app/convert &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
	docker.cloudsmith.io/isc/keama/keama:4.5.0 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
	/home/keama/app/keama &lt;span class=&quot;nt&quot;&gt;-4&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; /home/keama/app/dhcpd.conf &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; /home/keama/app/convert/kea-dhcpd.conf
KEAMA 4.5.0
Reading isc-dhcp config &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;IPv4 mode&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from /home/keama/app/dhcpd.conf, writing Kea JSON config to /home/keama/app/convert/kea-dhcpd.conf.
Started parsing new subnet declaration &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;line 15
Converted subnet 10.100.200.0/24 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lines 15 to 22&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;...
Parsing new host declaration at line 24
Converted host hw-address:bc:24:11:f3:9f:00 &lt;span class=&quot;nb&quot;&gt;hostname&lt;/span&gt;:pve1.chhanz.xyz ip-address:10.100.200.50  &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lines 24 to 27&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Parsing new host declaration at line 28
Converted host hw-address:bc:24:11:d7:aa:55 &lt;span class=&quot;nb&quot;&gt;hostname&lt;/span&gt;:pve2.chhanz.xyz ip-address:10.100.200.51  &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lines 28 to 31&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Parsing new host declaration at line 32
Converted host hw-address:bc:24:11:c9:53:86 &lt;span class=&quot;nb&quot;&gt;hostname&lt;/span&gt;:pve3.chhanz.xyz ip-address:10.100.200.52  &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lines 32 to 35&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Parsed 36 lines from the input &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;ISC DHCP config&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; /home/keama/app/dhcpd.conf file.
Wrote 1964 bytes to Kea JSON output /home/keama/app/convert/kea-dhcpd.conf file.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 서브넷 1개와 호스트 예약 3개가 정상적으로 변환된 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h3 id=&quot;변환된-설정-파일-확인&quot;&gt;변환된 설정 파일 확인&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# &lt;span class=&quot;nb&quot;&gt;cat &lt;/span&gt;convert/kea-dhcpd.conf
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;# DHCP Server Configuration file.&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;#   see /usr/share/doc/dhcp*/dhcpd.conf.example&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;#   see dhcpd.conf(5) man page&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;# Global configuration ####################################&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;#option domain-name &quot;chhanz.xyz&quot;;&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;#option domain-name-servers ns.chhanz.xyz;&lt;/span&gt;
  /// This configuration declares some subnets but has no interfaces-config
  /// Reference Kea &lt;span class=&quot;c&quot;&gt;#245&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;Dhcp4&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;valid-lifetime&quot;&lt;/span&gt;: 3600,
    &lt;span class=&quot;s2&quot;&gt;&quot;max-valid-lifetime&quot;&lt;/span&gt;: 7200,
    &lt;span class=&quot;s2&quot;&gt;&quot;authoritative&quot;&lt;/span&gt;: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;subnet4&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;c&quot;&gt;# subnet configuration ####################################&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;id&quot;&lt;/span&gt;: 1,
        &lt;span class=&quot;s2&quot;&gt;&quot;subnet&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;10.100.200.0/24&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;option-data&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;space&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;dhcp4&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;routers&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;code&quot;&lt;/span&gt;: 3,
            &lt;span class=&quot;s2&quot;&gt;&quot;data&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;10.100.200.1&quot;&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
          &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;space&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;dhcp4&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;subnet-mask&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;code&quot;&lt;/span&gt;: 1,
            &lt;span class=&quot;s2&quot;&gt;&quot;data&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;255.255.255.0&quot;&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
          &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;space&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;dhcp4&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;domain-name-servers&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;code&quot;&lt;/span&gt;: 6,
            &lt;span class=&quot;s2&quot;&gt;&quot;data&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;1.1.1.1&quot;&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
          &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;space&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;dhcp4&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;time-offset&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;code&quot;&lt;/span&gt;: 2,
            &lt;span class=&quot;s2&quot;&gt;&quot;data&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;-18000&quot;&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;pools&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;pool&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;10.100.200.100 - 10.100.200.200&quot;&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;host-reservation-identifiers&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;hw-address&quot;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;reservation-mode&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;global&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;reservations&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;hostname&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;pve1.chhanz.xyz&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;hw-address&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;bc:24:11:f3:9f:00&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;ip-address&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;10.100.200.50&quot;&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
      &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;hostname&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;pve2.chhanz.xyz&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;hw-address&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;bc:24:11:d7:aa:55&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;ip-address&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;10.100.200.51&quot;&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
      &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;hostname&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;pve3.chhanz.xyz&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;hw-address&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;bc:24:11:c9:53:86&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;ip-address&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;10.100.200.52&quot;&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;참고 : KeaMA 가 변환한 결과에는 주석(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;///&lt;/code&gt;) 과 함께 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;interfaces-config&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lease-database&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loggers&lt;/code&gt; 등의 항목이 포함되어 있지 않습니다. &lt;br /&gt;
이 항목들은 수동으로 추가해야 하며, 주석도 제거해야 합니다. (Kea 는 표준 JSON 을 사용하므로 주석을 지원하지 않습니다)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;step-4-변환된-설정-파일-수정&quot;&gt;Step 4) 변환된 설정 파일 수정&lt;/h2&gt;

&lt;p&gt;KeaMA 가 변환한 설정 파일은 그대로 사용할 수 없으며, 아래와 같은 수정이 필요합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# &lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; /etc/kea/config
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# &lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; /etc/kea/leases
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;변환된 파일을 복사하고 수정합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# &lt;span class=&quot;nb&quot;&gt;cp &lt;/span&gt;convert/kea-dhcpd.conf /etc/kea/config/kea-dhcp4.conf
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# vi /etc/kea/config/kea-dhcp4.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;아래와 같은 항목들을 수정합니다.&lt;/p&gt;

&lt;h3 id=&quot;1-주석-제거&quot;&gt;1) 주석 제거&lt;/h3&gt;

&lt;p&gt;Kea 는 표준 JSON 형식을 사용하므로 KeaMA 가 남긴 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;///&lt;/code&gt; 주석을 모두 제거합니다.&lt;/p&gt;

&lt;h3 id=&quot;2-interfaces-config-control-socket-lease-database-추가&quot;&gt;2) &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;interfaces-config&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;control-socket&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lease-database&lt;/code&gt; 추가&lt;/h3&gt;

&lt;p&gt;KeaMA 변환 결과에는 포함되지 않는 항목들을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dhcp4&lt;/code&gt; 블록 상단에 추가합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;s2&quot;&gt;&quot;interfaces-config&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;interfaces&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;eth1&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
      &lt;span class=&quot;s2&quot;&gt;&quot;dhcp-socket-type&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;raw&quot;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;control-socket&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;socket-type&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;unix&quot;&lt;/span&gt;,
      &lt;span class=&quot;s2&quot;&gt;&quot;socket-name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;/var/run/kea/kea4-ctrl-socket&quot;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;lease-database&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;type&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;memfile&quot;&lt;/span&gt;,
      &lt;span class=&quot;s2&quot;&gt;&quot;persist&quot;&lt;/span&gt;: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;,
      &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;/var/lib/kea/kea-leases4.csv&quot;&lt;/span&gt;,
      &lt;span class=&quot;s2&quot;&gt;&quot;lfc-interval&quot;&lt;/span&gt;: 3600
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;3-option-data-에서-불필요한-필드-제거&quot;&gt;3) &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;option-data&lt;/code&gt; 에서 불필요한 필드 제거&lt;/h3&gt;

&lt;p&gt;KeaMA 가 생성한 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;space&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;code&lt;/code&gt; 필드는 생략 가능하므로 간결하게 정리합니다. &lt;br /&gt;
또한 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;subnet-mask&lt;/code&gt; 옵션은 Kea 가 서브넷 정의에서 자동으로 처리하므로 제거합니다.&lt;/p&gt;

&lt;p&gt;변경 전 (KeaMA 변환 결과):&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;          &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;space&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;dhcp4&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;routers&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;code&quot;&lt;/span&gt;: 3,
            &lt;span class=&quot;s2&quot;&gt;&quot;data&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;10.100.200.1&quot;&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;변경 후:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;          &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;routers&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;data&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;10.100.200.1&quot;&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;4-reservation-mode-를-신규-키워드로-변경&quot;&gt;4) &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reservation-mode&lt;/code&gt; 를 신규 키워드로 변경&lt;/h3&gt;

&lt;p&gt;Kea 2.6 이상에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reservation-mode&lt;/code&gt; 는 deprecated 되었습니다. &lt;br /&gt;
아래와 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reservations-global&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reservations-in-subnet&lt;/code&gt; 으로 변경합니다.&lt;/p&gt;

&lt;p&gt;변경 전 (KeaMA 변환 결과):&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;s2&quot;&gt;&quot;reservation-mode&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;global&quot;&lt;/span&gt;,
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;변경 후:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;s2&quot;&gt;&quot;reservations-global&quot;&lt;/span&gt;: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;reservations-in-subnet&quot;&lt;/span&gt;: &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;,
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;5-loggers-추가&quot;&gt;5) &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loggers&lt;/code&gt; 추가&lt;/h3&gt;

&lt;p&gt;Docker 환경에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker logs&lt;/code&gt; 로 로그를 확인할 수 있도록 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stdout&lt;/code&gt; 출력 설정을 추가합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;s2&quot;&gt;&quot;loggers&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;kea-dhcp4&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;output-options&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;output&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;stdout&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;flush&quot;&lt;/span&gt;: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;severity&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;INFO&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;debuglevel&quot;&lt;/span&gt;: 0
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;최종-설정-파일&quot;&gt;최종 설정 파일&lt;/h3&gt;

&lt;p&gt;위 수정 사항을 모두 반영한 최종 설정 파일은 아래와 같습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# &lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; /etc/kea/config/kea-dhcp4.conf
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;Dhcp4&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;interfaces-config&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;interfaces&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;eth1&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
      &lt;span class=&quot;s2&quot;&gt;&quot;dhcp-socket-type&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;raw&quot;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;control-socket&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;socket-type&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;unix&quot;&lt;/span&gt;,
      &lt;span class=&quot;s2&quot;&gt;&quot;socket-name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;/var/run/kea/kea4-ctrl-socket&quot;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;lease-database&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;type&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;memfile&quot;&lt;/span&gt;,
      &lt;span class=&quot;s2&quot;&gt;&quot;persist&quot;&lt;/span&gt;: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;,
      &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;/var/lib/kea/kea-leases4.csv&quot;&lt;/span&gt;,
      &lt;span class=&quot;s2&quot;&gt;&quot;lfc-interval&quot;&lt;/span&gt;: 3600
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;authoritative&quot;&lt;/span&gt;: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;valid-lifetime&quot;&lt;/span&gt;: 3600,
    &lt;span class=&quot;s2&quot;&gt;&quot;max-valid-lifetime&quot;&lt;/span&gt;: 7200,
    &lt;span class=&quot;s2&quot;&gt;&quot;subnet4&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;id&quot;&lt;/span&gt;: 1,
        &lt;span class=&quot;s2&quot;&gt;&quot;subnet&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;10.100.200.0/24&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;option-data&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;routers&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;data&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;10.100.200.1&quot;&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
          &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;domain-name-servers&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;data&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;1.1.1.1&quot;&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
          &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;time-offset&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;data&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;-18000&quot;&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;pools&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;pool&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;10.100.200.100 - 10.100.200.200&quot;&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;host-reservation-identifiers&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;hw-address&quot;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;reservations-global&quot;&lt;/span&gt;: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;reservations-in-subnet&quot;&lt;/span&gt;: &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;reservations&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;hostname&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;pve1.chhanz.xyz&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;hw-address&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;bc:24:11:f3:9f:00&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;ip-address&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;10.100.200.50&quot;&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
      &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;hostname&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;pve2.chhanz.xyz&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;hw-address&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;bc:24:11:d7:aa:55&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;ip-address&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;10.100.200.51&quot;&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
      &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;hostname&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;pve3.chhanz.xyz&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;hw-address&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;bc:24:11:c9:53:86&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;ip-address&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;10.100.200.52&quot;&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;loggers&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;kea-dhcp4&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;output-options&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;output&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;stdout&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;flush&quot;&lt;/span&gt;: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;severity&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;INFO&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;debuglevel&quot;&lt;/span&gt;: 0
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;isc-dhcp-와-kea-dhcp-설정-비교&quot;&gt;ISC DHCP 와 Kea DHCP 설정 비교&lt;/h3&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;항목&lt;/th&gt;
      &lt;th&gt;ISC DHCP (dhcpd.conf)&lt;/th&gt;
      &lt;th&gt;Kea DHCP (kea-dhcp4.conf)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;설정 형식&lt;/td&gt;
      &lt;td&gt;자체 문법&lt;/td&gt;
      &lt;td&gt;JSON&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Subnet 선언&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;subnet 10.100.200.0 netmask 255.255.255.0&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;subnet&quot;: &quot;10.100.200.0/24&quot;&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;IP 범위&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;range 10.100.200.100 10.100.200.200;&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;pool&quot;: &quot;10.100.200.100 - 10.100.200.200&quot;&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;고정 IP 할당&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;host pve1 { hardware ethernet ...; fixed-address ...; }&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;reservations&quot;: [{&quot;hw-address&quot;: &quot;...&quot;, &quot;ip-address&quot;: &quot;...&quot;}]&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;옵션 설정&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;option routers 10.100.200.1;&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;option-data&quot;: [{&quot;name&quot;: &quot;routers&quot;, &quot;data&quot;: &quot;10.100.200.1&quot;}]&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Lease 저장&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/lib/dhcpd/dhcpd.leases&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/lib/kea/kea-leases4.csv&lt;/code&gt; 또는 DB&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;서비스명&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dhcpd&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kea-dhcp4&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;step-5-설정-파일-검증&quot;&gt;Step 5) 설정 파일 검증&lt;/h2&gt;

&lt;p&gt;컨테이너를 실행하기 전에 설정 파일의 문법을 검증합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# docker run &lt;span class=&quot;nt&quot;&gt;--rm&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; /etc/kea/config:/etc/kea &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    docker.cloudsmith.io/isc/docker/kea-dhcp4 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    kea-dhcp4 &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; /etc/kea/kea-dhcp4.conf
2026-02-09 06:04:14.319 WARN  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;kea-dhcp4.dhcpsrv/1.140164228530912]
DHCPSRV_MT_DISABLED_QUEUE_CONTROL disabling dhcp queue control when multi-threading is enabled.
2026-02-09 06:04:14.319 WARN  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;kea-dhcp4.dhcp4/1.140164228530912]
DHCP4_RESERVATIONS_LOOKUP_FIRST_ENABLED Multi-threading is enabled and host reservations lookup is always performed first.
2026-02-09 06:04:14.319 INFO  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;kea-dhcp4.dhcpsrv/1.140164228530912]
DHCPSRV_CFGMGR_NEW_SUBNET4 a new subnet has been added to configuration: 10.100.200.0/24 with params: valid-lifetime&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;3600
2026-02-09 06:04:14.319 INFO  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;kea-dhcp4.dhcpsrv/1.140164228530912]
DHCPSRV_CFGMGR_SOCKET_TYPE_SELECT using socket &lt;span class=&quot;nb&quot;&gt;type &lt;/span&gt;raw
...생략
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DHCPSRV_CFGMGR_NEW_SUBNET4&lt;/code&gt; 로그에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;10.100.200.0/24&lt;/code&gt; 서브넷이 정상적으로 추가된 것을 확인 할 수 있습니다. &lt;br /&gt;
ERROR 없이 출력이 완료되면 설정 파일에 문제가 없는 것입니다.&lt;/p&gt;

&lt;h2 id=&quot;step-6-기존-isc-dhcp-서비스-중지&quot;&gt;Step 6) 기존 ISC DHCP 서비스 중지&lt;/h2&gt;

&lt;p&gt;Kea DHCP 컨테이너를 시작하기 전에 기존 ISC DHCP 서비스를 중지합니다. &lt;br /&gt;
동일한 포트(UDP 67/68) 를 사용하기 때문에 반드시 기존 서비스를 먼저 중지해야 합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# systemctl stop dhcpd
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# systemctl disable dhcpd
Removed symlink /etc/systemd/system/multi-user.target.wants/dhcpd.service.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-7-kea-dhcp-컨테이너-실행&quot;&gt;Step 7) Kea DHCP 컨테이너 실행&lt;/h2&gt;

&lt;p&gt;아래와 같이 Kea DHCP 컨테이너를 실행합니다. &lt;br /&gt;
DHCP 서버는 브로드캐스트 패킷을 수신해야 하므로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--net host&lt;/code&gt; 옵션을 사용합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# docker run &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt; kea-dhcp4 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--restart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;always &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--net&lt;/span&gt; host &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; /etc/kea/config:/etc/kea &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; /etc/kea/leases:/var/lib/kea &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    docker.cloudsmith.io/isc/docker/kea-dhcp4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;컨테이너 실행 상태를 확인합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# docker ps
CONTAINER ID   IMAGE                                          COMMAND                  CREATED         STATUS         PORTS   NAMES
a1b2c3d4e5f6   docker.cloudsmith.io/isc/docker/kea-dhcp4      &lt;span class=&quot;s2&quot;&gt;&quot;/usr/sbin/kea-dhcp4…&quot;&lt;/span&gt;   5 seconds ago   Up 3 seconds           kea-dhcp4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 Kea DHCP 컨테이너가 정상적으로 실행 중인 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;step-8-동작-확인&quot;&gt;Step 8) 동작 확인&lt;/h2&gt;

&lt;h3 id=&quot;로그-확인&quot;&gt;로그 확인&lt;/h3&gt;

&lt;p&gt;아래와 같이 컨테이너 로그를 통해 Kea DHCP 서버의 동작 상태를 확인합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# docker logs &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; kea-dhcp4
2026-02-09 06:13:00.211 INFO  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;kea-dhcp4.dhcp4/1.140589193589472]
DHCP4_STARTING Kea DHCPv4 server version 3.0.2 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;stable&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; starting
...생략
2026-02-09 06:13:00.213 INFO  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;kea-dhcp4.dhcpsrv/1.140589193589472]
DHCPSRV_CFGMGR_ADD_IFACE listening on interface eth1
2026-02-09 06:13:00.213 INFO  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;kea-dhcp4.dhcp4/1.140589193589472]
DHCP4_CONFIG_COMPLETE DHCPv4 server has completed configuration: added IPv4 subnets: 1&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; DDNS: disabled
...생략
2026-02-09 06:13:00.251 INFO  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;kea-dhcp4.dhcp4/1.140589193589472]
DHCP4_MULTI_THREADING_INFO enabled: &lt;span class=&quot;nb&quot;&gt;yes&lt;/span&gt;, number of threads: 2, queue size: 64
2026-02-09 06:13:00.251 INFO  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;kea-dhcp4.dhcp4/1.140589193589472]
DHCP4_STARTED Kea DHCPv4 server version 3.0.2 started
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 Kea DHCP 서버 버전 3.0.2 가 정상적으로 시작된 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;p&gt;DHCP 클라이언트가 IP 를 요청하면 아래와 같은 로그를 확인 할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;2026-02-09 06:13:12.733 INFO  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;kea-dhcp4.packets/1.140589172878136]
DHCP4_PACKET_RECEIVED &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;hwtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1 bc:24:11:27:12:8c], &lt;span class=&quot;nv&quot;&gt;cid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=[&lt;/span&gt;no info], &lt;span class=&quot;nv&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0x9ae58e2a:
DHCPDISCOVER &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type &lt;/span&gt;1&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; received from 0.0.0.0 to 255.255.255.255 on interface eth1
2026-02-09 06:13:12.733 INFO  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;kea-dhcp4.leases/1.140589172878136]
DHCP4_LEASE_OFFER &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;hwtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1 bc:24:11:27:12:8c], &lt;span class=&quot;nv&quot;&gt;cid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=[&lt;/span&gt;no info], &lt;span class=&quot;nv&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0x9ae58e2a:
lease 10.100.200.100 will be offered
...생략
2026-02-09 06:13:12.734 INFO  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;kea-dhcp4.leases/1.140589173021496]
DHCP4_LEASE_ALLOC &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;hwtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1 bc:24:11:27:12:8c], &lt;span class=&quot;nv&quot;&gt;cid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=[&lt;/span&gt;no info], &lt;span class=&quot;nv&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0x9ae58e2a:
lease 10.100.200.100 has been allocated &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;3600 seconds
2026-02-09 06:13:12.734 INFO  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;kea-dhcp4.packets/1.140589173021496]
DHCP4_PACKET_SEND &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;hwtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1 bc:24:11:27:12:8c], &lt;span class=&quot;nv&quot;&gt;cid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=[&lt;/span&gt;no info], &lt;span class=&quot;nv&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0x9ae58e2a:
trying to send packet DHCPACK &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type &lt;/span&gt;5&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from 10.100.200.1:67 to 10.100.200.100:68 on interface eth1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 DHCPDISCOVER → DHCPOFFER → DHCPREQUEST → DHCPACK 과정을 거쳐 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;10.100.200.100&lt;/code&gt; IP 가 정상적으로 할당되는 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h3 id=&quot;lease-파일-확인&quot;&gt;Lease 파일 확인&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# &lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; /etc/kea/leases/kea-leases4.csv
address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context,pool_id
10.100.200.100,bc:24:11:27:12:8c,,3600,1770621192,1,0,0,rhel7,0,,0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 DHCP IP 가 정상적으로 할당되는 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;설정-변경-시-컨테이너-재시작&quot;&gt;설정 변경 시 컨테이너 재시작&lt;/h2&gt;

&lt;p&gt;설정 파일을 수정한 후에는 아래와 같이 컨테이너를 재시작합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# vi /etc/kea/config/kea-dhcp4.conf
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@chhan-al2 ~]# docker restart kea-dhcp4
kea-dhcp4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;참고&quot;&gt;참고&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;ISC DHCP 마이그레이션 가이드: &lt;a href=&quot;https://www.isc.org/dhcp_migration/&quot;&gt;https://www.isc.org/dhcp_migration/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;KeaMA 웹 인터페이스: &lt;a href=&quot;https://dhcp.isc.org/&quot;&gt;https://dhcp.isc.org/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;KeaMA Docker 이미지: &lt;a href=&quot;https://cloudsmith.io/~isc/repos/keama/packages/&quot;&gt;https://cloudsmith.io/~isc/repos/keama/packages/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Kea DHCP 공식 문서: &lt;a href=&quot;https://kea.readthedocs.io/&quot;&gt;https://kea.readthedocs.io/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Kea Docker 이미지: &lt;a href=&quot;https://cloudsmith.io/~isc/repos/docker/packages/&quot;&gt;https://cloudsmith.io/~isc/repos/docker/packages/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;KeaMA 매뉴얼: &lt;a href=&quot;https://kb.isc.org/docs/kea-migration-assistant&quot;&gt;https://kb.isc.org/docs/kea-migration-assistant&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;이전 포스팅 - DHCP 서버 구성: &lt;a href=&quot;https://tech.chhanz.xyz/linux/2020/11/17/configuration-dhcp/&quot;&gt;https://tech.chhanz.xyz/linux/2020/11/17/configuration-dhcp/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 09 Feb 2026 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/linux/2026/02/09/migration-isc-dhcp-to-kea-dhcp/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/linux/2026/02/09/migration-isc-dhcp-to-kea-dhcp/</guid>
        
        <category>linux</category>
        
        <category>docker</category>
        
        
        <category>linux</category>
        
      </item>
    
      <item>
        <title>[OpenWebUI] SQLite to PostgreSQL Migration</title>
        <description>&lt;h1 id=&quot;open-webui---sqlite-to-postgresql-migration&quot;&gt;Open WebUI - SQLite to PostgreSQL Migration&lt;/h1&gt;

&lt;h2 id=&quot;open-webui-란&quot;&gt;Open WebUI 란?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/open-webui/open-webui&quot;&gt;Open WebUI&lt;/a&gt; 는 다양한 LLM(Large Language Model) 을 웹 브라우저에서 편리하게 사용할 수 있도록 해주는 오픈소스 웹 인터페이스입니다.  &lt;br /&gt;
기본적으로 데이터 저장소로 SQLite 를 사용하지만, 다수의 사용자가 동시에 접근하는 환경에서는 SQLite 의 동시 접근성 한계로 인해 데이터베이스 잠금(lock) 이슈가 발생할 수 있습니다.&lt;/p&gt;

&lt;p&gt;이번 포스팅에서는 이러한 SQLite 의 한계를 해결하기 위해 Open WebUI 의 데이터베이스를 PostgreSQL 로 마이그레이션하는 방법에 대해 기록하도록 하겠습니다.&lt;/p&gt;

&lt;h2 id=&quot;테스트-환경&quot;&gt;테스트 환경&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;항목&lt;/th&gt;
      &lt;th&gt;내용&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;OS&lt;/td&gt;
      &lt;td&gt;Amazon Linux 2023&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Open WebUI&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ghcr.io/open-webui/open-webui:main&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;PostgreSQL&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postgres:18-alpine&lt;/code&gt; (Docker)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Migration Tool&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/taylorwilsdon/open-webui-postgres-migration&quot;&gt;open-webui-postgres-migration&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;사전-준비---postgresql-구성&quot;&gt;사전 준비 - PostgreSQL 구성&lt;/h2&gt;

&lt;p&gt;먼저 마이그레이션 대상이 될 PostgreSQL 을 Docker Compose 로 구성합니다. &lt;br /&gt;
아래와 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compose.yaml&lt;/code&gt; 파일을 작성합니다.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;$ cat pgsql/compose.yaml&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;postgres:18-alpine&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;always&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;shm_size&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;512mb&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/root/data/pgsql:/var/lib/postgresql/data&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;POSTGRES_USER&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;postgres&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;password&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;POSTGRES_DB&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;postgres&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;5432:5432&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;아래 명령어를 통해 PostgreSQL 컨테이너를 시작합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;pgsql &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker compose up &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-1-postgresql-데이터베이스-초기화-bootstrap&quot;&gt;Step 1) PostgreSQL 데이터베이스 초기화 (Bootstrap)&lt;/h2&gt;

&lt;p&gt;Open WebUI 가 사용하는 테이블 스키마를 PostgreSQL 에 생성하기 위해, 임시로 Open WebUI 를 PostgreSQL 에 연결하여 구동합니다. &lt;br /&gt;
이 과정을 통해 Open WebUI 가 자동으로 필요한 테이블을 생성합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat &lt;/span&gt;open-webui-imsi.sh
&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;

docker run &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--restart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;always &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;DATABASE_URL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;postgres://&lt;span class=&quot;s1&quot;&gt;&apos;postgres&apos;&lt;/span&gt;:&lt;span class=&quot;s1&quot;&gt;&apos;passwd&apos;&lt;/span&gt;@&amp;lt;host ip&amp;gt;:5432/postgres &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt; open-webui-imsi &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    ghcr.io/open-webui/open-webui:main
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 스크립트를 실행하여 임시 컨테이너를 구동합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;bash open-webui-imsi.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;테이블 생성이 완료되면 임시 컨테이너를 중지하고 삭제합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;docker stop open-webui-imsi &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker &lt;span class=&quot;nb&quot;&gt;rm &lt;/span&gt;open-webui-imsi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-2-기존-sqlite-데이터베이스-백업&quot;&gt;Step 2) 기존 SQLite 데이터베이스 백업&lt;/h2&gt;

&lt;p&gt;마이그레이션 진행 전 반드시 기존 SQLite 데이터베이스를 백업합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cp&lt;/span&gt; /root/data/webui.db /root/data/webui.db.backup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;또한 기존 Open WebUI 컨테이너를 중지하여 데이터 정합성을 확보합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;docker stop open-webui
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-3-마이그레이션-도구-설치&quot;&gt;Step 3) 마이그레이션 도구 설치&lt;/h2&gt;

&lt;p&gt;마이그레이션에는 &lt;a href=&quot;https://github.com/taylorwilsdon/open-webui-postgres-migration&quot;&gt;open-webui-postgres-migration&lt;/a&gt; 도구를 사용합니다. &lt;br /&gt;
아래와 같이 도구를 설치합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git clone https://github.com/taylorwilsdon/open-webui-postgres-migration.git
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;open-webui-postgres-migration
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;python &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; venv venv
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;source &lt;/span&gt;venv/bin/activate
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;venv&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;pip &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-4-마이그레이션-실행&quot;&gt;Step 4) 마이그레이션 실행&lt;/h2&gt;

&lt;h3 id=&quot;foreign-key-check-에러-해결&quot;&gt;Foreign Key Check 에러 해결&lt;/h3&gt;

&lt;p&gt;마이그레이션 도구를 실행하면 SQLite 데이터베이스의 무결성 검사(Integrity Check) 를 수행합니다. &lt;br /&gt;
이 과정에서 아래와 같이 &lt;strong&gt;Foreign Key Check 에러&lt;/strong&gt;가 발생할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(venv) $ python migrate.py
╭──────────────────────────────────────────────────────────────────────╮
│ SQLite Database Configuration                                        │
╰──────────────────────────────────────────────────────────────────────╯
SQLite database path (webui.db): /root/data/webui.db

✓ Valid SQLite database (version 3.40.0)
╭──────────────────────────────────────────────────────────────────────╮
│ Running SQLite Database Integrity Check                               │
╰──────────────────────────────────────────────────────────────────────╯
Failed Foreign Key Check: [(&apos;chat_file&apos;, 1, &apos;chat&apos;, 1), (&apos;chat_file&apos;, 2, &apos;chat&apos;, 1),
(&apos;chat_file&apos;, 3, &apos;chat&apos;, 1), (&apos;chat_file&apos;, 4, &apos;chat&apos;, 1), (&apos;chat_file&apos;, 5, &apos;chat&apos;, 1),
(&apos;knowledge_file&apos;, 1, &apos;knowledge&apos;, 1), (&apos;knowledge_file&apos;, 2, &apos;knowledge&apos;, 1),
...생략
Aborting migration due to database integrity issues
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이 에러는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chat_file&lt;/code&gt; 및 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;knowledge_file&lt;/code&gt; 테이블에 부모 테이블(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chat&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;knowledge&lt;/code&gt;) 에 존재하지 않는 고아 레코드(orphaned records) 가 남아 있어 발생합니다.&lt;/p&gt;

&lt;p&gt;아래와 같이 SQLite 에서 고아 레코드를 정리하여 해결합니다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;참고 : &lt;a href=&quot;https://github.com/taylorwilsdon/open-webui-postgres-migration/issues/19&quot;&gt;https://github.com/taylorwilsdon/open-webui-postgres-migration/issues/19&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sqlite3 /root/data/webui.db
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;-- Remove orphaned chat_file records&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;DELETE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chat_file&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chat_id&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;IN&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;-- Remove orphaned knowledge_file records&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;DELETE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;knowledge_file&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;knowledge_id&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;IN&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;knowledge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;마이그레이션-수행&quot;&gt;마이그레이션 수행&lt;/h3&gt;

&lt;p&gt;고아 레코드 정리 후 다시 마이그레이션 도구를 실행합니다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(venv) $ python migrate.py
╭──────────────────────────────────────────────────────────────────────╮
│ SQLite Database Configuration                                        │
╰──────────────────────────────────────────────────────────────────────╯
SQLite database path (webui.db): /root/data/webui.db

✓ Valid SQLite database (version 3.40.0)
╭──────────────────────────────────────────────────────────────────────╮
│ Running SQLite Database Integrity Check                               │
╰──────────────────────────────────────────────────────────────────────╯
┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Check Type        ┃ Status    ┃
┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ Integrity Check   │ ✅ Passed │
│ Quick Check       │ ✅ Passed │
│ Foreign Key Check │ ✅ Passed │
└───────────────────┴───────────┘
╭──────────────────────────────────────────────────────────────────────╮
│ PostgreSQL Connection Configuration                                  │
╰──────────────────────────────────────────────────────────────────────╯
PostgreSQL host (localhost): &amp;lt;host ip&amp;gt;
PostgreSQL port (5432):
Database name (postgres):
Username (postgres):
Password:

Connection Details:
 host:      &amp;lt;host ip&amp;gt;
 port:      5432
 dbname:    postgres
 user:      postgres
 password:  ********

✓ Database connection successful!
✓ PostgreSQL database has been properly bootstrapped!

Proceed with these settings? [y/n]: y
╭──────────────────────────────────────────────────────────────────────╮
│ Batch Size Configuration                                             │
╰──────────────────────────────────────────────────────────────────────╯
The batch size determines how many records are processed at once.
A larger batch size may be faster but uses more memory.
Recommended range: 100-5000

Batch size (500):
╭──────────────────────────────────────────────────────────────────────╮
│ Starting Migration Process                                           │
╰──────────────────────────────────────────────────────────────────────╯
  Migrating auth...             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%
  Migrating chat...             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%
  Migrating document...         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%
  Migrating prompt...           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%
  Migrating memory...           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%
  Migrating model...            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%
  Migrating tool...             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%
  Migrating function...         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%
  Migrating config...           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%
  Migrating tag...              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%
  Migrating file...             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%
  Migrating user...             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%
  Migrating knowledge...        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%
  Migrating knowledge_file...   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%
  Migrating chat_file...        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%
...생략
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 모든 테이블의 마이그레이션이 정상적으로 완료된 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;step-5-open-webui-설정-변경&quot;&gt;Step 5) Open WebUI 설정 변경&lt;/h2&gt;

&lt;p&gt;마이그레이션이 완료되었으므로, Open WebUI 가 PostgreSQL 을 사용하도록 설정을 변경하여 컨테이너를 재시작합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat &lt;/span&gt;open-webui.sh
&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;

docker run &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; 80:8080 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; /root/data:/app/backend/data &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--restart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;always &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;WEBUI_SECRET_KEY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;1234567890abcdefg&apos;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;DATABASE_URL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;postgres://&lt;span class=&quot;s1&quot;&gt;&apos;postgres&apos;&lt;/span&gt;:&lt;span class=&quot;s1&quot;&gt;&apos;password&apos;&lt;/span&gt;@&amp;lt;host ip&amp;gt;:5432/postgres &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt; open-webui &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    ghcr.io/open-webui/open-webui:main
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;bash open-webui.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DATABASE_URL&lt;/code&gt; 환경 변수를 PostgreSQL 연결 문자열로 설정하여 Open WebUI 를 시작합니다.&lt;/p&gt;

&lt;h2 id=&quot;마무리&quot;&gt;마무리&lt;/h2&gt;

&lt;p&gt;위와 같은 방법으로 Open WebUI 의 데이터베이스를 SQLite 에서 PostgreSQL 로 마이그레이션이 가능합니다. &lt;br /&gt;
PostgreSQL 로 전환 후에는 다수의 사용자가 동시에 접근하는 환경에서도 데이터베이스 잠금 이슈 없이 안정적으로 서비스를 운영할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;참고&quot;&gt;참고&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Open WebUI GitHub : &lt;a href=&quot;https://github.com/open-webui/open-webui&quot;&gt;https://github.com/open-webui/open-webui&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Migration Tool : &lt;a href=&quot;https://github.com/taylorwilsdon/open-webui-postgres-migration&quot;&gt;https://github.com/taylorwilsdon/open-webui-postgres-migration&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Foreign Key Check Issue : &lt;a href=&quot;https://github.com/taylorwilsdon/open-webui-postgres-migration/issues/19&quot;&gt;https://github.com/taylorwilsdon/open-webui-postgres-migration/issues/19&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;WEBUI_SECRET_KEY : &lt;a href=&quot;https://docs.openwebui.com/getting-started/env-configuration/#webui_secret_key&quot;&gt;https://docs.openwebui.com/getting-started/env-configuration/#webui_secret_key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 02 Feb 2026 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/ai/2026/02/02/open-webui-db-migration/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/ai/2026/02/02/open-webui-db-migration/</guid>
        
        <category>ai</category>
        
        <category>linux</category>
        
        <category>docker</category>
        
        
        <category>ai</category>
        
      </item>
    
      <item>
        <title>[Container] Finch - Docker Desktop 대체 오픈소스 컨테이너 도구 사용법</title>
        <description>&lt;h1 id=&quot;container-finch---docker-desktop-대체-오픈소스-컨테이너-도구-사용법&quot;&gt;[Container] Finch - Docker Desktop 대체 오픈소스 컨테이너 도구 사용법&lt;/h1&gt;

&lt;h2 id=&quot;finch-란&quot;&gt;Finch 란?&lt;/h2&gt;

&lt;p&gt;Finch는 AWS에서 개발한 오픈소스 컨테이너 개발 도구입니다. macOS / Windows / Linux 환경에서 Docker Desktop의 대안으로 사용할 수 있으며, containerd와 nerdctl을 기반으로 동작합니다. 라이선스 비용 없이 로컬 환경에서 컨테이너 이미지를 빌드, 실행, 배포할 수 있어 개인 개발자나 소규모 팀에게 유용한 도구입니다.&lt;/p&gt;

&lt;p&gt;이번 포스팅에서는 Finch의 기본 사용법에 대해 작성하도록 하겠습니다.&lt;/p&gt;

&lt;h2 id=&quot;테스트-환경&quot;&gt;테스트 환경&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;테스트 환경: macOS (Apple Silicon / ARM64)&lt;/li&gt;
  &lt;li&gt;Finch Server Version: v2.1.3&lt;/li&gt;
  &lt;li&gt;VM Kernel: 6.12.53-69.119.amzn2023.aarch64&lt;/li&gt;
  &lt;li&gt;VM Operating System: Fedora Linux 42 (Cloud Edition)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;finch-vm-시작&quot;&gt;Finch VM 시작&lt;/h2&gt;

&lt;p&gt;Finch는 Linux 컨테이너를 실행하기 위해 내부적으로 경량 VM(Lima)을 사용합니다. VM이 중지된 상태에서 명령어를 실행하면 아래와 같은 에러가 발생합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch stats
FATA[0000] instance &lt;span class=&quot;s2&quot;&gt;&quot;finch&quot;&lt;/span&gt; is stopped, run &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;finch vm start&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt; to start the instance
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;아래와 같이 VM을 시작합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch vm start
INFO[0000] Starting existing Finch virtual machine...
INFO[0037] Finch virtual machine started successfully
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 Finch VM이 정상적으로 시작된 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;컨테이너-이미지-pull&quot;&gt;컨테이너 이미지 Pull&lt;/h2&gt;

&lt;p&gt;아래와 같이 Docker Hub에서 httpd 이미지를 가져옵니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch pull httpd
docker.io/library/httpd:latest:                                                   resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:dd178595edd6d4f49296f62f9587238db2cd1045adfff6fccc15a6c4d08f5d2e:    &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;           |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:d455e832e73abe8385397a4942fbb118a0ad7bdc37a5c695c2bce15f88bd8c5e: &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;           |++++++++++++++++++++++++++++++++++++++|
config-sha256:3bd0a578c1bd6b6cb48eaddd1c8daaba6f1362fc792a4a1f9618275b20ed5314:   &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;           |++++++++++++++++++++++++++++++++++++++|
elapsed: 1.5 s                                                                    total:   0.0 B &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.0 B/s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;컨테이너-실행&quot;&gt;컨테이너 실행&lt;/h2&gt;

&lt;p&gt;아래와 같이 httpd 컨테이너를 백그라운드로 실행합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch container run &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt; my-httpd &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; 8080:80 httpd
38f1c0971d8b95cfabb27fb051979a75bafcf7ed0ac833dc69d03de2649cb620
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;실행 중인 컨테이너를 확인합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch ps &lt;span class=&quot;nt&quot;&gt;-a&lt;/span&gt;
CONTAINER ID    IMAGE                             COMMAND               CREATED           STATUS    PORTS                   NAMES
38f1c0971d8b    docker.io/library/httpd:latest    &lt;span class=&quot;s2&quot;&gt;&quot;httpd-foreground&quot;&lt;/span&gt;    11 seconds ago    Up        0.0.0.0:8080-&amp;gt;80/tcp    my-httpd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 my-httpd 컨테이너가 정상적으로 실행 중인 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;컨테이너-동작-확인&quot;&gt;컨테이너 동작 확인&lt;/h2&gt;

&lt;p&gt;아래와 같이 curl 명령어로 웹 서버가 정상 동작하는지 테스트합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;curl localhost:8080
&amp;lt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;DOCTYPE HTML PUBLIC &lt;span class=&quot;s2&quot;&gt;&quot;-//W3C//DTD HTML 4.01//EN&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;http://www.w3.org/TR/html4/strict.dtd&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&amp;lt;html&amp;gt;
&amp;lt;&lt;span class=&quot;nb&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&amp;lt;title&amp;gt;It works! Apache httpd&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;p&amp;gt;It works!&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 Apache httpd 웹 서버가 정상적으로 응답하는 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;컨테이너-이미지-빌드&quot;&gt;컨테이너 이미지 빌드&lt;/h2&gt;

&lt;p&gt;이번 섹션에서는 Finch를 사용하여 직접 컨테이너 이미지를 빌드하는 방법에 대해 기록하도록 하겠습니다.&lt;/p&gt;

&lt;h3 id=&quot;샘플-애플리케이션-준비&quot;&gt;샘플 애플리케이션 준비&lt;/h3&gt;

&lt;p&gt;간단한 Python Flask 웹 애플리케이션을 예제로 사용합니다. 아래와 같이 프로젝트 디렉토리를 생성하고 파일을 준비합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mkdir &lt;/span&gt;finch-demo &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;finch-demo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;아래와 같이 Flask 애플리케이션 파일을 작성합니다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vi&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;py&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;flask&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Flask&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Flask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;hostname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nodename&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;&apos;&apos;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Finch Demo App&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Hello from Finch!&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;Container Hostname: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;Built with Finch - Open Source Container Tool&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&apos;&apos;&apos;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;__main__&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;0.0.0.0&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;다음으로 의존성 파일을 작성합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;vi requirements.txt
&lt;span class=&quot;nv&quot;&gt;flask&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;3.0.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;containerfile-작성&quot;&gt;Containerfile 작성&lt;/h3&gt;

&lt;p&gt;아래와 같이 Containerfile을 작성합니다. Finch는 Dockerfile과 Containerfile 모두 지원합니다.&lt;/p&gt;

&lt;div class=&quot;language-dockerfile highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ vi Containerfile
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; python:3.11-slim&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;WORKDIR&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; /app&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;COPY&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; requirements.txt .&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;RUN &lt;/span&gt;pip &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--no-cache-dir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; requirements.txt

&lt;span class=&quot;k&quot;&gt;COPY&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; app.py .&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;EXPOSE&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; 5000&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;CMD&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; [&quot;python&quot;, &quot;app.py&quot;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;프로젝트 구조는 아래와 같습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt;
total 24
&lt;span class=&quot;nt&quot;&gt;-rw-r--r--&lt;/span&gt;@ 1 cheolhee  staff  434 Jan 20 13:38 app.py
&lt;span class=&quot;nt&quot;&gt;-rw-r--r--&lt;/span&gt;@ 1 cheolhee  staff  166 Jan 20 13:38 Containerfile
&lt;span class=&quot;nt&quot;&gt;-rw-r--r--&lt;/span&gt;@ 1 cheolhee  staff   13 Jan 20 13:38 requirements.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;이미지-빌드&quot;&gt;이미지 빌드&lt;/h3&gt;

&lt;p&gt;아래와 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;finch build&lt;/code&gt; 명령어를 사용하여 이미지를 빌드합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch build &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; finch-demo:v1.0 &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;+] Building 9.0s &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;10/10&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; FINISHED
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;internal] load build definition from Containerfile                                                                                          0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; transferring dockerfile: 208B                                                                                                             0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;internal] load metadata &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;docker.io/library/python:3.11-slim                                                                              2.7s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;internal] load .dockerignore                                                                                                                0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; transferring context: 2B                                                                                                                  0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;1/5] FROM docker.io/library/python:3.11-slim@sha256:5be45dbade29bebd6886af6b438fd7e0b4eb7b611f39ba62b430263f82de36d2                        3.5s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; resolve docker.io/library/python:3.11-slim@sha256:5be45dbade29bebd6886af6b438fd7e0b4eb7b611f39ba62b430263f82de36d2                        0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; sha256:518abaec573aacfc293edf9e19b26274fc7ee5d3448e80f90eecdae829acd7e7 249B / 249B                                                       0.5s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; sha256:068949646e5ac13b4b3f99bca3f1249ca853fc5bd30512ea7d447af7a649b011 14.31MB / 14.31MB                                                 1.8s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; sha256:d67bedf18e0abdffd887db745e6a45c9173ae1b93fd7fac8d7a8c6b2e5346455 1.27MB / 1.27MB                                                   1.7s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; sha256:d637807aba98f742a62ad9b0146579ceb0297a3c831f56b2361664b7f5fbc75b 30.13MB / 30.13MB                                                 2.8s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; extracting sha256:d637807aba98f742a62ad9b0146579ceb0297a3c831f56b2361664b7f5fbc75b                                                        0.4s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; extracting sha256:d67bedf18e0abdffd887db745e6a45c9173ae1b93fd7fac8d7a8c6b2e5346455                                                        0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; extracting sha256:068949646e5ac13b4b3f99bca3f1249ca853fc5bd30512ea7d447af7a649b011                                                        0.2s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; extracting sha256:518abaec573aacfc293edf9e19b26274fc7ee5d3448e80f90eecdae829acd7e7                                                        0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;internal] load build context                                                                                                                0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; transferring context: 527B                                                                                                                0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;2/5] WORKDIR /app                                                                                                                           0.1s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;3/5] COPY requirements.txt &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;                                                                                                                0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;4/5] RUN pip &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--no-cache-dir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; requirements.txt                                                                                     2.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;5/5] COPY app.py &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;                                                                                                                          0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; exporting to image                                                                                                                           0.6s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; exporting layers                                                                                                                          0.5s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; exporting manifest sha256:e045216b9a5483b26e5c9b16630913ce1c2b35b279158af02bae3d0a0080176d                                                0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; exporting config sha256:8c89f20c21344cbd96815ff7340b7e8f52784e4ab67b09b6239efd3c40fcb443                                                  0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; naming to docker.io/library/finch-demo:v1.0                                                                                               0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; unpacking to docker.io/library/finch-demo:v1.0                                                                                            0.1s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 이미지 빌드가 완료된 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h3 id=&quot;빌드된-이미지-확인&quot;&gt;빌드된 이미지 확인&lt;/h3&gt;

&lt;p&gt;아래와 같이 빌드된 이미지를 확인합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch images
REPOSITORY       TAG       IMAGE ID        CREATED           PLATFORM       SIZE       BLOB SIZE
finch-demo       v1.0      e045216b9a54    11 seconds ago    linux/arm64    184.4MB    51.4MB
jekyll/jekyll    latest    400b8d1569f1    21 hours ago      linux/amd64    907.3MB    322.1MB
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 finch-demo:v1.0 이미지가 정상적으로 빌드된 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h3 id=&quot;빌드한-이미지로-컨테이너-실행&quot;&gt;빌드한 이미지로 컨테이너 실행&lt;/h3&gt;

&lt;p&gt;아래와 같이 빌드한 이미지를 사용하여 컨테이너를 실행합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch run &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt; demo-app &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; 5000:5000 finch-demo:v1.0
acdbff628decca37867d875494c9fd9615df724ded3205bd72d8377761905652
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;실행 중인 컨테이너를 확인합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch ps
CONTAINER ID    IMAGE                                COMMAND            CREATED          STATUS    PORTS                     NAMES
acdbff628dec    docker.io/library/finch-demo:v1.0    &lt;span class=&quot;s2&quot;&gt;&quot;python app.py&quot;&lt;/span&gt;    9 seconds ago    Up        0.0.0.0:5000-&amp;gt;5000/tcp    demo-app
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;동작-확인&quot;&gt;동작 확인&lt;/h3&gt;

&lt;p&gt;아래와 같이 curl 명령어로 애플리케이션이 정상 동작하는지 확인합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;curl localhost:5000
&amp;lt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;&lt;span class=&quot;nb&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
    &amp;lt;title&amp;gt;Finch Demo App&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Hello from Finch!&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;Container Hostname: acdbff628dec&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;Built with Finch - Open Source Container Tool&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 Finch로 빌드한 Flask 애플리케이션이 정상적으로 동작하는 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;컨테이너-관리-명령어&quot;&gt;컨테이너 관리 명령어&lt;/h2&gt;

&lt;h3 id=&quot;컨테이너-삭제&quot;&gt;컨테이너 삭제&lt;/h3&gt;

&lt;p&gt;아래 명령어로 실행 중인 컨테이너를 강제 삭제할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch container &lt;span class=&quot;nb&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; my-httpd
my-httpd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;컨테이너-재시작&quot;&gt;컨테이너 재시작&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch container restart blog
blog
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;컨테이너-로그-확인&quot;&gt;컨테이너 로그 확인&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-f&lt;/code&gt; 옵션을 사용하여 실시간 로그를 확인할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch logs &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; blog
Fetching gem metadata from https://rubygems.org/..........
Using bundler 2.3.25
Fetching public_suffix 5.0.3
Using colorator 1.1.0
Fetching concurrent-ruby 1.2.2
Installing public_suffix 5.0.3
Installing concurrent-ruby 1.2.2
Using eventmachine 1.2.7
....
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;이미지-관리&quot;&gt;이미지 관리&lt;/h2&gt;

&lt;h3 id=&quot;이미지-목록-확인&quot;&gt;이미지 목록 확인&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch images
REPOSITORY    TAG       IMAGE ID        CREATED          PLATFORM       SIZE       BLOB SIZE
httpd         latest    dd178595edd6    2 minutes ago    linux/arm64    159.2MB    45.5MB
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;이미지-삭제&quot;&gt;이미지 삭제&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch rmi dd178595edd6
Untagged: docker.io/library/httpd:latest@sha256:dd178595edd6d4f49296f62f9587238db2cd1045adfff6fccc15a6c4d08f5d2e
Deleted: sha256:37127a0fa4c7aa2f661f5d88d5e0b6194640848159d7a56c5c0b7afb445aa6fe
Deleted: sha256:e2be4c959abac10d36314c871065c3ddeb6b1b76cfebd5bce06a05a5dde1d68e
Deleted: sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef
Deleted: sha256:0477352d89d2859cc39547b0769fc84ad80cb2fa92caca62531acef033043ea8
Deleted: sha256:f025424b0a4653e7ecc10f1d1f8a35458ae674db8c1f01df825a9b74808621b3
Deleted: sha256:3958c2a874d9078e3c5663b3a82cd3d9b87f2c19c9bdf2f720f6b9902c475eb2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;finch-compose를-이용한-멀티-컨테이너-실행&quot;&gt;Finch Compose를 이용한 멀티 컨테이너 실행&lt;/h2&gt;

&lt;p&gt;Finch는 Docker Compose와 호환되는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;finch compose&lt;/code&gt; 명령어를 제공합니다. 이번 섹션에서는 Finch Compose를 사용하여 여러 컨테이너를 함께 실행하는 방법에 대해 기록하도록 하겠습니다.&lt;/p&gt;

&lt;h3 id=&quot;샘플-애플리케이션-준비-1&quot;&gt;샘플 애플리케이션 준비&lt;/h3&gt;

&lt;p&gt;Flask 웹 애플리케이션과 Redis를 연동하는 간단한 방문자 카운터 예제를 사용합니다. 아래와 같이 프로젝트 디렉토리를 생성합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mkdir &lt;/span&gt;finch-demo &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;finch-demo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;아래와 같이 Flask 애플리케이션 파일을 작성합니다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vi&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;py&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;flask&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Flask&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;redis&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Flask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;redis&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6379&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_hit_count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;retries&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;incr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;hits&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exceptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ConnectionError&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;retries&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exc&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;retries&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_hit_count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;hostname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nodename&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;&apos;&apos;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Finch Compose Demo&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Hello from Finch Compose!&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;Container Hostname: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;Visit Count: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&apos;&apos;&apos;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;__main__&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;0.0.0.0&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;다음으로 의존성 파일을 작성합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;vi requirements.txt
&lt;span class=&quot;nv&quot;&gt;flask&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;3.0.0
&lt;span class=&quot;nv&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;5.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;containerfile-작성-1&quot;&gt;Containerfile 작성&lt;/h3&gt;

&lt;p&gt;아래와 같이 Containerfile을 작성합니다.&lt;/p&gt;

&lt;div class=&quot;language-dockerfile highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ vi Containerfile
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; python:3.11-slim&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;WORKDIR&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; /app&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;COPY&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; requirements.txt .&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;RUN &lt;/span&gt;pip &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--no-cache-dir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; requirements.txt

&lt;span class=&quot;k&quot;&gt;COPY&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; app.py .&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;EXPOSE&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; 5000&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;CMD&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; [&quot;python&quot;, &quot;app.py&quot;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;compose-파일-작성&quot;&gt;Compose 파일 작성&lt;/h3&gt;

&lt;p&gt;아래와 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compose.yaml&lt;/code&gt; 파일을 작성합니다. Finch는 Docker Compose 파일 형식과 호환됩니다.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;$ vi compose.yaml&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;web&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;.&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;5000:5000&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;redis&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;unless-stopped&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;redis:alpine&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;redis-data:/data&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;unless-stopped&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;redis-data&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;프로젝트 구조는 아래와 같습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt;
total 32
&lt;span class=&quot;nt&quot;&gt;-rw-r--r--&lt;/span&gt;@ 1 cheolhee  staff  748 Jan 20 13:43 app.py
&lt;span class=&quot;nt&quot;&gt;-rw-r--r--&lt;/span&gt;@ 1 cheolhee  staff  243 Jan 20 13:44 compose.yaml
&lt;span class=&quot;nt&quot;&gt;-rw-r--r--&lt;/span&gt;@ 1 cheolhee  staff  166 Jan 20 13:44 Containerfile
&lt;span class=&quot;nt&quot;&gt;-rw-r--r--&lt;/span&gt;@ 1 cheolhee  staff   26 Jan 20 13:43 requirements.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;compose로-컨테이너-실행&quot;&gt;Compose로 컨테이너 실행&lt;/h3&gt;

&lt;p&gt;아래와 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;finch compose up&lt;/code&gt; 명령어를 사용하여 멀티 컨테이너 환경을 실행합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch compose up &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt;
INFO[0000] Creating network finch-demo_default
INFO[0000] Creating volume finch-demo_redis-data
WARN[0000] Ignoring: service web: depends_on: redis: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Required]
INFO[0000] Ensuring image redis:alpine
docker.io/library/redis:alpine:                                                   resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:6cbef353e480a8a6e7f10ec545f13d7d3fa85a212cdcc5ffaf5a1c818b9d3798:    &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;           |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:1023a5ac993a92700157e724a9aa077428b9f5d1ef54f0ab1aa5e74371eab6c3: &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;           |++++++++++++++++++++++++++++++++++++++|
config-sha256:733d545e87b547f001d2a7965cb668561dd4e92751f84c519c8b6892c4162961:   &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:25e9d7d40e446acd1c87bc032302c12d6f69eb8ee0006879fb2be002ac7278db:    &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:ce3e85348d1524ee75ee16ea693b051e47a77cf7bfc2fd5fb21474f22f1d7ee6:    &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:b0abe8c185e79f4788817e25569e9b70ecb3d192996c09a18290cbb77f51b923:    &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:4e748fe7e898af4bba0af4ecc768150ae7883bf856f039c2c1051c47bb032a61:    &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:6b59a28fa20117e6048ad0616b8d8c901877ef15ff4c7f18db04e4f01f43bc39:    &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:d8d7a3e38cc296564e247ed12159d54a7ecdd0725b4664fe6d4f70420fa41523:    &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1:    &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;           |++++++++++++++++++++++++++++++++++++++|
elapsed: 6.9 s                                                                    total:  31.7 M &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;4.6 MiB/s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
INFO[0006] Building image finch-demo-web
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;+] Building 4.1s &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;10/10&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; FINISHED
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;internal] load build definition from Containerfile                                                                                          0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; transferring dockerfile: 208B                                                                                                             0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;internal] load metadata &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;docker.io/library/python:3.11-slim                                                                              1.3s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;internal] load .dockerignore                                                                                                                0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; transferring context: 2B                                                                                                                  0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;1/5] FROM docker.io/library/python:3.11-slim@sha256:5be45dbade29bebd6886af6b438fd7e0b4eb7b611f39ba62b430263f82de36d2                        0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; resolve docker.io/library/python:3.11-slim@sha256:5be45dbade29bebd6886af6b438fd7e0b4eb7b611f39ba62b430263f82de36d2                        0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;internal] load build context                                                                                                                0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; transferring context: 854B                                                                                                                0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; CACHED &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;2/5] WORKDIR /app                                                                                                                    0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;3/5] COPY requirements.txt &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;                                                                                                                0.1s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;4/5] RUN pip &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--no-cache-dir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; requirements.txt                                                                                     2.1s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;5/5] COPY app.py &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;                                                                                                                          0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; exporting to image                                                                                                                           0.7s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; exporting layers                                                                                                                          0.5s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; exporting manifest sha256:26a0db072b8e9c4fe1959e74a5ffbdd8022032094190a7546e928c581f4efa5a                                                0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; exporting config sha256:9583b0d9807ddc747aa3b5203bafc124edad0a624b89a3e3fa1b7a02a5de6145                                                  0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; naming to docker.io/library/finch-demo-web:latest                                                                                         0.0s
 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; unpacking to docker.io/library/finch-demo-web:latest                                                                                      0.1s
INFO[0011] Creating container finch-demo-redis-1
INFO[0011] Running &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;/usr/local/bin/nerdctl run &lt;span class=&quot;nt&quot;&gt;--cidfile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/tmp/compose-3033891241/cid &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;com.docker.compose.project&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;finch-demo &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;com.docker.compose.service&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;redis &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;finch-demo-redis-1 &lt;span class=&quot;nt&quot;&gt;--pull&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;never &lt;span class=&quot;nt&quot;&gt;--net&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;finch-demo_default &lt;span class=&quot;nt&quot;&gt;--hostname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;redis &lt;span class=&quot;nt&quot;&gt;--restart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;unless-stopped &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;finch-demo_redis-data:/data redis:alpine]
WARN[0000] volume &lt;span class=&quot;s2&quot;&gt;&quot;finch-demo_redis-data&quot;&lt;/span&gt; already exists and will be returned as-is
INFO[0011] Creating container finch-demo-web-1
INFO[0011] Running &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;/usr/local/bin/nerdctl run &lt;span class=&quot;nt&quot;&gt;--cidfile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/tmp/compose-3371262174/cid &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;com.docker.compose.project&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;finch-demo &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;com.docker.compose.service&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;web &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;finch-demo-web-1 &lt;span class=&quot;nt&quot;&gt;--pull&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;never &lt;span class=&quot;nt&quot;&gt;--net&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;finch-demo_default &lt;span class=&quot;nt&quot;&gt;--hostname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;web &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;5000:5000/tcp &lt;span class=&quot;nt&quot;&gt;--restart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;unless-stopped finch-demo-web]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 웹 애플리케이션과 Redis 컨테이너가 함께 실행된 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h3 id=&quot;실행-중인-컨테이너-확인&quot;&gt;실행 중인 컨테이너 확인&lt;/h3&gt;

&lt;p&gt;아래와 같이 실행 중인 컨테이너를 확인합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch ps &lt;span class=&quot;nt&quot;&gt;-a&lt;/span&gt;
CONTAINER ID    IMAGE                                      COMMAND                   CREATED           STATUS    PORTS                     NAMES
946badd3438c    docker.io/library/finch-demo-web:latest    &lt;span class=&quot;s2&quot;&gt;&quot;python app.py&quot;&lt;/span&gt;           22 seconds ago    Up        0.0.0.0:5000-&amp;gt;5000/tcp    finch-demo-web-1
c4e7f14ce140    docker.io/library/redis:alpine             &lt;span class=&quot;s2&quot;&gt;&quot;docker-entrypoint.s…&quot;&lt;/span&gt;    22 seconds ago    Up                                  finch-demo-redis-1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 finch-demo-web-1과 finch-demo-redis-1 컨테이너가 정상적으로 실행 중인 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h3 id=&quot;동작-확인-1&quot;&gt;동작 확인&lt;/h3&gt;

&lt;p&gt;아래와 같이 curl 명령어로 애플리케이션이 정상 동작하는지 확인합니다. 요청할 때마다 방문자 카운트가 증가합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;curl localhost:5000
&amp;lt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;&lt;span class=&quot;nb&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
    &amp;lt;title&amp;gt;Finch Compose Demo&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Hello from Finch Compose!&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;Container Hostname: web&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;Visit Count: 1&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;curl localhost:5000
&amp;lt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;&lt;span class=&quot;nb&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
    &amp;lt;title&amp;gt;Finch Compose Demo&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Hello from Finch Compose!&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;Container Hostname: web&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;Visit Count: 2&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 Flask 애플리케이션과 Redis가 정상적으로 연동되어 방문자 카운트가 증가하는 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h3 id=&quot;compose-환경-종료&quot;&gt;Compose 환경 종료&lt;/h3&gt;

&lt;p&gt;아래와 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;finch compose down&lt;/code&gt; 명령어를 사용하여 모든 컨테이너와 네트워크를 종료합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch compose down
INFO[0000] Removing container finch-demo-web-1
INFO[0000] Removing container finch-demo-redis-1
INFO[0001] Removing network finch-demo_default
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;볼륨까지 함께 삭제하려면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-v&lt;/code&gt; 옵션을 추가합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch compose down &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;
INFO[0000] Removing container finch-demo-web-1
INFO[0000] Removing container finch-demo-redis-1
INFO[0001] Removing volume finch-demo_redis-data
INFO[0001] Removing network finch-demo_default
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;시스템-정보-확인&quot;&gt;시스템 정보 확인&lt;/h2&gt;

&lt;p&gt;아래와 같이 Finch 시스템 정보를 확인할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;finch system info
Client:
 Namespace:	finch
 Debug Mode:	&lt;span class=&quot;nb&quot;&gt;false

&lt;/span&gt;Server:
 Server Version: v2.1.3
 Storage Driver: overlayfs
 Logging Driver: json-file
 Cgroup Driver: systemd
 Cgroup Version: 2
 Plugins:
  Log:     fluentd journald json-file none syslog
  Storage: native overlayfs stargz
 Security Options:
  seccomp
   Profile: &lt;span class=&quot;nb&quot;&gt;builtin
  &lt;/span&gt;cgroupns
 Kernel Version:   6.12.53-69.119.amzn2023.aarch64
 Operating System: Fedora Linux 42 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Cloud Edition&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
 OSType:           linux
 Architecture:     aarch64
 CPUs:             4
 Total Memory:     7.739GiB
 Name:             lima-finch
 ID:               501dce95-ed66-4c39-852d-642a4008f6d0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 Finch VM은 내부적으로 Fedora Linux 42 기반으로 동작하며, overlayfs 스토리지 드라이버와 systemd cgroup을 사용하는 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;docker-명령어와-비교&quot;&gt;Docker 명령어와 비교&lt;/h2&gt;

&lt;p&gt;Finch는 nerdctl을 기반으로 하기 때문에 Docker CLI와 거의 동일한 명령어 체계를 사용합니다.&lt;/p&gt;

&lt;table style=&quot;width: 100%; border-collapse: collapse;&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;background-color: #f2f2f2;&quot;&gt;
      &lt;th style=&quot;border: 1px solid #ddd; padding: 12px; text-align: left;&quot;&gt;Docker 명령어&lt;/th&gt;
      &lt;th style=&quot;border: 1px solid #ddd; padding: 12px; text-align: left;&quot;&gt;Finch 명령어&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;docker pull&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;finch pull&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;docker run&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;finch run&lt;/code&gt;  또는  &lt;code&gt;finch container run&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;docker ps&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;finch ps&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;docker images&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;finch images&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;docker logs&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;finch logs&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;docker rm&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;finch container rm&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;docker rmi&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;finch rmi&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;docker build&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;finch build&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;docker compose up&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;finch compose up&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;docker compose down&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;border: 1px solid #ddd; padding: 10px;&quot;&gt;&lt;code&gt;finch compose down&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;참고&quot;&gt;참고&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Finch GitHub: &lt;a href=&quot;https://github.com/runfinch/finch&quot;&gt;https://github.com/runfinch/finch&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Finch 공식 사이트: &lt;a href=&quot;https://runfinch.com/&quot;&gt;https://runfinch.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;위와 같은 방법으로 macOS 환경에서 Docker Desktop 대신 Finch를 사용하여 컨테이너를 관리할 수 있습니다. Docker CLI와 유사한 명령어 체계를 제공하기 때문에 기존 Docker 사용 경험이 있다면 쉽게 적응할 수 있습니다.&lt;/p&gt;
</description>
        <pubDate>Tue, 20 Jan 2026 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/container/2026/01/20/finch/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/container/2026/01/20/finch/</guid>
        
        <category>docker</category>
        
        <category>container</category>
        
        
        <category>container</category>
        
      </item>
    
      <item>
        <title>adb 를 이용하여 Android 16 무선 페어링 방법</title>
        <description>&lt;h1 id=&quot;adb-를-이용하여-android-16-무선-페어링-방법&quot;&gt;adb 를 이용하여 Android 16 무선 페어링 방법&lt;/h1&gt;
&lt;p&gt;정확한 사용 방법에 대해서 기록된 내용이 없어서, 해당 포스팅을 작성하게 되었습니다.&lt;/p&gt;

&lt;h1 id=&quot;how-to&quot;&gt;How to&lt;/h1&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;adb&lt;/code&gt; 를 사용하는 방법은 PC, APP 둘 다 동일한 방법으로 진행하면 됩니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;PC : &lt;a href=&quot;https://developer.android.com/tools/releases/platform-tools?hl=ko&quot;&gt;https://developer.android.com/tools/releases/platform-tools?hl=ko&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Mobile : &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ADB Shell&lt;/code&gt; 최신 버전&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;connect&quot;&gt;Connect&lt;/h2&gt;
&lt;p&gt;개발자 옵션에서 무선 디버깅을 활성화합니다.&lt;/p&gt;

&lt;p&gt;“페어링 코드로 기기 페어링” 을 누르고 나오는 정보를 아래와 같이 터미널을 통해 페어링을 먼저합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;adb pair 127.0.0.1:43033
Enter pairing code: 123456
Successfully paired to 127.0.0.1:43033 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;guid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;adb-abcdefg-chhanz]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;페어링이 완료된 이후, “무선 디버깅” 메뉴에 표기된 ‘IP 주소 및 포트’ 정보를 기반으로 connect 합니다. &lt;br /&gt;
해당 포트값은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pair&lt;/code&gt; 용 포트와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;connect&lt;/code&gt; 용 포트 번호가 다릅니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;adb connect 127.0.0.1:43853
connected to 127.0.0.1:43853
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;adb devices&lt;/code&gt; 와 같은 명령어로 장치 접속 상태를 확인합니다.&lt;/p&gt;

</description>
        <pubDate>Wed, 14 Jan 2026 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/linux/2026/01/14/adb-connect-android-16/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/linux/2026/01/14/adb-connect-android-16/</guid>
        
        <category>linux</category>
        
        
        <category>linux</category>
        
      </item>
    
      <item>
        <title>Container Registry - Github Package Registry 사용 with GITHUB CLI</title>
        <description>&lt;center&gt;
&lt;img width=&quot;800&quot; height=&quot;430&quot; src=&quot;https://github.blog/wp-content/uploads/2019/05/facebook-1200x630-final.png?resize=1200%2C630&quot; class=&quot;d-block cover-image wp-post-image&quot; alt=&quot;&quot; decoding=&quot;async&quot; loading=&quot;lazy&quot; srcset=&quot;https://github.blog/wp-content/uploads/2019/05/facebook-1200x630-final.png?w=1200 1200w, https://github.blog/wp-content/uploads/2019/05/facebook-1200x630-final.png?w=300 300w, https://github.blog/wp-content/uploads/2019/05/facebook-1200x630-final.png?w=768 768w, https://github.blog/wp-content/uploads/2019/05/facebook-1200x630-final.png?w=1024 1024w&quot; sizes=&quot;auto, (max-width: 1200px) 100vw, 1200px&quot; /&gt;
&lt;/center&gt;

&lt;h1 id=&quot;github-package-registry&quot;&gt;Github Package Registry&lt;/h1&gt;
&lt;p&gt;DockerHub 의 대안으로 Github Package Registry 를 사용해보고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;github-cli&lt;/code&gt; 인 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gh&lt;/code&gt; 를 사용하여 보다 안전하게 컨테이너 이미지를 관리하는 방법에 대해 작성해보도록 하겠습니다.&lt;/p&gt;

&lt;h1 id=&quot;github-cli-설치&quot;&gt;Github CLI 설치&lt;/h1&gt;
&lt;p&gt;Github CLI (&lt;a href=&quot;https://cli.github.com/&quot;&gt;https://cli.github.com/&lt;/a&gt;) 페이지를 참고하여 설치를 수행합니다.&lt;/p&gt;

&lt;p&gt;저의 경우, Linux 시스템에 아래와 같은 방법으로 설치하였습니다.&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; yum-config-manager &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;/dev/null &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;yum &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;yum-utils
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;yum-config-manager &lt;span class=&quot;nt&quot;&gt;--add-repo&lt;/span&gt; https://cli.github.com/packages/rpm/gh-cli.repo
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;yum &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;gh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;github-cli-를-이용하여-github-login&quot;&gt;Github CLI 를 이용하여 Github Login&lt;/h1&gt;
&lt;p&gt;Github CLI 를 이용하여 로그인을 하는 사유에는 암호화가 안되고 텍스트로 보관하고 있던 토큰값을 관리하는데 귀찮음(?), 안정성에 문제로 인해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gh&lt;/code&gt; 를 이용하면 좋을 것 같아 이번 포스트에서는 해당 방법을 사용하였습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gh auth&lt;/code&gt; 명령어를 이용하여 Github 를 로그인 할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;gh auth login &lt;span class=&quot;nt&quot;&gt;--scopes&lt;/span&gt; write:packages
? Where &lt;span class=&quot;k&quot;&gt;do &lt;/span&gt;you use GitHub? GitHub.com
? What is your preferred protocol &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;Git operations on this host? HTTPS
? Authenticate Git with your GitHub credentials? Yes
? How would you like to authenticate GitHub CLI? Login with a web browser

&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; First copy your one-time code: 1234-abcd
Press Enter to open https://github.com/login/device &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;your browser...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-01-13-gh/g1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;브라우져를 통해 github 에 one-time code 와 함께 device 인증을 수행하면 위와 같이 인증이 완료된 모습을 확인 할 수 있으며, 다음 단계가 수행이 됩니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;...
✓ Authentication complete.
- gh config &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-h&lt;/span&gt; github.com git_protocol https
✓ Configured git protocol
&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; Authentication credentials saved &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;plain text
✓ Logged &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;as chhanz
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;참고로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--scopes write:packages&lt;/code&gt; 는 차후 컨테이너 이미지 저장소에 이미지 PUSH 를 위해 미리 권한을 부여하였습니다. &lt;br /&gt;
필요시에 적합한 권한을 부여하여 로그인을 수행하면 됩니다. &lt;br /&gt;
만약 새로운 권한이 필요한 경우, &lt;a href=&quot;https://cli.github.com/manual/gh_auth_refresh&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gh auth refresh&lt;/code&gt;&lt;/a&gt; 를 사용하여 권한을 추가하면 됩니다.&lt;/p&gt;

&lt;h1 id=&quot;github-로그인-상태-확인&quot;&gt;Github 로그인 상태 확인&lt;/h1&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gh auth status&lt;/code&gt; 명령을 통해 로그인 상태, 권한 등에 대해 확인이 가능합니다.  &lt;br /&gt;
해당 명령어로는 기본적으로 암호화된 토큰 정보만 확인이 가능합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;gh auth status
github.com
  ✓ Logged &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;to github.com account chhanz &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;/root/.config/gh/hosts.yml&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  - Active account: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;
  - Git operations protocol: https
  - Token: git_&lt;span class=&quot;k&quot;&gt;***&lt;/span&gt;.......
  - Token scopes: &lt;span class=&quot;s1&quot;&gt;&apos;gist&apos;&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;&apos;read:org&apos;&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;&apos;repo&apos;&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;&apos;workflow&apos;&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;&apos;write:packages&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;push-the-container-image&quot;&gt;Push the Container Image&lt;/h1&gt;
&lt;p&gt;이번 테스트에서는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;podman&lt;/code&gt; 을 이용하여 이미지를 PUSH 하는 예제를 보여드릴 것입니다. &lt;br /&gt;
하지만 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker&lt;/code&gt; 도 동일한 방법으로 사용이 가능합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CR_PAT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;gh auth token&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$CR_PAT&lt;/span&gt; | podman login ghcr.io &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;USERNAME&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&amp;gt;&amp;gt; --password-stdin
Login Succeeded!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 명령어를 통해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gh&lt;/code&gt; 로 토큰값을 받아와서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ghcr.io&lt;/code&gt;, Github Package Registry 를 로그인합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;podman images
REPOSITORY                              TAG         IMAGE ID      CREATED       SIZE
ghcr.io/chhanz/git-readme-stats-docker  latest      2f2b17297e20  5 hours ago   300 MB
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 빌드된 이미지를 tag 를 아래 구조를 참고하여 수정한 이미지를 활용합니다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;ghcr.io/네임스페이스/컨테이너 이미지 이름:태그&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;podman push ghcr.io/chhanz/git-readme-stats-docker
Getting image &lt;span class=&quot;nb&quot;&gt;source &lt;/span&gt;signatures
Copying blob f35e3e5c2bc9 &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;   |
Copying blob 0649e2656ebe &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;   |
Copying blob e5aa2ce04d97 &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;   |
Copying blob def753c8a096 &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;   |
Copying blob bf948625900f &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;   |
Copying blob 7bb20cf5ef67 &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;   |
Copying config 2f2b17297e &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;   |
Writing manifest to image destination
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;설정된 태그를 이용하여 위와 같이 PUSH 를 수행합니다.&lt;/p&gt;

&lt;h1 id=&quot;change-package-visibility&quot;&gt;Change package visibility&lt;/h1&gt;
&lt;p&gt;기본적으로 PUSH 된 이미지는 private 로 되어 있습니다.  &lt;br /&gt;
GITHUB 정책에 의하여 무료로 사용 가능한 private 제한이 있고, public 이미지의 경우 무료로 사용이 가능합니다.&lt;/p&gt;

&lt;p&gt;위와 같은 사유로 인해 이미지를 Public 으로 변경을 해보도록 하겠습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-01-13-gh/g3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;GITHUB 의 Package 메뉴를 선택하면 위와 같이 이미지가 PUSH 된 것을 확인 할 수 있습니다. &lt;br /&gt;
먼저 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Connect Repository&lt;/code&gt; 를 선택하고 해당 이미지와 연결할 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Repository&lt;/code&gt; 를 지정합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-01-13-gh/g4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위와 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Repository&lt;/code&gt; 가 연결된 것을 확인 할 수 있습니다. &lt;br /&gt;
이후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Package settings&lt;/code&gt; 를 선택합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-01-13-gh/g2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;설정 하단에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Change package visibility&lt;/code&gt; 부분에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Change visibility&lt;/code&gt; 를 이용하여 private 에서 public 이미지로 변경을 합니다.&lt;/p&gt;

&lt;p&gt;위와 같은 방법으로 이미지를 Public 으로 변경합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2026-01-13-gh/g5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/chhanz?tab=packages&quot;&gt;https://github.com/chhanz?tab=packages&lt;/a&gt; 를 보시면 이미지가 Public 으로 전환 된 것을 확인 할 수 있습니다.&lt;/p&gt;

&lt;h1 id=&quot;참고-문서&quot;&gt;참고 문서&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry&quot;&gt;https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://cli.github.com/manual/&quot;&gt;https://cli.github.com/manual/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 13 Jan 2026 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/linux/2026/01/13/github-container-registry/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/linux/2026/01/13/github-container-registry/</guid>
        
        <category>linux</category>
        
        
        <category>linux</category>
        
      </item>
    
      <item>
        <title>mcpo - Open WebUI MCP 서버 연동 도구</title>
        <description>&lt;h1 id=&quot;mcpo-란&quot;&gt;mcpo 란&lt;/h1&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mcpo&lt;/code&gt; 는 MCP 서버 명령을 받아 표준 RESTful OpenAPI를 통해 접근 가능하게 해주는 매우 간단한 프록시입니다. &lt;br /&gt;
이러한 기능을 활용하여 LLM 에이전트 및 OpenAPI 를 사용하는 애플리케이션과 연동하는데 도움이 됩니다.&lt;/p&gt;

&lt;h1 id=&quot;mcpo-의-필요성&quot;&gt;mcpo 의 필요성&lt;/h1&gt;

&lt;p&gt;MCP 서버는 일반적으로 원시 표준 입출력(stdio)을 통해 통신하는데, 이는 다음과 같은 단점이 있습니다.&lt;/p&gt;

&lt;p&gt;🔓 본질적으로 보안에 취약합니다. &lt;br /&gt;
❌ 대부분의 도구와 호환되지 않습니다. &lt;br /&gt;
🧩 문서화, 인증, 오류 처리 등과 같은 표준 기능이 부족합니다.&lt;/p&gt;

&lt;p&gt;위와 같은 단점을 보완하고 여러 MCP 서버를 통합 관리하는데 편리함을 제공합니다.&lt;/p&gt;

&lt;p&gt;개인적으로는 MCP 서버를 stdio 형태로 사용하면 사용자의 Laptop 과 같은 디바이스의 리소스를 사용하므로 발생되는 문제, LLM 의 재시작으로 인해 MCP 서버의 재시작등의 관리적으로 연관된 불편함이 다수 존재하였습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mcpo&lt;/code&gt; 는 이러한 불편함을 통합 관리하게 만들어주므로 인해 편리함을 제공하였다고 생각합니다.&lt;/p&gt;

&lt;h1 id=&quot;build&quot;&gt;Build&lt;/h1&gt;

&lt;p&gt;이번 포스팅에서는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mcpo&lt;/code&gt; 를 container 이미지로 빌드하고 빌드된 이미지를 이용하여 사용하는 방법에 대해 설명을 드리겠습니다.&lt;/p&gt;

&lt;p&gt;아래와 같은 방법으로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mcpo&lt;/code&gt; container 이미지를 빌드합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git clone https://github.com/open-webui/mcpo.git
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;mcpo/
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;docker build &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; mcpo &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
mcpo         latest    98c0476e1d50   15 seconds ago   539MB

&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;docker run &lt;span class=&quot;nt&quot;&gt;--rm&lt;/span&gt; mcpo

 Usage: mcpo &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;OPTIONS]

╭─ Options ────────────────────────────────────────────────────────────────────╮
│ &lt;span class=&quot;nt&quot;&gt;--host&lt;/span&gt;                &lt;span class=&quot;nt&quot;&gt;-h&lt;/span&gt;      TEXT     Host address &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;default: 0.0.0.0]       │
│ &lt;span class=&quot;nt&quot;&gt;--port&lt;/span&gt;                &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt;      INTEGER  Port number &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;default: 8000]           │
│ &lt;span class=&quot;nt&quot;&gt;--cors-allow-origins&lt;/span&gt;          TEXT     CORS allowed origins &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;default: &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;     │
│ &lt;span class=&quot;nt&quot;&gt;--api-key&lt;/span&gt;             &lt;span class=&quot;nt&quot;&gt;-k&lt;/span&gt;      TEXT     API key &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;authentication            │
│ &lt;span class=&quot;nt&quot;&gt;--strict-auth&lt;/span&gt;                          API key protects all endpoints and    │
│                                        documentation                         │
│ &lt;span class=&quot;nt&quot;&gt;--env&lt;/span&gt;                 &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt;      TEXT     Environment variables                 │
│ &lt;span class=&quot;nt&quot;&gt;--env-path&lt;/span&gt;                    TEXT     Path to environment variables file    │
│ &lt;span class=&quot;nt&quot;&gt;--type&lt;/span&gt;,--server-type          TEXT     Server &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;default: stdio]          │
│ &lt;span class=&quot;nt&quot;&gt;--config&lt;/span&gt;              &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt;      TEXT     Config file path                      │
│ &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt;                &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt;      TEXT     Server name                           │
│ &lt;span class=&quot;nt&quot;&gt;--description&lt;/span&gt;         &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt;      TEXT     Server description                    │
│ &lt;span class=&quot;nt&quot;&gt;--version&lt;/span&gt;             &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;      TEXT     Server version                        │
│ &lt;span class=&quot;nt&quot;&gt;--ssl-certfile&lt;/span&gt;        &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt;      TEXT     SSL certfile                          │
│ &lt;span class=&quot;nt&quot;&gt;--ssl-keyfile&lt;/span&gt;         &lt;span class=&quot;nt&quot;&gt;-K&lt;/span&gt;      TEXT     SSL keyfile                           │
│ &lt;span class=&quot;nt&quot;&gt;--root-path&lt;/span&gt;                   TEXT     Root path                             │
│ &lt;span class=&quot;nt&quot;&gt;--path-prefix&lt;/span&gt;                 TEXT     URL prefix                            │
│ &lt;span class=&quot;nt&quot;&gt;--header&lt;/span&gt;              &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt;      TEXT     Headers &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;JSON format                │
│ &lt;span class=&quot;nt&quot;&gt;--hot-reload&lt;/span&gt;                           Enable hot reload &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;config file     │
│                                        changes                               │
│ &lt;span class=&quot;nt&quot;&gt;--log-level&lt;/span&gt;                   TEXT     Set log level &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;DEBUG, INFO, WARNING,  │
│                                        ERROR, CRITICAL&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;                      │
│ &lt;span class=&quot;nt&quot;&gt;--install-completion&lt;/span&gt;                   Install completion &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;the current    │
│                                        shell.                                │
│ &lt;span class=&quot;nt&quot;&gt;--show-completion&lt;/span&gt;                      Show completion &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;the current       │
│                                        shell, to copy it or customize the    │
│                                        installation.                         │
│ &lt;span class=&quot;nt&quot;&gt;--help&lt;/span&gt;                                 Show this message and exit.           │
╰──────────────────────────────────────────────────────────────────────────────╯
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;사용-방법&quot;&gt;사용 방법&lt;/h1&gt;

&lt;p&gt;먼저 사용할 MCP 서버들을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;json&lt;/code&gt; 형태로 선언합니다.&lt;/p&gt;

&lt;p&gt;테스트에 활용될 MCP 서버는 아래와 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;time&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memory&lt;/code&gt; 를 사용하도록 하겠습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mcpo.json&lt;/code&gt; 예제입니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; ~/mcpo.json
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;mcpServers&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;time&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;command&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;uvx&quot;&lt;/span&gt;,
      &lt;span class=&quot;s2&quot;&gt;&quot;args&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;mcp-server-time&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;--local-timezone=Asia/Seoul&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;memory&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;command&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;npx&quot;&lt;/span&gt;,
      &lt;span class=&quot;s2&quot;&gt;&quot;args&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-y&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;@modelcontextprotocol/server-memory&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
      &lt;span class=&quot;s2&quot;&gt;&quot;tags&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;memory&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;notes&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;아래와 같은 방법으로 빌드한 이미지를 실행하고 미리 작성한 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mcpo.json&lt;/code&gt; 을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;—config&lt;/code&gt; 옵션을 이용하여 지정합니다.&lt;/p&gt;

&lt;p&gt;참고로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--api-key &quot;top-secret&quot;&lt;/code&gt;   옵션을 추가하면 API 인증을 설정 할 수 있으니, 구성 환경에 적합하게 활용하면 도움이 될 것 같습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;docker run &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; 8000:8000 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; /root/mcpo.json:/app/mcpo.json &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;--restart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;always &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt; mcpo mcpo &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; mcpo &lt;span class=&quot;nt&quot;&gt;--config&lt;/span&gt; /app/mcpo.json
5414cbd48fd916fd1e9582ade16157a6cc0238c5ae631c830dc411eb4e39817c

&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;docker logs &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; mcpo
...
2026-01-05 00:48:28,993 - INFO - Successfully connected to &lt;span class=&quot;s1&quot;&gt;&apos;time&apos;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
2026-01-05 00:48:28,994 - INFO - Initiating connection &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;server: &lt;span class=&quot;s1&quot;&gt;&apos;memory&apos;&lt;/span&gt;...
Knowledge Graph MCP Server running on stdio
2026-01-05 00:48:39,094 - INFO - Successfully connected to &lt;span class=&quot;s1&quot;&gt;&apos;memory&apos;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
2026-01-05 00:48:39,095 - INFO -
&lt;span class=&quot;nt&quot;&gt;---&lt;/span&gt; Server Startup Summary &lt;span class=&quot;nt&quot;&gt;---&lt;/span&gt;
2026-01-05 00:48:39,095 - INFO - Successfully connected to:
2026-01-05 00:48:39,096 - INFO -   - &lt;span class=&quot;nb&quot;&gt;time
&lt;/span&gt;2026-01-05 00:48:39,096 - INFO -   - memory
2026-01-05 00:48:39,097 - INFO - &lt;span class=&quot;nt&quot;&gt;--------------------------&lt;/span&gt;

INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Press CTRL+C to quit&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker logs&lt;/code&gt; 를 이용하여 현재 시작된 MCP 서버를 확인 할 수 있으며, 아래와 같은 방법으로 OpenAPI 호환 API 를 호출 테스트를 할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;curl &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; localhost:8000/openapi.json | jq
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;openapi&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;3.1.0&quot;&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;info&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;title&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;MCP OpenAPI Proxy&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;description&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;Automatically generated API from MCP Tool Schemas&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;- **available tools**：&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;    - [time](/time/docs)&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;    - [memory](/memory/docs)&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;version&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;1.0&quot;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;paths&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;curl &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; localhost:8000/time/openapi.json | jq
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;openapi&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;3.1.0&quot;&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;info&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;title&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;mcp-time&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;description&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;mcp-time MCP Server&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;version&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;1.25.0&quot;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;servers&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;url&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;/time&quot;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;paths&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;/get_current_time&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;post&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;summary&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;Get Current Time&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;description&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;Get current time in a specific timezones&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;operationId&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;tool_get_current_time_post&quot;&lt;/span&gt;,
...

&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;curl &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; localhost:8000/memory/openapi.json | jq | &lt;span class=&quot;nb&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-n6&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;openapi&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;3.1.0&quot;&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;info&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;title&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;memory-server&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;description&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;memory-server MCP Server&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;version&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;0.6.3&quot;&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이와 같이 Proxy 된 MCP 서버를 &lt;a href=&quot;https://github.com/open-webui/open-webui&quot;&gt;Open WebUI&lt;/a&gt; 와 같은 도구에 연결하여 사용하거나, stdio 사용에 보안적인 문제로 인해 고민중이라면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mcpo&lt;/code&gt; 를 사용하는 것도 좋은 방안이 될 것 같습니다.&lt;/p&gt;

&lt;h1 id=&quot;참고-문서&quot;&gt;참고 문서&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;MCP Support - &lt;a href=&quot;https://docs.openwebui.com/features/plugin/tools/openapi-servers/mcp/&quot;&gt;https://docs.openwebui.com/features/plugin/tools/openapi-servers/mcp/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;mcpo - &lt;a href=&quot;https://github.com/open-webui/mcpo&quot;&gt;https://github.com/open-webui/mcpo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 05 Jan 2026 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/ai/2026/01/05/about-mcpo/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/ai/2026/01/05/about-mcpo/</guid>
        
        <category>linux</category>
        
        <category>ai</category>
        
        
        <category>ai</category>
        
      </item>
    
      <item>
        <title>Grype - 오픈 소스 취약점 스캔 도구</title>
        <description>&lt;p&gt;&lt;br /&gt;&lt;center&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/5199289/136855393-d0a9eef9-ccf1-4e2b-9d7c-7aad16a567e5.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;&lt;/p&gt;

&lt;h1 id=&quot;grype-란&quot;&gt;Grype 란?&lt;/h1&gt;

&lt;p&gt;Grype는 Anchore에서 개발한 오픈 소스 취약점 스캔 도구입니다. &lt;br /&gt;
컨테이너 이미지와 파일시스템에서 알려진 취약점을 빠르게 검색할 수 있으며, 다양한 패키지 관리자와 프로그래밍 언어를 지원합니다. &lt;br /&gt;
CVE 데이터베이스를 기반으로 보안 취약점을 식별하고, CI/CD 파이프라인에 통합하여 자동화된 보안 검사를 수행할 수 있습니다.&lt;/p&gt;

&lt;h1 id=&quot;grype-설치&quot;&gt;Grype 설치&lt;/h1&gt;

&lt;p&gt;Grype는 간단한 설치 스크립트를 통해 설치할 수 있습니다.  &lt;br /&gt;
아래 명령어는 최신 버전을 다운로드하여 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/local/bin&lt;/code&gt; 디렉토리에 설치합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;curl &lt;span class=&quot;nt&quot;&gt;-sSfL&lt;/span&gt; https://get.anchore.io/grype | &lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;sh &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-b&lt;/span&gt; /usr/local/bin
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;info]&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;33[0m checking github &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;the current release tag &lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;33[0m
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;info]&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;33[0m fetching release script &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;v0.103.0&apos;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;33[0m
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;info]&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;33[0m checking github &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;the current release tag &lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;33[0m
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;info]&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;33[0m using release &lt;span class=&quot;nv&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;v0.103.0&apos;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;0.103.0&apos;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;linux&apos;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;arch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;amd64&apos;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;33[0m
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;info]&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;33[0m installed /usr/local/bin/grype &lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;33[0m

&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;which grype
/usr/local/bin/grype
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;grype-사용법&quot;&gt;Grype 사용법&lt;/h1&gt;

&lt;h2 id=&quot;cve-데이터베이스-검색&quot;&gt;CVE 데이터베이스 검색&lt;/h2&gt;

&lt;p&gt;특정 CVE 번호로 취약점 정보를 검색할 수 있습니다. 이 명령어는 Grype의 취약점 데이터베이스에서 해당 CVE가 영향을 미치는 패키지와 버전 정보를 조회합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;grype db search &lt;span class=&quot;s2&quot;&gt;&quot;CVE-2024-56737&quot;&lt;/span&gt;
VULNERABILITY   PACKAGE                              ECOSYSTEM  NAMESPACE                      VERSION CONSTRAINT
CVE-2024-56737  cpe:2.3:a:gnu:grub2:&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;:&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;:&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;:&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;:&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;:&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;:&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;:&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;             nvd:cpe                        &amp;lt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 2.12
CVE-2024-56737  grub2                                deb        debian:distro:debian:11
CVE-2024-56737  grub2                                deb        debian:distro:debian:12
CVE-2024-56737  grub2                                deb        debian:distro:debian:13        &amp;lt; 2.12-6
CVE-2024-56737  grub2                                deb        debian:distro:debian:14        &amp;lt; 2.12-6
CVE-2024-56737  grub2                                deb        debian:distro:debian:unstable  &amp;lt; 2.12-6
CVE-2024-56737  grub2                                deb        &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt;:distro:echo:rolling       &amp;lt; 2.12-6
CVE-2024-56737  grub2                                rpm        mariner:distro:azurelinux:3.0  &amp;lt; 0:2.06-25.azl3
CVE-2024-56737  grub2                                rpm        mariner:distro:mariner:2.0     &amp;lt; 0:2.06-15.cm2
CVE-2024-56737  grub2                                rpm        sles:distro:sles:12.3          &amp;lt; 0:2.02-150.1
CVE-2024-56737  grub2                                rpm        sles:distro:sles:12.5          &amp;lt; 0:2.02-181.2 &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &amp;lt; 0:2.02-181.2
CVE-2024-56737  grub2                                rpm        sles:distro:sles:15.3          &amp;lt; 0:2.04-150300.22.52.3
CVE-2024-56737  grub2                                rpm        sles:distro:sles:15.4          &amp;lt; 0:2.06-150400.11.55.2 &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &amp;lt; 0:2.06-150400.11.55.2
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;시스템-전체-스캔&quot;&gt;시스템 전체 스캔&lt;/h2&gt;

&lt;p&gt;아래와 같은 방법을 통해 시스템 전체에 대해 스캔 할 수 있습니다. &lt;br /&gt;
이번 글에서는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ignore-package.yml&lt;/code&gt; 를 이용하여 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;runc&lt;/code&gt; 패키지의 취약점만 확인 할 수 있도록 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ignore&lt;/code&gt; 옵션을 활용하였습니다.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;$ cat ignore-package.yml&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;ignore&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;linux-kernel&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;linux-kernel&quot;&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;*&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;python&quot;&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;*&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;go-module&quot;&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;kernel&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;rpm&quot;&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;kernel-libbpf&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;rpm&quot;&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;kernel-tools&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;rpm&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;설정 파일을 적용하여 루트 디렉토리를 스캔합니다. 스캔 결과에는 발견된 취약점의 심각도, 설치된 버전, 수정 버전 등이 표시됩니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;grype / &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; ignore-package.yml
 ✔ Indexed file system                                                                                     /
 ✔ Cataloged contents                       8a5edab282632443219e051e4ade2d1d5bbc671c781051bf1437897cbdfea0f1
   ├── ✔ Packages                        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;1,321 packages]
   ├── ✔ Executables                     &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;1,889 executables]
   ├── ✔ File metadata                   &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;42,029 locations]
   └── ✔ File digests                    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;42,029 files]
 ✔ Scanned &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;vulnerabilities     &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;5 vulnerability matches]
   ├── by severity: 7 critical, 1526 high, 3982 medium, 58 low, 0 negligible
   └── by status:   5105 fixed, 468 not-fixed, 5568 ignored
NAME  INSTALLED              FIXED IN               TYPE  VULNERABILITY       SEVERITY  EPSS           RISK
runc  1.1.11-1.amzn2023.0.1  1.1.13-1.amzn2023.0.1  rpm   ALAS2023-2024-710   Medium    &amp;lt; 0.1% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;24th&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;  &amp;lt; 0.1
runc  1.1.11-1.amzn2023.0.1  1.2.4-2.amzn2023.0.1   rpm   ALAS2023-2025-1041  High      &amp;lt; 0.1% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;5th&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   &amp;lt; 0.1
runc  1.1.11-1.amzn2023.0.1  1.1.14-1.amzn2023.0.1  rpm   ALAS2023-2024-725   Low       &amp;lt; 0.1% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;4th&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   &amp;lt; 0.1
runc  1.1.11-1.amzn2023.0.1  1.3.2-2.amzn2023.0.1   rpm   ALAS2023-2025-1263  High      &amp;lt; 0.1% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0th&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   &amp;lt; 0.1
runc  1.1.11-1.amzn2023.0.1  1.2.6-1.amzn2023.0.1   rpm   ALAS2023-2025-1078  Medium    &amp;lt; 0.1% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0th&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   &amp;lt; 0.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;취약점-패치-적용&quot;&gt;취약점 패치 적용&lt;/h2&gt;

&lt;p&gt;스캔 결과에서 발견된 취약점을 해결하기 위해 패키지를 업데이트합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;rpm &lt;span class=&quot;nt&quot;&gt;-qa&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;runc
runc-1.1.11-1.amzn2023.0.1.x86_64

&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;yum update runc
...
Upgraded:
  runc-1.3.3-2.amzn2023.0.1.x86_64

Complete!

&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;rpm &lt;span class=&quot;nt&quot;&gt;-qa&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;runc
runc-1.3.3-2.amzn2023.0.1.x86_64
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;패치-후-재스캔&quot;&gt;패치 후 재스캔&lt;/h2&gt;

&lt;p&gt;패키지 업데이트 후 다시 스캔하여 취약점이 해결되었는지 확인합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;grype / &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; ignore-package.yml
 ✔ Indexed file system                                                                                  /
 ✔ Vulnerability DB                &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;no update available]
 ✔ Cataloged contents                    8a5edab282632443219e051e4ade2d1d5bbc671c781051bf1437897cbdfea0f1
   ├── ✔ Packages                        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;1,322 packages]
   ├── ✔ Executables                     &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;1,890 executables]
   ├── ✔ File metadata                   &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;42,034 locations]
   └── ✔ File digests                    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;42,034 files]
 ✔ Scanned &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;vulnerabilities     &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0 vulnerability matches]
   ├── by severity: 4 critical, 1509 high, 3961 medium, 57 low, 0 negligible
   └── by status:   5063 fixed, 468 not-fixed, 5531 ignored
No vulnerabilities found
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;보시는 것처럼 취약점이 해결된 것을 확인 할 수 있었습니다.&lt;/p&gt;

&lt;h1 id=&quot;컨테이너-이미지-검사&quot;&gt;컨테이너 이미지 검사&lt;/h1&gt;

&lt;p&gt;Grype 는 Docker 이미지의 취약점도 검사할 수 있습니다.&lt;/p&gt;

&lt;p&gt;사용 방법은 아래와 같습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;grype docker.io/library/nginx:1.28.0-alpine
 ✔ Loaded image                                                           index.docker.io/library/nginx:1.28.0-alpine
 ✔ Parsed image                               sha256:c318e336065b17ff460aeac6d14bce5d0b13e35f25d5cb1843b635359fc00c9a
 ✔ Cataloged contents                                c9fe5d237739ac0665d879b1ca8e4a81b8c1ab0a6158922e59937ca8163b43a7
   ├── ✔ Packages                        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;68 packages]
   ├── ✔ File digests                    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;976 files]
   ├── ✔ File metadata                   &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;976 locations]
   └── ✔ Executables                     &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;123 executables]
 ✔ Scanned &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;vulnerabilities     &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;15 vulnerability matches]
   ├── by severity: 2 critical, 3 high, 3 medium, 7 low, 0 negligible
NAME           INSTALLED   FIXED IN   TYPE  VULNERABILITY   SEVERITY  EPSS          RISK
libxml2        2.13.4-r6   2.13.9-r0  apk   CVE-2025-49796  Critical  0.4% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;62nd&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   0.4
libxml2        2.13.4-r6   2.13.9-r0  apk   CVE-2025-6021   High      0.4% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;58th&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   0.3
tiff           4.7.1-r0               apk   CVE-2023-6277   Medium    0.4% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;61st&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   0.2
libxml2        2.13.4-r6   2.13.9-r0  apk   CVE-2025-49794  Critical  0.3% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;48th&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   0.2
tiff           4.7.1-r0               apk   CVE-2023-52356  High      0.3% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;49th&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   0.2
libxml2        2.13.4-r6   2.13.9-r0  apk   CVE-2025-49795  High      0.1% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;34th&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   0.1
nginx          1.28.0-r1              apk   CVE-2025-53859  Medium    0.1% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;28th&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   &amp;lt; 0.1
tiff           4.7.1-r0               apk   CVE-2023-6228   Medium    &amp;lt; 0.1% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2nd&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;  &amp;lt; 0.1
libxml2        2.13.4-r6   2.13.9-r0  apk   CVE-2025-6170   Low       &amp;lt; 0.1% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;6th&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;  &amp;lt; 0.1
busybox        1.37.0-r13             apk   CVE-2025-46394  Low       &amp;lt; 0.1% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1st&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;  &amp;lt; 0.1
busybox-binsh  1.37.0-r13             apk   CVE-2025-46394  Low       &amp;lt; 0.1% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1st&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;  &amp;lt; 0.1
ssl_client     1.37.0-r13             apk   CVE-2025-46394  Low       &amp;lt; 0.1% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1st&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;  &amp;lt; 0.1
busybox        1.37.0-r13             apk   CVE-2024-58251  Low       &amp;lt; 0.1% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3rd&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;  &amp;lt; 0.1
busybox-binsh  1.37.0-r13             apk   CVE-2024-58251  Low       &amp;lt; 0.1% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3rd&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;  &amp;lt; 0.1
ssl_client     1.37.0-r13             apk   CVE-2024-58251  Low       &amp;lt; 0.1% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3rd&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;  &amp;lt; 0.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;스캔 결과는 취약점의 심각도(Critical, High, Medium, Low)와 EPSS(Exploit Prediction Scoring System) 점수를 포함하여 우선순위를 판단할 수 있도록 출력합니다.&lt;/p&gt;

&lt;h1 id=&quot;참고-문서&quot;&gt;참고 문서&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/anchore/grype&quot;&gt;https://github.com/anchore/grype&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 12 Nov 2025 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/linux/2025/11/12/grype/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/linux/2025/11/12/grype/</guid>
        
        <category>linux</category>
        
        
        <category>linux</category>
        
      </item>
    
      <item>
        <title>[Linux] Loop Mount 구성</title>
        <description>&lt;h1 id=&quot;loop-devive-란&quot;&gt;Loop Devive 란?&lt;/h1&gt;
&lt;p&gt;루프 장치(Loop device)는 유닉스 계열 운영 체제에서 특정 파일을 일반 블록 장치처럼 접근할 수 있게 해주는 가상 장치로, 파일 시스템이 포함된 ISO 이미지나 디스크 이미지를 마운트하는 등의 용도로 사용됩니다.  &lt;br /&gt;
루프 장치를 통해 파일 전체를 하나의 디스크처럼 취급하여 해당 파일 시스템을 직접 마운트하고 읽거나 쓸 수 있습니다.&lt;/p&gt;

&lt;h1 id=&quot;mount-the-loop-device&quot;&gt;Mount the Loop device&lt;/h1&gt;
&lt;p&gt;이러한 Loop Device 와 같은 가상 장치를 통해 Cloud Image, ISO, 파일을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mount&lt;/code&gt; 하고 블록 장치와 같은 형태로 사용 할 수 있습니다.&lt;/p&gt;

&lt;p&gt;이번 글에서는 Cloud Image 의 형태에 따라 Loop device 를 사용하는 방법에 대해 작성해보았습니다.&lt;/p&gt;

&lt;h2 id=&quot;single-partition-구조&quot;&gt;Single Partition 구조&lt;/h2&gt;
&lt;p&gt;일반적으로 파티션 한개를 이미지 백업 받은 파일을 loop device 를 이용하여 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mount&lt;/code&gt; 하는 방법은 일반적인 ISO 이미지를 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mount&lt;/code&gt; 하는 방법과 유사합니다.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;parted part-image-backup.img unit B print
&lt;span class=&quot;go&quot;&gt;Model:  (file)
Disk /data/part-image-backup.img: 8587820544B
Sector size (logical/physical): 512B/512B
Partition Table: loop
Disk Flags:

Number  Start  End          Size         File system  Flags
 1      0B     8587820543B  8587820544B  xfs

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;한개의 파티션을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dd&lt;/code&gt; 를 통해 파일로 생성한 형태의 구조입니다.&lt;/p&gt;

&lt;p&gt;이런 경우, 아래와 같은 방법으로 파일시스템 탑재를 하고 수정 및 확인이 가능합니다.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;mount &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; loop,nouuid part-image-backup.img /mnt
&lt;span class=&quot;go&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;lsblk
&lt;span class=&quot;go&quot;&gt;NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
loop0     7:0    0    8G  0 loop /mnt        &amp;lt;&amp;lt;&amp;lt;----!!!
&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;...
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; /mnt/etc/os-release |head &lt;span class=&quot;nt&quot;&gt;-n1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;NAME=&quot;Amazon Linux&quot;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;multiple-partition-구조&quot;&gt;Multiple Partition 구조&lt;/h2&gt;
&lt;p&gt;디스크 (or 볼륨) 의 모든 파티션을 이미지 백업을 하거나 Cloud Image 와 같은 형태로 제공이 되는 파일을 loop device 를 이용하여 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mount&lt;/code&gt; 하여 사용이 가능하게 하는 방법입니다.&lt;/p&gt;

&lt;p&gt;테스트에 사용된 Cloud Image 정보는 아래와 같습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;qemu-img info rhel-9.6-x86_64-kvm.raw
image: rhel-9.6-x86_64-kvm.raw
file format: raw
virtual size: 10 GiB &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;10737418240 bytes&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
disk size: 1.61 GiB
Child node &lt;span class=&quot;s1&quot;&gt;&apos;/file&apos;&lt;/span&gt;:
    filename: rhel-9.6-x86_64-kvm.raw
    protocol &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;: file
    file length: 10 GiB &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;10737418240 bytes&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    disk size: 1.61 GiB
    Format specific information:
        extent size hint: 1048576
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;먼저 이미지의 파티션 구조를 파악합니다.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;parted rhel-9.6-x86_64-kvm.raw unit B print
&lt;span class=&quot;go&quot;&gt;Model:  (file)
Disk /root/rhel-9.6-x86_64-kvm.raw: 10737418240B
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start        End           Size         File system  Name  Flags
 1      1048576B     2097151B      1048576B                        bios_grub
 2      2097152B     211812351B    209715200B   fat16              boot, esp
 3      211812352B   1285554175B   1073741824B  xfs                bls_boot
 4      1285554176B  10737401343B  9451847168B  xfs
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/&lt;/code&gt; 파일시스템은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1285554176&lt;/code&gt; B 부터 섹터가 시작이 되는 것으로 확인 됩니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;losetup&lt;/code&gt; 명령어를 통해 파티션 시작 섹터를 지정하여 loop device 생성합니다.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;losetup &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; 1285554176 /dev/loop0 rhel-9.6-x86_64-kvm.raw
&lt;span class=&quot;go&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;losetup &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;NAME       SIZELIMIT     OFFSET AUTOCLEAR RO BACK-FILE                     DIO LOG-SEC
/dev/loop0         0 1285554176         0  0 /root/rhel-9.6-x86_64-kvm.raw   0     512
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 loop0 디바이스가 생성이 되면 아래와 같은 방법을 통해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mount&lt;/code&gt; 를 수행하고 파일시스템을 탑재할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;lsblk
NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
loop0           7:0    0  8.8G  0 loop
nvme0n1       259:0    0   50G  0 disk
├─nvme0n1p1   259:1    0   50G  0 part /
├─nvme0n1p127 259:2    0    1M  0 part
└─nvme0n1p128 259:3    0   10M  0 part /boot/efi

&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;mount /dev/loop0 /mnt

&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo cat&lt;/span&gt; /mnt/etc/redhat-release
Red Hat Enterprise Linux release 9.6 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Plow&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;참고-문서&quot;&gt;참고 문서&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://linux.die.net/man/8/losetup&quot;&gt;https://linux.die.net/man/8/losetup&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 29 Sep 2025 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/linux/2025/09/29/loop-mount/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/linux/2025/09/29/loop-mount/</guid>
        
        <category>linux</category>
        
        
        <category>linux</category>
        
      </item>
    
      <item>
        <title>[AWS] CloudFormation과 SSM을 이용한 RHEL HA 클러스터 자동 구성</title>
        <description>&lt;p&gt;&lt;img src=&quot;https://clusterlabs.org/projects/pacemaker/doc/deprecated/en-US/Pacemaker/2.0/html-single/Pacemaker_Administration/Common_Content/images/title_logo.svg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;rhel-ha-클러스터-자동-구성&quot;&gt;RHEL HA 클러스터 자동 구성&lt;/h1&gt;
&lt;p&gt;AWS에서 RHEL 기반 고가용성(HA) 클러스터를 자동으로 구성하는 솔루션을 소개합니다. &lt;br /&gt;
CloudFormation 템플릿과 SSM 문서를 활용하여 Pacemaker 기반의 HA 클러스터를 완전 자동화된 방식으로 배포할 수 있습니다.&lt;/p&gt;

&lt;center&gt;&lt;h1 style=&quot;color: red;&quot;&gt;
&lt;br /&gt; [주의] 해당 솔루션은 POC 환경 혹은 개발 환경, 이슈 재현 환경등으로 사용하는 것을 권장 드립니다. &lt;br /&gt; &lt;br /&gt;
운영 환경에는 적합한 설정이 아닌 부분이 있을 수 있습니다.&lt;br /&gt; &lt;br /&gt;
&lt;/h1&gt;&lt;/center&gt;

&lt;h1 id=&quot;솔루션-소스&quot;&gt;솔루션 소스&lt;/h1&gt;
&lt;p&gt;Github 의 &lt;a href=&quot;https://github.com/chhanz/rhel.ha-cluster_pacemaker_on_aws&quot;&gt;chhanz/rhel.ha-cluster_pacemaker_on_aws&lt;/a&gt; 에서 소스를 제공하고 있습니다.&lt;/p&gt;

&lt;h1 id=&quot;솔루션-개요&quot;&gt;솔루션 개요&lt;/h1&gt;
&lt;p&gt;이 솔루션은 두 가지 주요 구성 요소로 이루어져 있습니다:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;CloudFormation 템플릿&lt;/strong&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deployment.yaml&lt;/code&gt;) - AWS 인프라 자동 구성&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;SSM 문서&lt;/strong&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ha-cluster-setup-document.json&lt;/code&gt;) - HA 클러스터 자동 설정&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;아키텍처-구성&quot;&gt;아키텍처 구성&lt;/h2&gt;
&lt;h3 id=&quot;인프라-구성&quot;&gt;인프라 구성&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;기본 리전 : ap-northeast-2 (서울)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;VPC&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;10.0.0.0/16&lt;/code&gt; CIDR 블록&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;서브넷&lt;/strong&gt;:
    &lt;ul&gt;
      &lt;li&gt;SubnetB (ap-northeast-2b): &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;10.0.1.0/24&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;SubnetD (ap-northeast-2d): &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;10.0.2.0/24&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;EC2 인스턴스&lt;/strong&gt;: RHEL 9.6 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t3.medium&lt;/code&gt;) 2대&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;보안 그룹&lt;/strong&gt;: 클러스터 내부 통신 허용&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;IAM 역할&lt;/strong&gt;: STONITH 및 Elastic IP 관리 권한&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;ha-클러스터-구성&quot;&gt;HA 클러스터 구성&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Pacemaker/Corosync&lt;/strong&gt; 기반 클러스터&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;STONITH&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fence_aws&lt;/code&gt; 사용&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Ansible&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rhel-system-roles&lt;/code&gt; 로 자동 구성&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;선택적 Dummy 리소스&lt;/strong&gt;: 테스트용 Dummy 리소스&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;배포-과정&quot;&gt;배포 과정&lt;/h1&gt;

&lt;h2 id=&quot;1단계-인프라-배포&quot;&gt;1단계: 인프라 배포&lt;/h2&gt;
&lt;p&gt;CloudFormation 스택을 생성하여 AWS 인프라를 구성합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# CloudFormation 스택 생성&lt;/span&gt;
aws cloudformation create-stack &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--stack-name&lt;/span&gt; rhel-ha-cluster &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--template-body&lt;/span&gt; file://deployment.yaml &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--parameters&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ParameterKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;SameSubnet,ParameterValue&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--capabilities&lt;/span&gt; CAPABILITY_NAMED_IAM &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--region&lt;/span&gt; ap-northeast-2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;파라미터-설명&quot;&gt;파라미터 설명&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SameSubnet&lt;/code&gt;:
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt; (기본값): 서로 다른 AZ에 배치 (권장)&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt;: 같은 서브넷에 배치&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;인스턴스가 생성되고 운영체제 업데이트 및 최초 설정 작업이 수행되고, 운영체제 재부팅이 진행 될 것 입니다.  &lt;br /&gt;
진행이 완료된 이후, 다음 단계로 가시면 됩니다.&lt;/p&gt;

&lt;h2 id=&quot;2단계-ssm-문서-생성&quot;&gt;2단계: SSM 문서 생성&lt;/h2&gt;
&lt;p&gt;HA 클러스터 자동 설정을 위한 SSM 문서를 생성합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# SSM 문서 생성&lt;/span&gt;
aws ssm create-document &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;HA-Cluster-Setup&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--document-type&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Command&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--document-format&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;JSON&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--content&lt;/span&gt; file://ha-cluster-setup-document.json &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--region&lt;/span&gt; ap-northeast-2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;3단계-ha-클러스터-구성&quot;&gt;3단계: HA 클러스터 구성&lt;/h2&gt;
&lt;p&gt;생성된 인스턴스에서 HA 클러스터를 자동으로 구성합니다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;[주의] HA 클러스터 설정 실행은 Node 1 에서만 SSM 문서 “명령 실행” 을 수행합니다.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# 인스턴스 정보 확인&lt;/span&gt;
aws cloudformation describe-stacks &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--stack-name&lt;/span&gt; rhel-ha-cluster &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--query&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Stacks[0].Outputs&apos;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--region&lt;/span&gt; ap-northeast-2

&lt;span class=&quot;c&quot;&gt;# HA 클러스터 설정 실행 &amp;gt; Node 1 로 사용될 인스턴스 한대에 대상으로 SSM 문서 명령 실행&lt;/span&gt;
aws ssm send-command &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--document-name&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;HA-Cluster-Setup&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--instance-ids&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;i-xxxxxxxxx&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--parameters&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;{
        &quot;Node1InstanceId&quot;:&quot;i-xxxxxxxxx&quot;,
        &quot;Node1PrivateIP&quot;:&quot;10.0.1.10&quot;,
        &quot;Node2InstanceId&quot;:&quot;i-yyyyyyyyy&quot;,
        &quot;Node2PrivateIP&quot;:&quot;10.0.2.20&quot;,
        &quot;ClusterPassword&quot;:&quot;secure-password&quot;,
        &quot;ClusterName&quot;:&quot;my-ha-cluster&quot;,
        &quot;DeployDummyResource&quot;:&quot;false&quot;
    }&apos;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--region&lt;/span&gt; ap-northeast-2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;혹은 Systems Manager &amp;gt; “문서” 에서 “HA-Cluster-Setup” 를 검색하고 실행하면 AWS 콘솔에서도 각 파라미터를 입력 할 수 있도록 제공합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2025-08-20-pcs-ssm/ssm-para.png&quot; alt=&quot;HA-Cluster-Setup 파라미터&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;주요-기능&quot;&gt;주요 기능&lt;/h1&gt;

&lt;h2 id=&quot;자동화된-구성&quot;&gt;자동화된 구성&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;시스템 업데이트&lt;/strong&gt;: 최신 패키지로 자동 업데이트&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;사용자 생성&lt;/strong&gt;: haadm 계정 자동 생성&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;인스턴스 연결&lt;/strong&gt;: Session Manager 를 사용하도록 설정&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;필수 패키지&lt;/strong&gt;: rhel-system-roles, AWS CLI, 기타 도구 설치&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;ha-클러스터-설정&quot;&gt;HA 클러스터 설정&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;방화벽/SELinux&lt;/strong&gt;: 자동 비활성화&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;부팅 시 시작&lt;/strong&gt;: 비활성화 (수동 시작)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;클라우드 에이전트&lt;/strong&gt;: 자동 설치&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;STONITH 설정&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fence_aws&lt;/code&gt; 사용&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;네트워크-구성&quot;&gt;네트워크 구성&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;호스트 파일&lt;/strong&gt;: 자동 업데이트 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/hosts&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Ansible 인벤토리&lt;/strong&gt;: 동적 생성&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;생성되는-파일들&quot;&gt;생성되는 파일들&lt;/h1&gt;
&lt;p&gt;SSM 문서 실행 시 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/local/ha_cluster/&lt;/code&gt;에 다음 파일들이 생성됩니다:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inventory.yml&lt;/code&gt;: Ansible 인벤토리&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;update-hosts.yaml&lt;/code&gt;: 호스트 파일 업데이트 플레이북&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fast-aws-playbook.yaml&lt;/code&gt;: HA 클러스터 배포 플레이북&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;group_vars/${CLUSTER_NAME}.yml&lt;/code&gt;: 클러스터 설정 변수&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;클러스터-상태-확인&quot;&gt;클러스터 상태 확인&lt;/h1&gt;
&lt;p&gt;배포 완료 후 클러스터 상태를 확인할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# 클러스터 상태 확인&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;pcs status
Cluster name: fast-aws-rh-cluster
Cluster Summary:
  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; Stack: corosync &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Pacemaker is running&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; Current DC: fast-aws-rh-node-1 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;version 2.1.9-1.2.el9_6-49aab9983&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; - partition with quorum
  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; Last updated: Wed Aug 20 04:51:15 2025 on fast-aws-rh-node-1
  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; Last change:  Wed Aug 20 04:50:26 2025 by root via root on fast-aws-rh-node-1
  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; 2 nodes configured
  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; 4 resource instances configured

Node List:
  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; Online: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; fast-aws-rh-node-1 fast-aws-rh-node-2 &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

Full List of Resources:
  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; mystonith   &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;stonith:fence_aws&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;:     Started fast-aws-rh-node-1
  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; example-1   &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;ocf:pacemaker:Dummy&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;:   Started fast-aws-rh-node-2
  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; example-2   &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;ocf:pacemaker:Dummy&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;:   Started fast-aws-rh-node-1
  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; example-3   &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;ocf:pacemaker:Dummy&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;:   Started fast-aws-rh-node-2

Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h1 id=&quot;클러스터-설정-확인&quot;&gt;클러스터 설정 확인&lt;/h1&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;pcs config
Cluster Name: fast-aws-rh-cluster
Corosync Nodes:
 fast-aws-rh-node-1 fast-aws-rh-node-2
Pacemaker Nodes:
 fast-aws-rh-node-1 fast-aws-rh-node-2

Resources:
  Resource: example-1 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ocf &lt;span class=&quot;nv&quot;&gt;provider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;pacemaker &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;Dummy&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    Operations:
      migrate_from: example-1-migrate_from-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      migrate_to: example-1-migrate_to-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      monitor: example-1-monitor-interval-10s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;10s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      reload: example-1-reload-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      reload-agent: example-1-reload-agent-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      start: example-1-start-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      stop: example-1-stop-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
  Resource: example-2 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ocf &lt;span class=&quot;nv&quot;&gt;provider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;pacemaker &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;Dummy&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    Operations:
      migrate_from: example-2-migrate_from-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      migrate_to: example-2-migrate_to-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      monitor: example-2-monitor-interval-10s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;10s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      reload: example-2-reload-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      reload-agent: example-2-reload-agent-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      start: example-2-start-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      stop: example-2-stop-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
  Resource: example-3 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ocf &lt;span class=&quot;nv&quot;&gt;provider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;pacemaker &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;Dummy&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    Operations:
      migrate_from: example-3-migrate_from-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      migrate_to: example-3-migrate_to-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      monitor: example-3-monitor-interval-10s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;10s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      reload: example-3-reload-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      reload-agent: example-3-reload-agent-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      start: example-3-start-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s
      stop: example-3-stop-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;20s

Stonith Devices:
  Resource: mystonith &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;stonith &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;fence_aws&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    Attributes: mystonith-instance_attributes
      &lt;span class=&quot;nv&quot;&gt;pcmk_delay_max&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;45
      &lt;span class=&quot;nv&quot;&gt;pcmk_host_map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;fast-aws-rh-node-1:i-123456789012abcdef&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;fast-aws-rh-node-2:i-09876543214321ffedcba
      &lt;span class=&quot;nv&quot;&gt;pcmk_reboot_retries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;4
      &lt;span class=&quot;nv&quot;&gt;pcmk_reboot_timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;600
      &lt;span class=&quot;nv&quot;&gt;power_timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;600
      &lt;span class=&quot;nv&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ap-northeast-2
    Operations:
      monitor: mystonith-monitor-interval-300
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;300 &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;60
      start: mystonith-start-interval-0s
        &lt;span class=&quot;nv&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0s &lt;span class=&quot;nb&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;600

Cluster Properties: cib-bootstrap-options
  cluster-infrastructure&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;corosync
  cluster-name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;fast-aws-rh-cluster
  dc-version&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;2.1.9-1.2.el9_6-49aab9983
  have-watchdog&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;false
  &lt;/span&gt;stonith-watchdog-timeout&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;stonith-테스트&quot;&gt;STONITH 테스트&lt;/h1&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;pcs stonith fence fast-aws-rh-node-2
Node: fast-aws-rh-node-2 fenced
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;정리&quot;&gt;정리&lt;/h1&gt;
&lt;p&gt;사용이 완료된 후에는 다음 명령어로 리소스를 정리할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# CloudFormation 스택 삭제&lt;/span&gt;
aws cloudformation delete-stack &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--stack-name&lt;/span&gt; rhel-ha-cluster &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--region&lt;/span&gt; ap-northeast-2

&lt;span class=&quot;c&quot;&gt;# SSM 문서 삭제&lt;/span&gt;
aws ssm delete-document &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;HA-Cluster-Setup&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--region&lt;/span&gt; ap-northeast-2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;참고-문서&quot;&gt;참고 문서&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;rhel.ha-cluster_pacemaker_on_aws:  &lt;br /&gt;
&lt;a href=&quot;https://github.com/chhanz/rhel.ha-cluster_pacemaker_on_aws&quot;&gt;https://github.com/chhanz/rhel.ha-cluster_pacemaker_on_aws&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Red Hat High Availability Add-On Reference :  &lt;br /&gt;
&lt;a href=&quot;https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/configuring_and_managing_high_availability_clusters/index&quot;&gt;https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/configuring_and_managing_high_availability_clusters/index&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 20 Aug 2025 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/aws/2025/08/20/aws-rhel-ha-cluster-automation/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/aws/2025/08/20/aws-rhel-ha-cluster-automation/</guid>
        
        <category>aws</category>
        
        <category>linux</category>
        
        <category>cloud</category>
        
        
        <category>aws</category>
        
      </item>
    
      <item>
        <title>UV - Rust로 작성된 빠른 Python 패키지 관리자</title>
        <description>&lt;h1 id=&quot;uv&quot;&gt;UV&lt;/h1&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UV&lt;/code&gt; 는 Rust로 작성된 Python 패키지 및 프로젝트 관리자로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip&lt;/code&gt; 의 대안으로 떠오르는 패키지 관리자입니다.&lt;/p&gt;

&lt;h1 id=&quot;highlights&quot;&gt;Highlights&lt;/h1&gt;

&lt;p&gt;🚀 pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv 등을 대체하는 단일 도구입니다. &lt;br /&gt;
 ⚡️ pip보다 10-100배 빠릅니다. &lt;br /&gt;
 🗂️ 범용 잠금 파일을 통한 포괄적인 프로젝트 관리를 제공합니다. &lt;br /&gt;
 ❇️ 인라인 의존성 메타데이터를 지원하여 스크립트를 실행합니다. &lt;br /&gt;
 🐍 Python 버전을 설치하고 관리합니다. &lt;br /&gt;
 🛠️ Python 패키지로 게시된 도구를 실행하고 설치합니다. &lt;br /&gt;
 🔩 친숙한 CLI로 성능 향상을 위한 pip 호환 인터페이스를 포함합니다. &lt;br /&gt;
 🏢 확장 가능한 프로젝트를 위한 Cargo 스타일 워크스페이스를 지원합니다. &lt;br /&gt;
 💾 의존성 중복 제거를 위한 글로벌 캐시로 디스크 공간을 효율적으로 사용합니다. &lt;br /&gt;
 ⏬ curl 또는 pip을 통해 Rust나 Python 없이도 설치 가능합니다. &lt;br /&gt;
 🖥️ macOS, Linux, Windows를 지원합니다.&lt;/p&gt;

&lt;h1 id=&quot;installation&quot;&gt;Installation&lt;/h1&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/&amp;gt; # python --version
Python 2.7.18          &amp;lt;&amp;lt;&amp;lt;---- 운영체제 Python 버전

/&amp;gt; # curl -LsSf https://astral.sh/uv/install.sh | sh
downloading uv 0.8.4 x86_64-unknown-linux-gnu
no checksums to verify
installing to /root/.local/bin
  uv
  uvx
everything&apos;s installed!

To add $HOME/.local/bin to your PATH, either restart your shell or run:

    source $HOME/.local/bin/env (sh, bash, zsh)
    source $HOME/.local/bin/env.fish (fish)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;how-to&quot;&gt;How to&lt;/h1&gt;

&lt;h2 id=&quot;프로젝트-초기화&quot;&gt;프로젝트 초기화&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/&amp;gt; # uv init uv-test
Initialized project `uv-test` at `/root/uv-test`

/&amp;gt; # cd uv-test; tree -a
.
├── main.py
├── pyproject.toml    &amp;lt;&amp;lt;--- 프로젝트의 메타데이터와 설정을 저장하는 파일
├── .python-version   &amp;lt;&amp;lt;--- 프로젝트에서 사용할 Python 버전을 지정하는 파일
└── README.md
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;의존성-패키지-추가&quot;&gt;의존성 패키지 추가&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/&amp;gt; uv add flask
Using CPython 3.7.16 interpreter at: /usr/bin/python3.7
Creating virtual environment at: .venv
Resolved 24 packages in 115ms
Prepared 9 packages in 53ms
Installed 9 packages in 15ms
 + click==8.1.8
 + flask==2.2.5
 + importlib-metadata==6.7.0
 + itsdangerous==2.1.2
 + jinja2==3.1.6
 + markupsafe==2.1.5
 + typing-extensions==4.7.1
 + werkzeug==2.2.3
 + zipp==3.15.0

/&amp;gt; # cat uv.lock
version = 1
revision = 3
requires-python = &quot;&amp;gt;=3.7&quot;
resolution-markers = [
    &quot;python_full_version &amp;gt;= &apos;3.10&apos;&quot;,
    &quot;python_full_version == &apos;3.9.*&apos;&quot;,
    &quot;python_full_version == &apos;3.8.*&apos;&quot;,
    &quot;python_full_version &amp;lt; &apos;3.8&apos;&quot;,
]
... skip

/&amp;gt; # uv pip freeze &amp;gt; requirements.txt
/&amp;gt; # cat requirements.txt
click==8.1.8
flask==2.2.5
importlib-metadata==6.7.0
itsdangerous==2.1.2
jinja2==3.1.6
markupsafe==2.1.5
typing-extensions==4.7.1
werkzeug==2.2.3
zipp==3.15.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;의존성-패키지-제거&quot;&gt;의존성 패키지 제거&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/&amp;gt; # uv add flask_cors
Resolved 26 packages in 42ms
Prepared 1 package in 11ms
Installed 1 package in 1ms
 + flask-cors==5.0.0

/&amp;gt; # uv remove flask-cors
Resolved 24 packages in 41ms
Uninstalled 1 package in 0.40ms
 - flask-cors==5.0.0
/&amp;gt; # uv pip freeze &amp;gt; requirements.txt
/&amp;gt; # cat requirements.txt
click==8.1.8
flask==2.2.5
importlib-metadata==6.7.0
itsdangerous==2.1.2
jinja2==3.1.6
markupsafe==2.1.5
typing-extensions==4.7.1
werkzeug==2.2.3
zipp==3.15.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;패키지-버전-고정&quot;&gt;패키지 버전 고정&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/&amp;gt; # uv lock
Resolved 24 packages in 0.80ms
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;가상-환경-생성&quot;&gt;가상 환경 생성&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/&amp;gt; # uv venv
Using CPython 3.7.16 interpreter at: /usr/bin/python3.7
Creating virtual environment at: .venv
✔ A virtual environment already exists at `.venv`. Do you want to replace it? · yes
Activate with: source .venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;uv-프로젝트로-실행&quot;&gt;UV 프로젝트로 실행&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/&amp;gt; # uv run main.py
Installed 9 packages in 16ms
Flask 버전: 2.2.5
Python 버전: 3.7.16 (default, Jun 27 2025, 23:12:33)
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;테스트-결과-&quot;&gt;테스트 결과 :&lt;/h3&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ curl -s 172.31.46.51:5000 | egrep &quot;\&quot;version-l|\&quot;version-v&quot;
                &amp;lt;div class=&quot;version-label&quot;&amp;gt;Flask Version:&amp;lt;/div&amp;gt;
                &amp;lt;div class=&quot;version-value&quot;&amp;gt;2.2.5&amp;lt;/div&amp;gt;
                &amp;lt;div class=&quot;version-label&quot;&amp;gt;Python Version:&amp;lt;/div&amp;gt;
                &amp;lt;div class=&quot;version-value&quot;&amp;gt;3.7.16 (default, Jun 27 2025, 23:12:33)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;프로젝트-이외-경로에서-실행-방안&quot;&gt;프로젝트 이외 경로에서 실행 방안&lt;/h1&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/&amp;gt; # uv run --project /root/uv-test /root/uv-test/main.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;pip-과-비교&quot;&gt;pip 과 비교&lt;/h1&gt;
&lt;p&gt;기존 pip 을 통해 패키지를 설치하고 관리하는 방법에 비해 매우 빠른 성능으로 패키지를 설치 관리 할 수 있었습니다. &lt;br /&gt;
실제 대규모 프로젝트에서는 많은 의존성으로 인해 빌드 과정이 복잡해질 것이며, UV 를 사용하게되면 성능적 (속도)으로 효과적인 개선 효과를 만들 수 있을 것으로 기대합니다.&lt;/p&gt;

&lt;h1 id=&quot;참고-자료&quot;&gt;참고 자료&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/astral-sh/uv&quot;&gt;https://github.com/astral-sh/uv&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 30 Jul 2025 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/linux/2025/07/30/python-uv/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/linux/2025/07/30/python-uv/</guid>
        
        <category>linux</category>
        
        
        <category>linux</category>
        
      </item>
    
      <item>
        <title>RHEL BYOL AMI 생성 가이드</title>
        <description>&lt;h1 id=&quot;rhel-byol-ami-생성&quot;&gt;RHEL BYOL AMI 생성&lt;/h1&gt;

&lt;p&gt;AWS 와 같은 기타 CSP 를 사용하게 되면 PAYG 라이센스의 RHEL 을 사용합니다. &lt;br /&gt;
PAYG 라이센스가 아닌 BYOL (Bring Your Own License) RHEL 을 사용하면서, OpenSCAP 프로파일 적용, 파티션 구분 및 파일시스템 분리 등을 위한 커스텀한 RHEL BYOL AMI 을 생성하는 방안에 대해 설명을 드리겠습니다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;이번 포스팅은 AWS 를 대상으로 진행이 되었으나, GCP, Azure, Oracle Cloud, VMWare, qcow2, iso 로 사용 가능한 이미지가 생성에도 활용이 가능합니다.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;recommanded&quot;&gt;Recommanded&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Developers Subscription 등록 필요
    &lt;ul&gt;
      &lt;li&gt;https://developers.redhat.com/blog/2021/02/10/how-to-activate-your-no-cost-red-hat-enterprise-linux-subscription&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;아래 페이지에서도 등록이 가능합니다.
    &lt;ul&gt;
      &lt;li&gt;https://developers.redhat.com/products/rhel/download&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/1.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
  &lt;/li&gt;
  &lt;li&gt;정상적으로 등록이 된다면 아래와 같이 서브스크립션이 확인이 될 것입니다.
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/2.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;how-to-create-byol-ami&quot;&gt;How to create BYOL AMI&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.redhat.com/en/technologies/management/insights&quot;&gt;Red Hat Insights&lt;/a&gt; &amp;gt; Inventory &amp;gt; Images
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/3.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/4.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Select target environment &amp;gt; AWS
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/5.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
      &lt;li&gt;Select the RHEL Release version
        &lt;ul&gt;
          &lt;li&gt;
            &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/6.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Enter the account ID for shared AMI
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/7.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Select “Registration method”
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/8.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Select the “&lt;a href=&quot;https://www.open-scap.org/&quot;&gt;OpenSCAP&lt;/a&gt; profile”
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/9.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;File system configuration
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/10.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Select the “Disable repeatable build“ for use the newest state of repositories
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/11.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;(optional) if you need custom repositories, add custom repository information
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/12.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;(optional) if you need additional packages
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/13.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/14.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;(optional) if you need add user
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/15.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Select the timezone
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/16.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Select the Locale
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/17.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Select the hostname
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/18.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;(optional) Customize kernel name and kernel arguments.
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/19.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;(optional) Customize firewall settings for your image.
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/20.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;(optional) Enable, disable and mask systemd services.
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/21.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;(optional) Configure the image with a custom script that will execute on its first boot.
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/22.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Select the Blueprint name
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/23.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Review
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/24.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Create blueprint and build image
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/25.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;building the image
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/26.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Shared AMI
    &lt;ul&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/27.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-04-rhel-byol/28.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Create the instance from shared AMI&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@ip-172-31-8-200 ~]# cat /var/log/messages | grep rhel-image
Jun  4 01:16:27 ip-172-31-8-200 systemd: Hostname set to &amp;lt;rhel-image-builder&amp;gt;.

[root@ip-172-31-8-200 ~]# cat /etc/redhat-release
Red Hat Enterprise Linux release 10.0 (Coughlan)

[root@ip-172-31-8-200 ~]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme0n1p3   20G  1.9G   18G  10% /
devtmpfs        4.0M     0  4.0M   0% /dev
tmpfs           1.8G     0  1.8G   0% /dev/shm
efivarfs        128K  3.6K  120K   3% /sys/firmware/efi/efivars
tmpfs           707M  8.6M  698M   2% /run
tmpfs           1.0M     0  1.0M   0% /run/credentials/systemd-journald.service
/dev/nvme0n1p2  200M  8.4M  192M   5% /boot/efi
tmpfs           1.0M     0  1.0M   0% /run/credentials/serial-getty@ttyS0.service
tmpfs           1.0M     0  1.0M   0% /run/credentials/getty@tty1.service
tmpfs           354M  4.0K  354M   1% /run/user/1001

[root@ip-172-31-8-200 ~]# lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
nvme0n1     259:0    0   20G  0 disk
├─nvme0n1p1 259:1    0    1M  0 part
├─nvme0n1p2 259:2    0  200M  0 part /boot/efi
└─nvme0n1p3 259:3    0 19.8G  0 part /

[root@ip-172-31-8-200 ~]# rpm -qa | egrep &quot;cloud-init|tmux&quot;
cloud-init-24.4-3.el10.noarch
tmux-3.3a-13.20230918gitb202a2f.el10.x86_64
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@ip-172-31-8-200 ~]# subscription-manager status
+-------------------------------------------+
   System Status Details
+-------------------------------------------+
Overall Status: Not registered

[root@ip-172-31-8-200 ~]# yum repolist
Updating Subscription Management repositories.
Unable to read consumer identity

This system is not registered with an entitlement server. You can use &quot;rhc&quot; or &quot;subscription-manager&quot; to register.

No repositories available
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;register-subscription&quot;&gt;Register subscription&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@ip-172-31-8-200 ~]# subscription-manager register
Registering to: subscription.rhsm.redhat.com:443/subscription
Username: chhanz
Password: ******
The system has been registered with ID: 1234-1234-1234-1234-1234
The registered system name is: ip-172-31-8-200.ap-northeast-2.compute.internal
[root@ip-172-31-8-200 ~]# subscription-manager status
+-------------------------------------------+
   System Status Details
+-------------------------------------------+
Overall Status: Registered

[root@ip-172-31-8-200 ~]# yum repolist
Updating Subscription Management repositories.
repo id                                                      repo name
rhel-10-for-x86_64-appstream-rpms                            Red Hat Enterprise Linux 10 for x86_64 - AppStream (RPMs)
rhel-10-for-x86_64-baseos-rpms                               Red Hat Enterprise Linux 10 for x86_64 - BaseOS (RPMs)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;참고-자료&quot;&gt;참고 자료&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.redhat.com/ko/documentation/red_hat_enterprise_linux/8/html/creating_customized_images_by_using_insights_image_builder/index&quot;&gt;https://docs.redhat.com/ko/documentation/red_hat_enterprise_linux/8/html/creating_customized_images_by_using_insights_image_builder/index&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 04 Jun 2025 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/linux/2025/06/04/rhel-byol-image-on-aws/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/linux/2025/06/04/rhel-byol-image-on-aws/</guid>
        
        <category>linux</category>
        
        
        <category>linux</category>
        
      </item>
    
      <item>
        <title>RHEL Lightspeed 사용기</title>
        <description>&lt;h1 id=&quot;rhel-lightspeed-사용기&quot;&gt;RHEL Lightspeed 사용기&lt;/h1&gt;

&lt;p&gt;&lt;br /&gt;&lt;center&gt;&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/GVGxH3eFxz4?si=ueCCQ5YQ1_Hq1pUY&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/center&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.redhat.com/ko/technologies/linux-platforms/enterprise-linux-10/lightspeed&quot;&gt;RHEL Lightspeed&lt;/a&gt; 은 Red Hat 이 수십 년간 축적해온 Linux 전문 지식이 적용된 AI 기반 서비스를 활용하면 간소화된 명령으로 Red Hat Enterprise Linux를 구축, 배포, 관리할 수 있는 도구입니다.&lt;/p&gt;

&lt;p&gt;RHEL Lightspeed 은 Red Hat Enterprise Linux 9.6 및 10에서 사용할 수 있습니다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;이번 포스팅에서는 RHEL Lightspeed 이 어떻게 RHEL 에서 사용되고, 활용 할 수 있을지 몇가지 예제를 수행하여 활용을 해보았습니다.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h1 id=&quot;recommanded&quot;&gt;Recommanded&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;기본적으로 Developers Subscription 이상의 서브스크립션이 필요합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rhc&lt;/code&gt; 혹은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;subscription-manager&lt;/code&gt; 명령어를 통해 운영체제에 서브스크립션이 활성화 된 상태가 필요합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;command-line-assistant-설치&quot;&gt;command-line-assistant 설치&lt;/h1&gt;
&lt;p&gt;아래와 같은 방법으로 command-line-assistant (이하 CLA) 를 설치합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;dnf &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;command-line-assistant
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;how-to&quot;&gt;How to&lt;/h1&gt;
&lt;p&gt;기본적으로 아래와 같은 구문으로 명령어를 수행합니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;c &lt;span class=&quot;s2&quot;&gt;&quot;질문&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;example&quot;&gt;Example&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;What is redhat? &lt;br /&gt;
아래와 같이 RHEL 과 관련한 질문을 할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-03-rhel-lightspeed/l1.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;

&lt;ul&gt;
  &lt;li&gt;What is this error messages? &lt;br /&gt;
아래와 같이 파이프(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;|&lt;/code&gt;)를 통해 시스템에서 발생되는 메시지에 대한 자료를 요청 할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-03-rhel-lightspeed/l2.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;

&lt;ul&gt;
  &lt;li&gt;How do I install NFS Server? &lt;br /&gt;
아래와 같이 RHEL 에 서버 역할을 구성하는 방안에 대해 질의하고 안내 받을 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-03-rhel-lightspeed/l3.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;

&lt;ul&gt;
  &lt;li&gt;특정 포맷의 데이터를 원하는 형태로 가공을 요청 할 수 있습니다.
    &lt;ul&gt;
      &lt;li&gt;테스트 데이터 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;json&lt;/code&gt;)
        &lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;test.json&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;first_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Jeanette&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;last_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Penddreth&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;jpenddreth0@cs.dom&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;gender&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Female&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;ip_address&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2.5.1.2&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;first_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Giavani&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;last_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Frediani&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;gfrediani1@se.dom&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;gender&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Male&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;ip_address&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2.1.4.2&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;first_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Noell&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;last_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Bea&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;nbea2@ik.dom&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;gender&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Female&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;ip_address&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1.6.1.2&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;first_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Willard&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;last_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Valek&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;wvalek3@v.com&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;gender&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Male&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;ip_address&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;6.6.8.6&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
        &lt;p&gt;아래와 같이 CLA 를 이용하여 table 형태로 편리하게 포맷을 변경 할 수 있습니다.&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-03-rhel-lightspeed/l4.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;

&lt;ul&gt;
  &lt;li&gt;특정 명령어 생성 지원  &lt;br /&gt;
파이프(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;|&lt;/code&gt;)를 통해 특정 출력에 대해 특정 조건의 명령어 생성을 요청 할 수 있습니다. &lt;br /&gt;
또한 한글로 질문을 할 수 있습니다. &lt;strong&gt;&lt;em&gt;하지만 답변은 영문으로만 제공이 되는 것을 볼 수 있었습니다.&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-03-rhel-lightspeed/l5.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;

&lt;ul&gt;
  &lt;li&gt;테스트용 소스 코드 생성 지원
아래와 같이 테스트를 위한 소스 코드 생성을 지원하는 것을 확인 할 수 있었습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-03-rhel-lightspeed/l6.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;

&lt;ul&gt;
  &lt;li&gt;여러 조건의 명령어 생성 지원
아래와 같은 여러 조건의 명령을 one line 명령어로 생성 지원하는 것을 확인 할 수 있었습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-03-rhel-lightspeed/l7.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;

&lt;ul&gt;
  &lt;li&gt;특정 어플리케이션 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;httpd&lt;/code&gt;) 의 설정 파일 점검
아래와 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;httpd&lt;/code&gt; 의 설정 파일을 점검 요청 할 수 있었습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-8-200 conf]# systemctl start httpd
Job &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;httpd.service failed because the control process exited with error code.
See &lt;span class=&quot;s2&quot;&gt;&quot;systemctl status httpd.service&quot;&lt;/span&gt; and &lt;span class=&quot;s2&quot;&gt;&quot;journalctl -xeu httpd.service&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;details.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;위와 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;httpd&lt;/code&gt; 서비스가 정상적으로 동작을 안하는 문제로 인해 CLA 에게 설정 파일 검토를 요청 하였습니다.&lt;/p&gt;

&lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-06-03-rhel-lightspeed/l8.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;

&lt;p&gt;위와 같이 Listen 구문에 문제가 있는 것을 확인했고, 가능한 설정 방법에 대해 안내를 지원하였습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-8-200 conf]# &lt;span class=&quot;nb&quot;&gt;cat &lt;/span&gt;httpd.conf | &lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;Listen
&lt;span class=&quot;c&quot;&gt;# Listen: Allows you to bind Apache to specific IP addresses and/or&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Change this to Listen on a specific IP address, but note that if&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#Listen 12.34.56.78:80&lt;/span&gt;
Listen 9999999
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;실제로 위와 같이 잘못된 Listen 설정을 확인 할 수 있었습니다.&lt;/p&gt;

&lt;h2 id=&quot;총평&quot;&gt;총평&lt;/h2&gt;
&lt;p&gt;그 외에도 데이터를 기반한 스크립트 생성, 명령어 간편화 등등 여러 플랫폼을 사용하지 않고 RHEL 운영체제 명령어를 통해 지원을 받을 수 있는 점에서 도움이 되는 기능이 였습니다.&lt;/p&gt;

&lt;p&gt;또한 현재 Red Hat 에서 제공하는 interactive lab 을 통해 위 기능을 직접 사용해보고 활용 방법에 대해 실습 할 수 있는 랩도 제공 중이오니 직접 실습을 해보시면 도움이 될 것 같습니다.&lt;/p&gt;

&lt;p&gt;[+] &lt;a href=&quot;https://www.redhat.com/en/interactive-labs/Solve-problems-with-Command-Line-Assistant&quot;&gt;https://www.redhat.com/en/interactive-labs/Solve-problems-with-Command-Line-Assistant&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;참고-자료&quot;&gt;참고 자료&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.redhat.com/ko/technologies/linux-platforms/enterprise-linux-10/lightspeed&quot;&gt;https://www.redhat.com/ko/technologies/linux-platforms/enterprise-linux-10/lightspeed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 03 Jun 2025 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/linux/2025/06/03/rhel-lightspeed/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/linux/2025/06/03/rhel-lightspeed/</guid>
        
        <category>linux</category>
        
        
        <category>linux</category>
        
      </item>
    
      <item>
        <title>멀티 클라우드 환경에 호환 가능한 클라우드 이미지 개발 - 발표 자료</title>
        <description>&lt;h1 id=&quot;openinfra-korea-user-group---3월-meetup-발표-자료-공유&quot;&gt;[OpenInfra Korea User Group - 3월 Meetup] 발표 자료 공유&lt;/h1&gt;
&lt;p&gt;2025/3/6 에 열린 OpenInfra Korea User Group 3월 Meetup 에서 “멀티 클라우드 환경에 호환 가능한 클라우드 이미지 개발”이라는 주제로 발표를 진행했습니다!&lt;/p&gt;

&lt;p&gt;발표 영상은 아래 Youtube 를 참고하시면 됩니다.&lt;/p&gt;

&lt;center&gt;&lt;iframe width=&quot;900&quot; height=&quot;515&quot; src=&quot;https://www.youtube.com/embed/OxG_OfOH5h8?si=lxdKQtT-lmDak-NK&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/center&gt;

&lt;ul&gt;
  &lt;li&gt;OpenInfra Korea User Group : &lt;a href=&quot;https://www.linkedin.com/posts/chhanz_%EB%A9%80%ED%8B%B0-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%ED%99%98%EA%B2%BD%EC%97%90-%ED%98%B8%ED%99%98-%EA%B0%80%EB%8A%A5%ED%95%9C-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EA%B0%9C%EB%B0%9C-%ED%95%9C%EC%B2%A0%ED%9D%AC-activity-7308279114874961920-JhYo?utm_source=share&amp;amp;utm_medium=member_desktop&amp;amp;rcm=ACoAACmZJOYBCTurULjLso2XjoGG131DmDAwi2c&quot;&gt;Link&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 21 Mar 2025 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/linux/2025/03/21/bootc-meetup/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/linux/2025/03/21/bootc-meetup/</guid>
        
        <category>linux</category>
        
        
        <category>linux</category>
        
      </item>
    
      <item>
        <title>[Linux] Bootc 사용법</title>
        <description>&lt;h1 id=&quot;bootc-이미지-빌드-및-관리-가이드&quot;&gt;bootc 이미지 빌드 및 관리 가이드&lt;/h1&gt;

&lt;center&gt;&lt;img src=&quot;https://raw.githubusercontent.com/containers/common/main/logos/bootc-logo-full-vert.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;

&lt;p&gt;bootc 는 부팅 가능한 컨테이너의 핵심 요소이며, 부팅 가능한 컨테이너를 관리하기 위한 여러 systemd, timer 와 함께 제동 되는 CLI 도구 입니다. &lt;br /&gt;
또한 업데이트를 다운로드하고 대기 시키는 역할을 하고 시스템을 관리하고 시스템 상태 검사를 하는데 사용합니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.fedoraproject.org/en-US/bootc/getting-started/&quot;&gt;https://docs.fedoraproject.org/en-US/bootc/getting-started/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;bootc-를-이용한-부팅이-가능한-컨테이너를-사용하는-것에-대한-장점&quot;&gt;bootc 를 이용한 부팅이 가능한 컨테이너를 사용하는 것에 대한 장점&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;DevOps를 위한 통합된 접근 방식&lt;/p&gt;

    &lt;p&gt;부팅 가능한 컨테이너는 Linux의 역할을 한 단계 더 발전시켜 GitOps 및 CI/CD(Continuous Integration/Continuous Delivery)를 포함한 컨테이너 기반 툴링과 개념을 통해 전체 OS를 관리할 수 있도록 합니다. 
  이 간소화된 접근 방식은 패치를 다른 위치에 푸시하거나 운영 팀과 애플리케이션 개발 주기 간의 격차를 메우는 경우 대규모로 Linux를 관리하는 과제를 해결하는 데 도움이 됩니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;간소화된 보안&lt;/p&gt;

    &lt;p&gt;이미지 기반 시스템에는 수십 가지의 보안 이점이 있지만 OS가 컨테이너 이미지 형태로 제공된다는 사실을 강조하고 싶습니다. 
  즉, 패치, 검사, 검증 및 서명을 처리하기 위해 고급 컨테이너 보안 도구와 같은 컨테이너 보안의 지난 10년 간의 발전을 활용할 수 있습니다. 이제 커널, 드라이버, 부트로더 등에 컨테이너 보안 검사를 적용할 수 있습니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;속도 및 생태계 통합&lt;/p&gt;

    &lt;p&gt;보안 이점과 마찬가지로 부팅 가능한 컨테이너는 컨테이너를 중심으로 등장한 도구와 기술의 광대한 생태계에 통합됩니다.&lt;br /&gt;
  부팅 가능한 컨테이너를 사용하면 새로운 규모와 속도로 Linux 시스템을 빌드, 배포 및 관리할 수 있습니다. 부팅 가능한 컨테이너의 초기 채택자로부터 일관된 피드백은 이러한 모든 작업을 더 짧은 시간 내에 관리하기 위한 간소화된 툴체인을 관찰한다는 것입니다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이번 포스팅에서는 bootc 이미지 빌드부터 관리까지 전체적인 내용을 다뤄보겠습니다.&lt;/p&gt;

&lt;h2 id=&quot;bootc-이미지-빌드-및-관리&quot;&gt;bootc 이미지 빌드 및 관리&lt;/h2&gt;

&lt;h3 id=&quot;1-기본-이미지-빌드&quot;&gt;1. 기본 이미지 빌드&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2025-03-09-bootc/file1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Containerfile을 이용하여 bootc 이미지를 빌드합니다.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;podman build &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; bootc &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;STEP 1/7: FROM quay.io/centos-bootc/centos-bootc:stream9
STEP 2/7: RUN dnf -y install httpd cloud-init plymouth vim &amp;amp;&amp;amp; \
     systemctl enable httpd &amp;amp;&amp;amp; \    
     systemctl enable cloud-init.service &amp;amp;&amp;amp; \    
     mv /var/www /usr/share/www &amp;amp;&amp;amp; \    
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;     echo &apos;d /var/log/httpd 0700 - - -&apos; &amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;/usr/lib/tmpfiles.d/httpd-log.conf &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;     sed -ie &apos;s,/var/www,/usr/share/www,&apos; /etc/httpd/conf/httpd.conf
STEP 3/7: RUN mkdir -p /usr/lib/bootc/kargs.d
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;4f70d792d20d
&lt;span class=&quot;gp&quot;&gt;STEP 4/7: RUN cat &amp;lt;&amp;lt;EOF &amp;gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; /usr/lib/bootc/kargs.d/kcmdline.toml &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;kargs &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;console=ttyS0,114800n8&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;selinux=0&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;...&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;a7e112a51f79
&lt;span class=&quot;go&quot;&gt;STEP 5/7: RUN rm /usr/share/httpd/noindex -rf
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;83c9cccb104d
&lt;span class=&quot;go&quot;&gt;STEP 6/7: COPY index.html /usr/share/www/html
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;91dc066387f9
&lt;span class=&quot;go&quot;&gt;STEP 7/7: EXPOSE 80
COMMIT bootc
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;db1bdf3e68dd
&lt;span class=&quot;go&quot;&gt;Successfully tagged localhost/bootc:latest
db1bdf3e68dda4ab9365ad5571236d52c961447fc0cdb008f7090cc721d05158
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;2-이미지-태깅-및-푸시&quot;&gt;2. 이미지 태깅 및 푸시&lt;/h3&gt;

&lt;p&gt;여러 버전의 이미지를 태깅하고 레지스트리에 푸시합니다. &lt;br /&gt;
테스트의 편의를 위해 ECR 을 사용하였으나, 사설 레포지토리 및 기타 솔루션을 사용 할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;podman tag bootc:latest public.ecr.aws/w4&lt;span class=&quot;k&quot;&gt;****&lt;/span&gt;s3/bootc:latest
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;podman push public.ecr.aws/w4&lt;span class=&quot;k&quot;&gt;****&lt;/span&gt;s3/bootc:latest
&lt;span class=&quot;go&quot;&gt;Getting image source signatures
Copying blob 54cc565ad42f skipped: already exists
Copying blob 54cc565ad42f skipped: already exists
&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;...
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;podman tag bootc:latest public.ecr.aws/w4&lt;span class=&quot;k&quot;&gt;****&lt;/span&gt;s3/bootc:v1
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;podman push public.ecr.aws/w4&lt;span class=&quot;k&quot;&gt;****&lt;/span&gt;s3/bootc:v1
&lt;span class=&quot;go&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;podman images
&lt;span class=&quot;go&quot;&gt;REPOSITORY                                TAG         IMAGE ID      CREATED        SIZE
public.ecr.aws/w4****s3/bootc             v1          db1bdf3e68dd  3 minutes ago  1.86 GB
public.ecr.aws/w4****s3/bootc             latest      db1bdf3e68dd  3 minutes ago  1.86 GB
localhost/bootc                           latest      db1bdf3e68dd  3 minutes ago  1.86 GB
quay.io/centos-bootc/centos-bootc         stream9     f9e21da0d9d0  2 weeks ago    1.57 GB
quay.io/centos-bootc/bootc-image-builder  latest      bfc3eaae8414  5 weeks ago    774 MB
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;3-컨테이너로-실행-테스트&quot;&gt;3. 컨테이너로 실행 테스트&lt;/h3&gt;

&lt;p&gt;빌드된 이미지를 컨테이너로 실행하여 웹 서버 동작을 테스트합니다.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;podman run &lt;span class=&quot;nt&quot;&gt;--rm&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt; test-web &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; 80:80  public.ecr.aws/w4&lt;span class=&quot;k&quot;&gt;****&lt;/span&gt;s3/bootc:latest
&lt;span class=&quot;go&quot;&gt;b309f135c7d0d950dd86e2e263602770cada47c616911dc04b828afdc6f71886

&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;curl localhost:80
&lt;span class=&quot;go&quot;&gt;TEST INDEX v1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;ami-생성-프로세스&quot;&gt;AMI 생성 프로세스&lt;/h2&gt;
&lt;h3 id=&quot;1-ami-생성을-위한-설정&quot;&gt;1. AMI 생성을 위한 설정&lt;/h3&gt;

&lt;p&gt;config.toml 설정 파일:&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat &lt;/span&gt;config.toml
&lt;span class=&quot;go&quot;&gt;[[customizations.user]]
name = &quot;centos&quot;
password = &quot;password&quot;
key = &quot;ssh-rsa AAAAB3Nz...&quot;
groups = [&quot;wheel&quot;]

[[customizations.disk.partitions]]
mountpoint = &quot;/&quot;
minsize = &quot;7 GiB&quot;
label = &quot;root&quot;
fs_type = &quot;xfs&quot;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;2-ami-생성-스크립트&quot;&gt;2. AMI 생성 스크립트&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/post/2025-03-09-bootc/file2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bootc-image-builder&lt;/code&gt; 를 이용하여 빌드한 컨테이너 이미지를 AMI 로 생성합니다. &lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bootc-image-builder&lt;/code&gt; 는 퍼블릭 클라우드 뿐만 아니라 다양한 환경에 적합한 이미지를 생성하고 변환하는 역할을 합니다.&lt;/p&gt;

&lt;p&gt;create-ami.sh:&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;sudo podman run \
  --rm \
  -it \
  --privileged \
  --security-opt label=type:unconfined_t \
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;  -v $&lt;/span&gt;HOME/.aws:/root/.aws:ro &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  -v ./config.toml:/config.toml:ro \
  -v /var/lib/containers/storage:/var/lib/containers/storage \
  --env AWS_PROFILE=default \
  quay.io/centos-bootc/bootc-image-builder:latest \
  --type ami \
  --aws-ami-name http-bootc-ami \
  --aws-bucket s3test \
  --aws-region ap-northeast-2 \
  public.ecr.aws/w4****s3/bootc:latest
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;3-ami-생성-실행-결과&quot;&gt;3. AMI 생성 실행 결과&lt;/h3&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;./create-ami.sh
&lt;span class=&quot;go&quot;&gt;[/] Image building step
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;[4 / 4] Pipeline image [------------------------------------------------------------------------------------------------------------&amp;gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; 100.00%
&lt;span class=&quot;gp&quot;&gt;[10 / 10] Stage org.osbuild.selinux [-----------------------------------------------------------------------------------------------&amp;gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; 100.00%
&lt;span class=&quot;go&quot;&gt;Message: Build complete!
Uploading http-bootc-ami to s3test:dda70dae-aafb-4b31-9ddb-fcd2dfadec0a-http-bootc-ami
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;7.20 GiB / 7.20 GiB [------------------------------------------------------------------------------------------------&amp;gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; 100.00% 201.82 MiB p/s
&lt;span class=&quot;go&quot;&gt;File uploaded to https://s3test.s3.ap-northeast-2.amazonaws.com/dda70dae-aafb-4b31-9ddb-fcd2dfadec0a-http-bootc-ami
Registering AMI http-bootc-ami
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;7.20 GiB / 7.20 GiB [-------------------------------------------------------------------------------------------------------&amp;gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; 100.00% 0 B p/s
&lt;span class=&quot;gp&quot;&gt;7.20 GiB / 7.20 GiB [-------------------------------------------------------------------------------------------------------&amp;gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; 100.00% 0 B p/s
&lt;span class=&quot;go&quot;&gt;Deleted S3 object s3test:dda70dae-aafb-4b31-9ddb-fcd2dfadec0a-http-bootc-ami
AMI registered: ami-0526*************
Snapshot ID: snap-0ce7*************
7.20 GiB / 7.20 GiB [--------------------------------------------------------------------------------------------------] 100.00% 26.24 MiB p/s
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;4-생성된-ami-로-생성된-인스턴스의-파일시스템-확인&quot;&gt;4. 생성된 AMI 로 생성된 인스턴스의 파일시스템 확인&lt;/h3&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;[root@ip-*********** ~]#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-h&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        4.0M     0  4.0M   0% /dev
tmpfs           1.9G     0  1.9G   0% /dev/shm
tmpfs           759M  516K  758M   1% /run
efivarfs        128K  3.4K  120K   3% /sys/firmware/efi/efivars
/dev/nvme0n1p3  7.8G  1.9G  5.9G  24% /sysroot
composefs       7.2M  7.2M     0 100% /
&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;...
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;[root@ip-*********** ~]#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;lsblk
&lt;span class=&quot;go&quot;&gt;NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
loop0         7:0    0  7.2M  1 loop
zram0       252:0    0  3.7G  0 disk [SWAP]
nvme0n1     259:0    0    8G  0 disk
├─nvme0n1p1 259:1    0    1M  0 part
├─nvme0n1p2 259:2    0  200M  0 part /boot/efi
└─nvme0n1p3 259:3    0  7.8G  0 part /var
                                     /sysroot/ostree/deploy/default/var
                                     /etc
                                     /boot
                                     /sysroot
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;위와 같이 composefs 를 이용한 특수한 구성을 이용하는 운영체제로 시작됩니다.&lt;/p&gt;

&lt;h1 id=&quot;bootc-운영-관리&quot;&gt;bootc 운영 관리&lt;/h1&gt;
&lt;h2 id=&quot;1-bootc-기본-명령어&quot;&gt;1. bootc 기본 명령어&lt;/h2&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;bootc &lt;span class=&quot;nt&quot;&gt;--help&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Deploy and transactionally in-place with bootable container images.

Commands:
  upgrade      Download and queue an updated container image to apply
  switch       Target a new container image reference to boot
  rollback     Change the bootloader entry ordering
  edit         Apply full changes to the host specification
  status       Display status
  usr-overlay  Adds a transient writable overlayfs on `/usr`
  install      Install the running container to a target
  container    Operations which can be executed as part of a container build
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;2-시스템-상태-확인-및-업그레이드&quot;&gt;2. 시스템 상태 확인 및 업그레이드&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;bootc 를 통한 이미지 관리 체계
    &lt;center&gt;&lt;img src=&quot;/assets/images/post/2025-03-09-bootc/file3.png&quot; style=&quot;max-width: 95%; height: auto;&quot; /&gt;&lt;/center&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;상태-확인&quot;&gt;상태 확인:&lt;/h3&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;bootc status
&lt;span class=&quot;go&quot;&gt;No staged image present
Current booted image: public.ecr.aws/w4****s3/bootc:latest
    Image version: stream9.20250129.0 (2025-02-17 05:03:12.502233712 UTC)
    Image digest: sha256:326be670c2b10bdb187fbbcb9b28fbcde66c9cbe1d32915478089af9478d373e
No rollback image present
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;업그레이드-실행&quot;&gt;업그레이드 실행:&lt;/h3&gt;
&lt;p&gt;레포지토리에 있는 최신 버전의 이미지를 Pull 하고, 부팅을 위해 staged image 로 준비합니다.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;bootc upgrade
&lt;span class=&quot;gp&quot;&gt;layers already present: 0;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;layers needed: 72 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1.1 GB&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Fetched layers: 1.01 GiB in 87 seconds (11.86 MiB/s)
  Deploying: done (4 seconds)       Queued for next boot: public.ecr.aws/w4****s3/bootc:latest
  Version: stream9.20250129.0
  Digest: sha256:01fe8dea52017556f85932f5debb142cd48bc5d9162a23030239ebf64f7b2b1e
Total new layers: 72    Size: 1.1 GB
Removed layers:   72    Size: 1.9 GB
Added layers:     72    Size: 1.1 GB
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# bootc status
Current staged image: public.ecr.aws/w4****s3/bootc:latest      &amp;lt;&amp;lt;----!!!
    Image version: stream9.20250129.0 (2025-02-17 06:52:27.362887944 UTC)
    Image digest: sha256:01fe8dea52017556f85932f5debb142cd48bc5d9162a23030239ebf64f7b2b1e
Current booted image: public.ecr.aws/w4****s3/bootc:latest
    Image version: stream9.20250129.0 (2025-02-17 05:03:12.502233712 UTC)
    Image digest: sha256:326be670c2b10bdb187fbbcb9b28fbcde66c9cbe1d32915478089af9478d373e
No rollback image present
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;재부팅 후 :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# bootc status
No staged image present
Current booted image: public.ecr.aws/w4****s3/bootc:latest
    Image version: stream9.20250129.0 (2025-02-17 06:52:27.362887944 UTC)
    Image digest: sha256:01fe8dea52017556f85932f5debb142cd48bc5d9162a23030239ebf64f7b2b1e
Current rollback image: public.ecr.aws/w4****s3/bootc:latest
    Image version: stream9.20250129.0 (2025-02-17 05:03:12.502233712 UTC)
    Image digest: sha256:326be670c2b10bdb187fbbcb9b28fbcde66c9cbe1d32915478089af9478d373e

# curl localhost
TEST INDEX v2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;3-이미지-롤백-및-전환&quot;&gt;3. 이미지 롤백 및 전환&lt;/h2&gt;

&lt;h3 id=&quot;롤백-실행&quot;&gt;롤백 실행:&lt;/h3&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;bootc rollback
&lt;span class=&quot;go&quot;&gt;Next boot: rollback deployment

&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;reboot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;재부팅 후:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# bootc status
No staged image present
Current booted image: public.ecr.aws/w4****s3/bootc:latest
    Image version: stream9.20250129.0 (2025-02-17 05:03:12.502233712 UTC)
    Image digest: sha256:326be670c2b10bdb187fbbcb9b28fbcde66c9cbe1d32915478089af9478d373e
Current rollback image: public.ecr.aws/w4****s3/bootc:latest
    Image version: stream9.20250129.0 (2025-02-17 06:52:27.362887944 UTC)
    Image digest: sha256:01fe8dea52017556f85932f5debb142cd48bc5d9162a23030239ebf64f7b2b1e

# curl localhost
TEST INDEX v1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;특정-이미지로-전환&quot;&gt;특정 이미지로 전환:&lt;/h3&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;bootc switch public.ecr.aws/w4&lt;span class=&quot;k&quot;&gt;****&lt;/span&gt;s3/bootc:v3
&lt;span class=&quot;gp&quot;&gt;layers already present: 71;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;layers needed: 1 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;230 bytes&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Fetched layers: 230 B in 21 seconds (10 B/s)
  Deploying: done (4 seconds)           Queued for next boot: public.ecr.aws/w4****s3/bootc:v3
  Version: stream9.20250129.0
  Digest: sha256:eeb8035601e584bf5cb21f5906a9c5eda097c0891e52d427017b5253cb4d0191
  
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;bootc status
&lt;span class=&quot;go&quot;&gt;Current staged image: public.ecr.aws/w4****s3/bootc:v3
    Image version: stream9.20250129.0 (2025-02-17 07:00:14.550632920 UTC)
    Image digest: sha256:eeb8035601e584bf5cb21f5906a9c5eda097c0891e52d427017b5253cb4d0191
Current booted image: public.ecr.aws/w4****s3/bootc:latest
    Image version: stream9.20250129.0 (2025-02-17 05:03:12.502233712 UTC)
    Image digest: sha256:326be670c2b10bdb187fbbcb9b28fbcde66c9cbe1d32915478089af9478d373e
Current rollback image: public.ecr.aws/w4****s3/bootc:latest
    Image version: stream9.20250129.0 (2025-02-17 06:52:27.362887944 UTC)
    Image digest: sha256:01fe8dea52017556f85932f5debb142cd48bc5d9162a23030239ebf64f7b2b1e
    
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; 재부팅 진행
&lt;span class=&quot;go&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;bootc status
&lt;span class=&quot;go&quot;&gt;No staged image present
Current booted image: public.ecr.aws/w4****s3/bootc:v3
    Image version: stream9.20250129.0 (2025-02-17 07:00:14.550632920 UTC)
    Image digest: sha256:eeb8035601e584bf5cb21f5906a9c5eda097c0891e52d427017b5253cb4d0191
Current rollback image: public.ecr.aws/w4****s3/bootc:latest
    Image version: stream9.20250129.0 (2025-02-17 05:03:12.502233712 UTC)
    Image digest: sha256:326be670c2b10bdb187fbbcb9b28fbcde66c9cbe1d32915478089af9478d373e

&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;curl localhost
&lt;span class=&quot;go&quot;&gt;TEST INDEX v3

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;파일시스템-관리&quot;&gt;파일시스템 관리&lt;/h2&gt;
&lt;h3 id=&quot;1-영구-저장소-사용&quot;&gt;1. 영구 저장소 사용&lt;/h3&gt;

&lt;p&gt;/var 디렉토리는 재부팅 후에도 유지되는 영구 저장소입니다:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@ip-172-31-1-74 ~]# mkdir /var/data

[root@ip-172-31-1-74 ~]# dd if=/dev/zero of=/var/data/bigfile count=1 bs=1G
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 4.29051 s, 250 MB/s

[root@ip-172-31-1-74 ~]# ls -l /var/data/
total 1048576
-rw-r--r-- 1 root root 1073741824 Feb 17 07:11 bigfile

[root@ip-172-31-1-74 ~]# reboot

[root@ip-172-31-1-74 ~]# uptime
 07:13:15 up 0 min,  1 user,  load average: 0.07, 0.02, 0.00

재부팅 후에도 데이터 유지:

[root@ip-172-31-1-74 ~]# ls -l /var/data
total 1048576
-rw-r--r-- 1 root root 1073741824 Feb 17 07:11 bigfile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;2-usr-임시-작업&quot;&gt;2. /usr 임시 작업&lt;/h3&gt;

&lt;p&gt;bootc usr-overlay를 사용한 임시 쓰기 작업:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# echo &quot;Enabled USR&quot; &amp;gt; /usr/share/www/html/index.html
-bash: /usr/share/www/html/index.html: Read-only file system

# bootc usr-overlay
Development mode enabled.

# echo &quot;Enabled USR&quot; &amp;gt; /usr/share/www/html/index.html
# curl localhost
Enabled USR

재부팅 후 원래 상태로 복구:

# uptime
 07:16:11 up 1 min,  1 user,  load average: 0.03, 0.01, 0.00
# curl localhost
TEST INDEX v3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;자동-업데이트-관리&quot;&gt;자동 업데이트 관리&lt;/h2&gt;
&lt;h3 id=&quot;1-업데이트-타이머-설정&quot;&gt;1. 업데이트 타이머 설정&lt;/h3&gt;

&lt;p&gt;타이머 상태 확인:&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;systemctl status bootc-fetch-apply-updates.timer
&lt;span class=&quot;go&quot;&gt;● bootc-fetch-apply-updates.timer - Apply bootc updates
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;     Loaded: loaded (/usr/lib/systemd/system/bootc-fetch-apply-updates.timer;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;disabled&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; preset: disabled&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;     Active: active (waiting) since Wed 2025-02-26 12:04:05 UTC;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;1min 21s ago
&lt;span class=&quot;gp&quot;&gt;      Until: Wed 2025-02-26 12:04:05 UTC;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;1min 21s ago
&lt;span class=&quot;gp&quot;&gt;    Trigger: Wed 2025-02-26 14:21:43 UTC;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;2h 16min left
&lt;span class=&quot;go&quot;&gt;   Triggers: ● bootc-fetch-apply-updates.service
       Docs: man:bootc(8)

Feb 26 12:04:05 localhost systemd[1]: Started Apply bootc updates.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;2-업데이트-시간-설정&quot;&gt;2. 업데이트 시간 설정&lt;/h3&gt;

&lt;p&gt;주간 업데이트 설정:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# systemctl edit bootc-fetch-apply-updates.timer
[Timer]
OnCalendar=Sun *-*-* 00:00:00
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Timer 구문은 아래와 같은 방법으로 구문 확인 가능합니다.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# systemd-analyze calendar --iterations 5 &quot;Sun *-*-* 00:00:00&quot;
Normalized form: Sun *-*-* 00:00:00
    Next elapse: Sun 2025-03-02 00:00:00 UTC
       From now: 2 days left
       Iter. #2: Sun 2025-03-09 00:00:00 UTC
       From now: 1 week 2 days left
       Iter. #3: Sun 2025-03-16 00:00:00 UTC
       From now: 2 weeks 2 days left
       Iter. #4: Sun 2025-03-23 00:00:00 UTC
       From now: 3 weeks 2 days left
       Iter. #5: Sun 2025-03-30 00:00:00 UTC
       From now: 1 month 0 days left

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;3-자동-업데이트&quot;&gt;3. 자동 업데이트&lt;/h3&gt;

&lt;p&gt;bootc-fetch-apply-updates 의 기본 서비스 구성:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# cat /usr/lib/systemd/system/bootc-fetch-apply-updates.service
[Unit]
Description=Apply bootc updates
Documentation=man:bootc(8)
ConditionPathExists=/run/ostree-booted

[Service]
Type=oneshot
ExecStart=/usr/bin/bootc update --apply --quiet      &amp;lt;&amp;lt;---!! 자동 재부팅 설정 되어 있음.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# systemctl list-timers
NEXT                        LEFT        LAST                        PASSED       UNIT                            ACTIVATES
Thu 2025-02-27 14:30:38 UTC 8h left     Wed 2025-02-26 14:30:38 UTC 15h ago      systemd-tmpfiles-clean.timer    systemd-tmpfiles-clean.service
Fri 2025-02-28 00:00:00 UTC 17h left    Thu 2025-02-27 00:00:02 UTC 6h ago       logrotate.timer                 logrotate.service
Sun 2025-03-02 00:00:00 UTC 2 days left Thu 2025-02-27 06:09:29 UTC 1min 23s ago bootc-fetch-apply-updates.timer bootc-fetch-apply-updates.service

3 timers listed.
Pass --all to see loaded but inactive timers, too.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;참고: journalctl 을 이용한 업데이트 로그 확인&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  Feb 27 01:22:27 hostname bootc[1699]: Fetching ostree-unverified-registry:public.ecr.aws/w4****s3/bootc:latest
  Feb 27 01:22:28 hostname bootc[1699]: No changes in public.ecr.aws/w4****s3/bootc:latest
  Feb 27 01:22:28 hostname bootc[1699]: No update available.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;4-자동-업데이트-비활성화&quot;&gt;4. 자동 업데이트 비활성화&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# systemctl mask bootc-fetch-apply-updates.timer
Created symlink /etc/systemd/system/bootc-fetch-apply-updates.timer → /dev/null
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;참고-자료&quot;&gt;참고 자료&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.redhat.com/ko/documentation/red_hat_enterprise_linux/9/html/using_image_mode_for_rhel_to_build_deploy_and_manage_operating_systems/managing-kernel-arguments-in-bootc-systems&quot;&gt;Red Hat bootc 커널 파라미터 관리&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/using_image_mode_for_rhel_to_build_deploy_and_manage_operating_systems/managing-rhel-bootc-images&quot;&gt;Red Hat bootc 이미지 관리&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://osbuild.org/docs/bootc/&quot;&gt;osbuild 문서&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://documentation.suse.com/smart/systems-management/html/systemd-working-with-timers/index.html&quot;&gt;Working with systemd Timers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sun, 09 Mar 2025 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/linux/2025/03/09/bootc/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/linux/2025/03/09/bootc/</guid>
        
        <category>linux</category>
        
        
        <category>linux</category>
        
      </item>
    
      <item>
        <title>[Linux] mount-s3 설치 및 사용</title>
        <description>&lt;h1 id=&quot;mount-s3-설치-및-사용&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mount-s3&lt;/code&gt; 설치 및 사용&lt;/h1&gt;
&lt;h2 id=&quot;설치&quot;&gt;설치&lt;/h2&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-5-165 ~]# yum &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.rpm

...
Installed:
  mount-s3.x86_64 0:1.0.0-1

Dependency Installed:
  fuse.x86_64 0:2.9.2-11.amzn
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;aws-configure&quot;&gt;aws configure&lt;/h2&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-5-165 ~]# aws configure
AWS Access Key ID &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;None]: &lt;span class=&quot;k&quot;&gt;******************&lt;/span&gt;
AWS Secret Access Key &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;None]: &lt;span class=&quot;k&quot;&gt;******************&lt;/span&gt;
Default region name &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;None]: ap-northeast-2
Default output format &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;None]: json

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-5-165 ~]# aws s3 &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;tail&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-n1&lt;/span&gt;
2023-01-17 01:12:23 s3fsmounttest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;mount&quot;&gt;mount&lt;/h2&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-5-165 ~]# mount-s3 s3fsmounttest /root/test
bucket s3fsmounttest is mounted at /root/test

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-5-165 ~]# &lt;span class=&quot;nb&quot;&gt;df
&lt;/span&gt;Filesystem     1K-blocks    Used Available Use% Mounted on
devtmpfs          479016       0    479016   0% /dev
tmpfs             487796       0    487796   0% /dev/shm
tmpfs             487796     412    487384   1% /run
tmpfs             487796       0    487796   0% /sys/fs/cgroup
/dev/xvda1       8376300 1806468   6569832  22% /
tmpfs              97560       0     97560   0% /run/user/1000

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-5-165 ~]# mount | &lt;span class=&quot;nb&quot;&gt;grep test
&lt;/span&gt;mountpoint-s3 on /root/test &lt;span class=&quot;nb&quot;&gt;type &lt;/span&gt;fuse &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;rw,nosuid,nodev,noatime,user_id&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0,group_id&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0,default_permissions&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;테스트&quot;&gt;테스트&lt;/h2&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-5-165 ~]# &lt;span class=&quot;nb&quot;&gt;cp &lt;/span&gt;mount-s3.rpm /root/test/
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-5-165 ~]# &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-la&lt;/span&gt; /root/test
total 10189
drwxr-xr-x 2 root root        0 Aug 10 04:31 &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
dr-xr-x--- 5 root root      147 Aug 10 04:31 ..
&lt;span class=&quot;nt&quot;&gt;-rw-r--r--&lt;/span&gt; 1 root root 10432224 Aug 10 04:31 mount-s3.rpm
&lt;span class=&quot;nt&quot;&gt;-rw-r--r--&lt;/span&gt; 1 root root       68 May 11 04:01 prj.txt

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@ip-172-31-5-165 ~]# aws s3 &lt;span class=&quot;nb&quot;&gt;ls &lt;/span&gt;s3testfsmount
2023-08-10 04:31:57   10432224 mount-s3.rpm
2023-05-11 04:01:01         68 prj.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;참고-문서&quot;&gt;참고 문서&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/awslabs/mountpoint-s3&quot;&gt;https://github.com/awslabs/mountpoint-s3&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/orgs/awslabs/projects/84&quot;&gt;https://github.com/orgs/awslabs/projects/84&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 27 Dec 2024 00:00:00 +0900</pubDate>
        <link>https://tech.chhanz.xyz/linux/2024/12/27/mount-s3/</link>
        <guid isPermaLink="true">https://tech.chhanz.xyz/linux/2024/12/27/mount-s3/</guid>
        
        <category>linux</category>
        
        <category>aws</category>
        
        
        <category>linux</category>
        
      </item>
    
  </channel>
</rss>
