<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>poala_0217.log</title>
        <link>https://velog.io/</link>
        <description>숲(구조)을 보는 개발자</description>
        <lastBuildDate>Thu, 19 Feb 2026 07:23:44 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>poala_0217.log</title>
            <url>https://velog.velcdn.com/images/poala_0217/profile/daeda105-a80b-42fe-abff-45b1bc876f9b/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. poala_0217.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/poala_0217" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[HackerRank 알고리즘 문제 풀이(파이썬)]]></title>
            <link>https://velog.io/@poala_0217/HackerRank-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%AC%B8%EC%A0%9C-%ED%92%80%EC%9D%B4%ED%8C%8C%EC%9D%B4%EC%8D%AC</link>
            <guid>https://velog.io/@poala_0217/HackerRank-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%AC%B8%EC%A0%9C-%ED%92%80%EC%9D%B4%ED%8C%8C%EC%9D%B4%EC%8D%AC</guid>
            <pubDate>Thu, 19 Feb 2026 07:23:44 GMT</pubDate>
            <description><![CDATA[<p>역시 코테하면 파이썬만한 것이 없는 것 같아서 알고리즘 공부를 하면서 파이썬 공부도 하는 중이다‼️</p>
<p>내가 제시한 풀이 방식</p>
<pre><code class="language-python">def timeConversion(s):
    timeZone=s[-2];
    hour_str = s[:2];
    hour_int = int(hour_str);
    others = s[2:-2]

    if timeZone==&#39;P&#39; and hour_int&lt;12:
        hour_int+=12;
    elif timeZone==&#39;A&#39; and hour_int==12:
        hour_int=0;

    return f&quot;{hour_int:02d}{others}&quot;</code></pre>
<p>제미나이가 말한 정석적 풀이</p>
<pre><code class="language-python">def timeConversion(s):
    meridiem = s[-2:]  # AM 또는 PM
    hour = int(s[:2])  # 시간 숫자화
    others = s[2:-2]   # :MM:SS 부분

    if meridiem == &quot;AM&quot;:
        if hour == 12:
            hour = 0
    else: # PM인 경우
        if hour != 12:
            hour += 12

    return f&quot;{hour:02d}{others}&quot;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[맥북 세팅 - Homebrew 다운로드]]></title>
            <link>https://velog.io/@poala_0217/%EB%A7%A5%EB%B6%81-%EC%84%B8%ED%8C%85-Homebrew-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C</link>
            <guid>https://velog.io/@poala_0217/%EB%A7%A5%EB%B6%81-%EC%84%B8%ED%8C%85-Homebrew-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C</guid>
            <pubDate>Sun, 18 Jan 2026 08:14:57 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-bash"> /bin/bash -c &quot;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&quot;
==&gt; Checking for `sudo` access (which may request your password)...
</code></pre>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/6ff06b07-cd50-4859-9ea8-4476a5715930/image.png" alt=""></p>
<pre><code class="language-bash">- Run these commands in your terminal to add Homebrew to your PATH:
    echo &gt;&gt; /Users/yeyeong_kwak/.zprofile
    echo &#39;eval &quot;$(/opt/homebrew/bin/brew shellenv zsh)&quot;&#39; &gt;&gt; /Users/yeyeong_kwak/.zprofile
    eval &quot;$(/opt/homebrew/bin/brew shellenv zsh)&quot;
- Run brew help to get started</code></pre>
<pre><code class="language-bash">// 설정 파일에 빈 줄을 하나 추가
~ % echo &gt;&gt; /Users/yeyeong_kwak/.zprofile

// 맥이 켜질 때마다 Homebrew를 인식하게
~ % echo &#39;eval &quot;$(/opt/homebrew/bin/brew shellenv)&quot;&#39; &gt;&gt; /Users/yeyeong_kwak/.zprofile

// 방금 설정한 내용을 지금 바로 현재 터미널에 적용
~ % eval &quot;$(/opt/homebrew/bin/brew shellenv)&quot;
~ % brew --version
Homebrew 5.0.10</code></pre>
<pre><code class="language-bash">curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

touch ~/.zshrc

echo &#39;export NVM_DIR=&quot;$HOME/.nvm&quot;&#39; &gt;&gt; ~/.zshrc
echo &#39;[ -s &quot;$NVM_DIR/nvm.sh&quot; ] &amp;&amp; \. &quot;$NVM_DIR/nvm.sh&quot;&#39; &gt;&gt; ~/.zshrc
echo &#39;[ -s &quot;$NVM_DIR/etc/bash_completion.d/nvm&quot; ] &amp;&amp; \. &quot;$NVM_DIR/etc/bash_completion.d/nvm&quot;&#39; &gt;&gt; ~/.zshrc

source ~/.zshrc


nvm install --lts

corepack enable

brew install pyenv

echo &#39;export PYENV_ROOT=&quot;$HOME/.pyenv&quot;&#39; &gt;&gt; ~/.zshrc

source ~/.zshrc

pyenv install 3.13

pyenv global 3.13


</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Nest.js로 개발한 주문 프로그램]]></title>
            <link>https://velog.io/@poala_0217/Nest.js%EB%A1%9C-%EA%B0%9C%EB%B0%9C%ED%95%9C-%EC%A3%BC%EB%AC%B8-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8</link>
            <guid>https://velog.io/@poala_0217/Nest.js%EB%A1%9C-%EA%B0%9C%EB%B0%9C%ED%95%9C-%EC%A3%BC%EB%AC%B8-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8</guid>
            <pubDate>Fri, 19 Dec 2025 04:58:19 GMT</pubDate>
            <description><![CDATA[<p>Nest.js로 BFF(Backend For Frontend)를 개발해왔는데 Nest.js로 주문 관리 프로그램을 개발해보기로 했다.</p>
<p>아직 프론트엔드를 별도로 만들지 않고 In-memory-repository를 생성해서 CSV 파일 데이터를 읽어온 후 터미널에서 입력받는 값에 따라 주문 관리 프로그램이 동작하도록 개발해보려고 한다.</p>
<ol>
<li>Nest.js 프로젝트 생성</li>
</ol>
<p>폴더를 생성하고</p>
<pre><code class="language-typescript">nest new .</code></pre>
<p>입력하면</p>
<ol>
<li>npm</li>
<li>yarn</li>
<li>pnpm(?기억이 잘 안 난다)
중에 선택하라고 뜨는데 yarn을 선택했다.</li>
</ol>
<pre><code>✔ Which package manager would you ❤️ to use? yarn</code></pre><p>별도로 DB를 생성하지 않고 In-memory-repository를 생성해보도록 하겠다.</p>
<hr>
<p>NestJS에서 node dist/main.js 실행 시
NestJS 내부에서 메모리 상에 하나의 ApplicationContext(=DI 컨테이너)가 생김</p>
<pre><code class="language-typescript">async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
</code></pre>
<p>NestFactory.create(AppModule) 이 호출되는 순간</p>
<ul>
<li><p>Nest가 AppModule을 루트로 해서</p>
</li>
<li><p>그 안에 선언된 모든 @Module, providers, controllers 등을 스캔하고</p>
</li>
<li><p>DI 컨테이너(앱 컨텍스트)를 구성</p>
</li>
</ul>
<br/>

<details><summary>DI(Dependency Injection)❓</summary>
DI는 클래스가 필요한 의존성을 스스로 생성하지 않고 외부에서 주입받는 설계 방식


<p>목적은 다음과 같다:</p>
<ol>
<li><p>객체 간 결합도 감소</p>
</li>
<li><p>테스트 용이성 향상</p>
</li>
<li><p>구현 교체 용이성</p>
</li>
<li><p>구조적이고 예측 가능한 초기화 과정 확보</p>
</li>
</ol>
<ul>
<li><p>NodeJS에서 DI 방식
별도의 DI 컨테이너가 없기 때문에 개발자가 직접 객체를 생성하고 주입</p>
<pre><code class="language-javascript">const repo = new ProductRepository();
const service = new ProductService(repo);
const controller = new ProductController(service);</code></pre>
</li>
<li><p>NestJS에서의 DI 방식</p>
<ul>
<li>DI 컨테이너가 내장되어 있으며, 모듈 시스템과 데코레이터를 활용해 자동으로 의존성을 관리</li>
<li>싱글톤/요청 스코프 관리 가능</li>
<li>구현 교체(예: InMemoryRepo ↔ DBRepo)가 매우 쉬움</li>
<li>테스트 모듈(Test.createTestingModule) 제공 → Unit Test 환경에서 큰 장점</li>
</ul>
<pre><code class="language-typescript">@Injectable()
  export class ProductService {
    constructor(private readonly repo: ProductRepository) {}
}
@Module({
    providers: [ProductRepository, ProductService],
})
export class ProductModule {}</code></pre>
<table>
<thead>
<tr>
<th>구분</th>
<th>Node.js / Express</th>
<th>NestJS</th>
</tr>
</thead>
<tbody><tr>
<td>DI 컨테이너</td>
<td>없음</td>
<td>내장</td>
</tr>
<tr>
<td>의존성 생성</td>
<td>개발자 직접</td>
<td>Nest가 자동 처리</td>
</tr>
<tr>
<td>모듈 구조</td>
<td>자유(혼란 가능)</td>
<td>모듈 기반 계층 구조</td>
</tr>
<tr>
<td>테스트 용이성</td>
<td>낮음 (Mock 주입 번거로움)</td>
<td>높음 (Test Module 제공)</td>
</tr>
<tr>
<td>구현 교체</td>
<td>어렵거나 번거로움</td>
<td>provider 바꾸면 끝</td>
</tr>
<tr>
<td>코드 일관성</td>
<td>팀 역량에 따라 편차 큼</td>
<td>프레임워크가 일관성 강제</td>
</tr>
</tbody></table>
</li>
</ul>
</details>


<pre><code class="language-typescript">// app.module.ts
@Module({
    imports: [ProductModule, OrderModule],
    providers: [OrderCliService],
})
export class AppModule implements OnModuleInit {
    constructor(private readonly productService: ProductService) {}

    async onModuleInit() {
        await this.productService.loadCSV();
    }
}</code></pre>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/fb0ec2fa-4300-47ba-b158-d28664c198c6/image.png" alt=""></p>
<p>main.ts에 정의된 bootstrap() 실행후에 바로 실행되는 onModuleInit() 함수가 모듈이 초기화될 때 자동으로 실행</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/4df80c84-80ac-41f7-8b91-2387129fe9c1/image.png" alt=""></p>
<p>❓ 언제 사용할까?</p>
<ul>
<li>DB 연결 초기화</li>
<li>WebSocket 연결</li>
<li>이벤트 리스너 설정</li>
<li>기본 데이터 로딩</li>
<li>기타 초기화 작업 수행</li>
</ul>
<p>src/app.module.ts에서 AppModule이 ProductModule을 임포트하고, OnModuleInit 훅에서 ProductService.loadCSV()를 한 번 호출</p>
<p>이 호출로 애플리케이션 부팅 시점에만 CSV를 읽어 메모리에 올리기</p>
<pre><code class="language-typescript">// src/products/product.service.ts

    async loadCSV() {
        const filePath = path.join(
            process.cwd(), // node 명령어를 실행하는 루트(폴더)
            &#39;src&#39;,
            &#39;product-data&#39;,
            &#39;products.csv&#39;,
        );

        const products = await this.readCsv(filePath);
        this.productRepo.loadData(products);
        this.logger.log(`Loaded ${products.length} products into memory`);
    }
</code></pre>
<pre><code class="language-typescript">    async readCsv(filePath: string): Promise&lt;Array&lt;ProductTypes&gt;&gt; {
        const rows: Array&lt;ProductTypes&gt; = [];
        return new Promise((resolve, reject) =&gt; {
            fs.createReadStream(filePath, { encoding: &#39;utf-8&#39; })
                .pipe(
                    parse({
                      //헤더(첫 행)를 읽고 컬럼명이 결정된 이후부터 각 row가 객체로
                        columns: (header) =&gt;
                            header.map((h) =&gt; h.replace(/\uFEFF/g, &#39;&#39;).trim()), //눈에 보이지 않는 특정 바이트를 넣은 UTF-8 BOM 형식이라서 상품번호 컬럼이 인식되지 않아서 
                        trim: true,
                        skip_empty_lines: true,
                    }),
                )
                .on(&#39;data&#39;, (data: ProductCsvRow) =&gt; {
                    const productId = data[&#39;상품번호&#39;];
                    const productName = data[&#39;상품명&#39;];
                    let salePrice = data[&#39;판매가격&#39;];
                    salePrice = salePrice.replace(/[^\d.-]/g, &#39;&#39;);
                    const stockQuantity = data[&#39;재고수량&#39;];

                    rows.push({
                        productId,
                        productName,
                        salePrice: Number(salePrice) ?? 0,
                        stockQuantity: Number(stockQuantity) ?? 0,
                    });
                })
                .on(&#39;end&#39;, () =&gt; {
                    resolve(rows); // 스트림 파싱이 끝났으므로 Promise를 성공(fulfilled) 상태로 완료하고 rows를 반환
                })
                .on(&#39;error&#39;, (err) =&gt; reject(err));
        });
    }
</code></pre>
<p>parse() 함수로 CSV를 행(record) 단위로 파싱
=&gt; columns: true 또는 columns: (header) =&gt; ... 를 쓰면, 첫 행을 헤더로 써서 각 행이 객체로 출력</p>
<pre><code class="language-typescript">//src/products/in-memory-product.repository.ts

private readonly products = new Map&lt;string, ProductTypes&gt;();


loadData(products: ProductTypes[]) {
        this.products.clear();

        products.forEach((product: ProductTypes) =&gt; {
            this.products.set(product.productId, { ...product });
        });

        this.logger.log(
            `Loaded ${this.products.size} into in-memory repository`,
        );
    }</code></pre>
<p>products map에 담아주기</p>
<p>또한 터미널 창이 곧 UI 역할을 하기 때문에 서버를 실행하면 cli도 실행할 수 있게</p>
<pre><code class="language-typescript">//main.ts

async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    await app.listen(process.env.PORT ?? 3030);
    console.log(
        `HTTP SERVER LISTENING ON http://localhost:${process.env.PORT}`,
    );

    const cli = app.get(OrderCliService);
    await cli.run();
}
bootstrap();
</code></pre>
<pre><code class="language-typescript">
//src/cli/order-cli.service.ts

async run() {
        let hasOrdered = false; // 주문 없이 터미널 창을 빠져나갈 때랑 아닐 때 메시지를 구별하기 위한 flag
        while (true) {
            const cmd = (
                await this.ask(&#39;입력(o[order]: 주문, q[quit]: 종료) : &#39;)
            )
                .trim()
                .toLowerCase();

            if (cmd === &#39;q&#39; || cmd === &#39;quit&#39;) {
                if (hasOrdered) {
                    console.log(`고객님의 주문 감사합니다.`);
                } else {
                    console.log(`주문을 종료합니다.`);
                }
                this.rl.close();
                process.exit(0);
            }

            if (cmd === &#39;o&#39; || cmd === &#39;order&#39;) {
                const ordered = await this.handleOrderFlow();
                if (ordered) {
                    hasOrdered = true;
                }
            }
        }
    }


    private ask(question: string): Promise&lt;string&gt; {
        return new Promise((resolve) =&gt; {
            this.rl.question(question, (answer) =&gt; {
                resolve(answer);
            });
        });
    }</code></pre>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/f8cb2275-b6fd-4596-938a-f39cf14725bc/image.png" alt=""></p>
<p>터미널 창으로 o나 order라는 단어가 입력되면 </p>
<p>handleOrderFlow() 호출</p>
<pre><code class="language-typescript">// src/cli/order-cli.service.ts

    async handleOrderFlow(): Promise&lt;boolean&gt; {
        const items: { productId: string; quantity: number }[] = [];
        const products = await this.productRepository.findAll();
        const requested = new Map&lt;string, number&gt;();

        // 최초에 전체 상품 상품번호, 상품명, 가격, 재고 출력해주기
        printProducts(products);

        try {
            while (true) {
                // 1) 입력받은 상품 ID
                const productId = (await this.ask(&#39;상품번호 : &#39;)).trim();

                // 2) 입력받은 수량
                const qtyStr = (await this.ask(&#39;수량 : &#39;)).trim();
                const quantity = Number(qtyStr);

                const alreadyRequested = requested.get(productId) ?? 0;
                const requestedTotal = alreadyRequested + quantity;

                try {
                    const validatedProduct =
                        await this.orderInputValidator.validateLine(
                            productId,
                            quantity,
                        );

                    if (&#39;end&#39; in validatedProduct &amp;&amp; validatedProduct.end) {
                        break;
                    }

                    if (!validatedProduct.ok &amp;&amp; &#39;message&#39; in validatedProduct) {
                        this.logger.log(validatedProduct.message);
                        continue;
                    }

                    if (validatedProduct.ok) {
                        items.push({
                            productId: validatedProduct.value.productId,
                            quantity: validatedProduct.value.quantity,
                        });
                        requested.set(productId, requestedTotal);
                    }
                    return true;
                } catch (err) {
                    const msg =
                        err instanceof Error
                            ? err.message
                            : &#39;입력 처리 중 오류가 발생했습니다.&#39;;
                    this.logger.log(`${msg}\n`);
                }
            }

            if (!items.length) {
                console.log(&#39;주문 상품이 없습니다. \n&#39;);
                return false;
            }

            const summary = await this.orderService.createOrder(items);

            printSummary(summary);

            return true;
        } catch (e) {
            if (e instanceof SoldOutException) {
                this.logger.error(e.message, e.stack, e.name);
                return false;
            }

            const message =
                e instanceof Error ? e.message : &#39;주문 처리 중 오류&#39;;
            this.logger.error(`주문 처리 중 오류가 발생했습니다. ${message}`);
            return false;
        }
    }

 // src/order/order.service.ts
@Injectable()
export class OrderInputValidator {
    constructor(
        @Inject(&#39;ProductRepository&#39;)
        private readonly productRepository: ProductRepository,
    ) {}

    async validateLine(
        productId: string,
        qtyStr: string,
        alreadyRequested: number,
    ): Promise&lt;ValidateResult&gt; {
        if (!productId &amp;&amp; !qtyStr) {
            return { ok: false, end: true };
        }

        if (!productId || !qtyStr) {
            return {
                ok: false,
                message:
                    &#39;상품번호와 수량을 모두 입력하거나, 둘 다 space+enter 입력으로 주문을 종료해 주세요.&#39;,
            };
        }
        const quantity = Number(qtyStr);

        if (!Number.isInteger(quantity) || quantity &lt;= 0) {
            return { ok: false, message: &#39;수량은 1개 이상 입력해주세요.&#39; };
        }

        const product = await this.productRepository.findById(productId);
        if (!product) {
            return { ok: false, message: &#39;존재하지 않는 상품번호입니다.&#39; };
        }

        const requestedTotal = alreadyRequested + quantity;
        if (requestedTotal &gt; product.stockQuantity) {
            const available = Math.max(
                product.stockQuantity - alreadyRequested,
                0,
            );

            return {
                ok: false,
                message: `${productId}-${product.productName}의 재고가 부족합니다. 현재 재고는 ${product.stockQuantity}개이며, 이미 ${alreadyRequested}개를 요청하셨습니다. 추가로 주문 가능한 수량은 ${available}개입니다.`,
            };
        }

        return { ok: true, value: { productId, quantity, requestedTotal } };
    }
}
</code></pre>
<ol>
<li><p>in-memory-repo에 저장된 상품정보를 모두 불러와 출력해준다
 <img src="https://velog.velcdn.com/images/poala_0217/post/ac148410-5ccd-4449-9a02-194ea0708194/image.png" alt=""></p>
</li>
<li><p>입력받은 상품 Id와 수량으로 유효성 체크를 한다
validateLine(productId, quantity)</p>
<ul>
<li>동작방식<ol>
<li>상품 ID와 수량이 모두 입력되지 않으면
<img src="https://velog.velcdn.com/images/poala_0217/post/3bfb578d-659f-4fab-b19a-f0ff0d7f0fad/image.png" alt="">2. 상품 ID를 입력했지만 수량이 1 미만일 때
<img src="https://velog.velcdn.com/images/poala_0217/post/1f9a14c2-69a0-41e7-9cc7-88d76a1dd8ef/image.png" alt=""> 3. 존재하지 않는 상품번호를 입력했을 때
<img src="https://velog.velcdn.com/images/poala_0217/post/24299898-114f-4df1-9a78-834ceb94cd39/image.png" alt=""> 4. 상품 ID와 수량 입력 후 해당 상품의 재고수량보다 희망하는 수량이 클 경우
<img src="https://velog.velcdn.com/images/poala_0217/post/8940830e-3515-4001-be87-a00bfa1f6f5e/image.png" alt=""> 5. 유효성 통과 시 items 배열에 추가</li>
</ol>
</li>
</ul>
</li>
</ol>
<pre><code class="language-typescript">// src/order/order.service.ts
@Injectable()
export class OrderService {
    constructor(
        @Inject(&#39;ProductRepository&#39;)
        private readonly productRepository: ProductRepository,
    ) {}
    async createOrder(items: { productId: string; quantity: number }[]) {
        const summary: OrderSummary = {
            lines: [],
            orderAmount: 0,
            shippingFee: 0,
            paymentAmount: 0,
        };
        for (const item of items) {
            const product = await this.productRepository.findById(
                item.productId,
            );
            if (!product) {
                throw new ProductNotFoundException();
            }

            if (item.quantity &gt; product.stockQuantity) {
                throw new SoldOutException(
                    item.productId,
                    item.quantity,
                    product.stockQuantity,
                );
            }
            summary.orderAmount += item.quantity * product.salePrice;
            summary.lines.push({
                productId: item.productId,
                productName: product.productName,
                quantity: item.quantity,
            });

            await this.productRepository.decreaseStock(
                item.productId,
                item.quantity,
            );
        }

        // 주문 금액이 5만원 이하면 배송비 2,500원 더해주기
        if (summary.orderAmount &lt; 50000) {
            summary.shippingFee += 2500;
        }

        summary.paymentAmount += summary.orderAmount + summary.shippingFee;

        return summary;
    }
}</code></pre>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/9ecf36a5-6712-4cbe-9c41-c5993997cf1c/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[고가용성 및 확장성 Quiz!]]></title>
            <link>https://velog.io/@poala_0217/%EA%B3%A0%EA%B0%80%EC%9A%A9%EC%84%B1-%EB%B0%8F-%ED%99%95%EC%9E%A5%EC%84%B1-Quiz</link>
            <guid>https://velog.io/@poala_0217/%EA%B3%A0%EA%B0%80%EC%9A%A9%EC%84%B1-%EB%B0%8F-%ED%99%95%EC%9E%A5%EC%84%B1-Quiz</guid>
            <pubDate>Sun, 23 Nov 2025 14:20:44 GMT</pubDate>
            <description><![CDATA[<p>Q1. EC2 인스턴스를 r4.large에서 r4.4xlarge로 확장하는 것을 .....................................(이)라고 합니다.</p>
<p><span>1. 수평 확장성</span>
<span style='color:green'>2. 수직 확장성</span></p>
<p>➡️ 수직 확장성(Vertical Scaling, Scale Up/Down)은 기존 인스턴스 자체의 성능을 높이거나 낮추는 것</p>
<hr>
<p>Q2. EC2 인스턴스 수를 확장 및 축소하는 Auto Scaling Group에서 애플리케이션을 실행하는 것을 .....................................(이)라고 합니다.</p>
<p><span>1. 수직 확장성(Vertical Scalability)</span>
<span style='color:green'>2. 수평 확장성(Horizontal Scalability)</span></p>
<p>➡️ 수평 확장성(Horizontal Scaling) → 인스턴스 개수를 조절</p>
<hr>
<p>Q3. ELB는 ..................................을(를) 제공합니다.</p>
<p><span>1. 애플리케이션에서 사용할 수 있는 static IPv4</span>
<span style='color:green'>2. 애플리케이션에서 사용할 수 있는 static DNS 이름</span>
<span>3. 애플리케이션에서 사용할 수 있는 static IPv6</span></p>
<p><strong>풀이💡</strong></p>
<ol>
<li><p>Static IPv4?</p>
<p>ELB는 내부적으로 여러 가용 영역(AZ)의 여러 IP를 가지고 있어서 고정된 IP를 보장하지 않음</p>
<p>요청이 들어올 때마다 다른 IP로 라우팅될 수 있음 → ❌</p>
</li>
<li><p>Static DNS 이름?</p>
<p>ELB는 DNS 이름을 제공하고, 이 DNS 이름을 통해 항상 ELB에 접근할 수 있음</p>
<p>ELB 뒤의 실제 IP는 변할 수 있지만, DNS 이름으로는 항상 접근 가능 → ✅</p>
</li>
<li><p>Static IPv6?</p>
<p>IPv6도 ELB의 경우 마찬가지로 IP가 고정되지 않음 → ❌</p>
</li>
</ol>
<hr>
<p>Q4. 여러분은 ELB가 전면에 있는 10개의 EC2 인스턴스에서 웹 사이트를 실행하고 있습니다. 사용자는 <U><strong>웹 사이트 페이지 간에 이동할 때 웹 사이트에서 항상 재인증을 요청한다는 사실</strong></U>에 대해 불평하고 있습니다. 그러나 해당 웹사이트는 한 개의 EC2 인스턴스가 있는 개발 환경과 컴퓨터에서는 제대로 작동하기 때문에 의아합니다. 이 현상이 발생하는 이유는 무엇일까요?</p>
<p><span style='color:green'>1. ELB에 Sticky Session이 활성화되어 있지 않음.</span>
<span>2. 여러 EC2 인스턴스에서 호스팅할 때 웹 사이트에 문제가 있음.</span>
<span>3. EC2 인스턴스는 사용자가 자신의 IP 주소를 볼 수 없기 때문에 로그아웃 하는 대신 ELB IP주소를 수신.</span></p>
<p><strong>풀이💡</strong></p>
<ol>
<li><p>ELB에 Sticky Session이 활성화되어 있지 않음 ✅
ELB는 기본적으로 라운드로빈 방식으로 요청을 분배합니다.
즉, 같은 사용자의 요청이라도 다른 EC2 인스턴스로 라우팅될 수 있음</p>
<p>웹 애플리케이션이 세션 정보를 <strong>서버 메모리(Instance Local)</strong>에 저장하고 있다면, 다른 인스턴스로 요청이 가면 세션 정보가 없어 재인증 요청이 발생</p>
<p>해결 방법: Sticky Session(세션 유지, Session Affinity) 활성화 → 사용자가 항상 같은 인스턴스로 요청이 가도록 함</p>
</li>
<li><p>여러 EC2 인스턴스에서 호스팅할 때 웹 사이트에 문제가 있음. ❌</p>
<p>여러 인스턴스 자체가 문제가 아니라, 세션이 인스턴스 간 공유되지 않아서 발생하는 문제입니다.</p>
<p>즉, “호스팅 환경이 여러 대라서 문제”라는 표현은 정확하지 않아요.</p>
</li>
<li><p>EC2 인스턴스는 사용자가 자신의 IP 주소를 볼 수 없기 때문에 로그아웃 하는 대신 ELB IP주소를 수신. ❌</p>
<p>사용자의 IP는 ELB를 거치면서 X-Forwarded-For 헤더로 전달 가능</p>
<p>이 때문에 로그아웃이 일어나는 건 아님 → ❌</p>
</li>
</ol>
<hr>
<p>Q5. Application Load Balancer를 사용하여 EC2 인스턴스에서 호스팅되는 웹 사이트로 트래픽을 분산하고 있습니다. 웹 사이트는 실제로 Application Load Balancer의 IP 주소인 프라이빗 IPv4 주소에서 오는 트래픽만 보는 것으로 나타났습니다. 웹사이트에 연결된 클라이언트의 IP 주소를 얻으려면 어떻게 해야 할까요?</p>
<p><span>1. 사용자가 모든 요청에서 자신의 IP를 보내도록 웹사이트의 프런트엔드를 수정</span>
<span style='color:green'>2. X-Forwarded-For 헤더에서 클라이언트 IP 주소를 가져오도록 웹사이트의 백엔드를 수정</span>
<span>3. 웹사이트의 백엔드를 수정하여 X-Forwarded-Port 헤더에서 클라이언트 IP 주소를 가져옴</span>
<span>4. 웹사이트의 백엔드를 수정하여 X-Forwarded-Proto 헤더에서 클라이언트 IP 주소를 가져옴</span></p>
<p><strong>풀이💡</strong></p>
<ol>
<li><p>사용자가 모든 요청에서 자신의 IP를 보내도록 프런트엔드 수정 ❌</p>
<p>사용자가 IP를 “보내도록” 하는 건 현실적으로 불가능</p>
<p>HTTP 요청에는 이미 클라이언트 IP가 포함돼 있고, ALB가 이를 전달해줌 → ❌</p>
</li>
<li><p>X-Forwarded-For 헤더에서 클라이언트 IP 주소를 가져오도록 백엔드 수정 ✅</p>
<p>ALB는 X-Forwarded-For 헤더에 실제 클라이언트 IP를 담아서 EC2로 전달</p>
<p>따라서 백엔드에서 X-Forwarded-For 헤더를 읽으면 실제 클라이언트 IP 확인 가능 → ✅</p>
</li>
<li><p>X-Forwarded-Port 헤더에서 클라이언트 IP 가져오기 ❌</p>
<p>X-Forwarded-Port는 요청이 들어온 포트 번호를 나타냄</p>
<p>클라이언트 IP와는 관련 없음 → ❌</p>
</li>
<li><p>X-Forwarded-Proto 헤더에서 클라이언트 IP 가져오기 ❌</p>
<p>X-Forwarded-Proto는 요청 프로토콜(http/https)을 나타냄</p>
<p>IP와는 관련 없음 → ❌</p>
</li>
</ol>
<hr>
<p>Q6. ELB가 전면에 있는 일련의 EC2 인스턴스에서 애플리케이션을 호스팅했습니다. 일주일 후 사용자는 애플리케이션이 때때로 작동하지 않는다고 불평하기 시작합니다. 문제를 조사한 결과 일부 EC2 인스턴스가 때때로 충돌하는 것을 발견했습니다. 사용자가 충돌하는 EC2 인스턴스에 연결하지 못하도록 보호하려면 어떻게 해야 할까요?</p>
<p><span>1. ELB Stickiness 활성화</span>
<span>2. SSL Termination 활성화</span>
<span style='color:green'>3. ELB Health Checks 활성화</span>
<span>4. Cross-Zone Load Balancing 활성화</span></p>
<p><strong>풀이💡</strong></p>
<ol>
<li><p>ELB Stickiness 활성화 ❌</p>
<p>Sticky Session은 같은 사용자가 항상 동일한 인스턴스로 요청을 보내도록 하는 기능</p>
<p>오히려 충돌한 인스턴스로 계속 연결될 수 있음 → ❌</p>
</li>
<li><p>SSL Termination 활성화 ❌</p>
<p>SSL Termination은 SSL 암호화를 ELB에서 해제하는 기능</p>
<p>트래픽 보호와는 관계 없음 → ❌</p>
</li>
<li><p>ELB Health Checks 활성화 ✅</p>
<p>Health Check를 활성화하면 인스턴스 상태를 주기적으로 확인</p>
<p>상태가 Unhealthy로 판단되면 ELB는 해당 인스턴스에 트래픽 전송을 중단</p>
<p>충돌 인스턴스가 있어도 사용자는 문제 없이 다른 Healthy 인스턴스로 연결 가능 → ✅</p>
</li>
<li><p>Cross-Zone Load Balancing 활성화 ❌</p>
<p>Cross-Zone LB는 여러 가용 영역(AZ) 간에 트래픽 분산</p>
<p>충돌 인스턴스 차단과는 직접 관련 없음 → ❌</p>
</li>
</ol>
<hr>
<p>Q7. 여러분은 회사의 솔루션 아키텍트로 일하고 있으며 초당 수백만 건의 요청을 수신할 <strong>고성능, 저지연 애플리케이션</strong>을 위한 아키텍처를 설계해야 합니다. 어떤 유형의 ELB를 선택해야 할까요?</p>
<p><span>1. Application Load Balancer</span>
<span>2. Classic Load Balancer</span>
<span style='color:green'>3. Network Load Balancer</span></p>
<p><strong>풀이💡</strong></p>
<ol>
<li><p>Application Load Balancer (ALB) ❌</p>
<ul>
<li><p>L7 계층 (HTTP/HTTPS)</p>
</li>
<li><p>기능: URL 기반 라우팅, Host 기반 라우팅, WebSocket 지원 등</p>
</li>
<li><p>장점: 애플리케이션 로직 기반 라우팅</p>
</li>
<li><p>단점: 초당 수백만 요청 같은 극한 성능, 저지연 처리에는 최적화 아님 → ❌</p>
</li>
</ul>
</li>
<li><p>Classic Load Balancer (CLB) ❌</p>
<ul>
<li><p>초기형 ELB, L4 + L7 지원</p>
</li>
<li><p>기능 제한, 성능 최적화 부족, 새로운 기능 부재</p>
</li>
<li><p>AWS에서는 신규 서비스 권장 아님 → ❌</p>
</li>
</ul>
</li>
<li><p>Network Load Balancer (NLB) ✅</p>
<ul>
<li><p>L4 계층 (TCP, UDP)</p>
</li>
<li><p>특징:</p>
</li>
<li><p>초고성능 (수백만 요청/초 처리 가능)</p>
</li>
<li><p>극히 낮은 지연(latency)</p>
</li>
<li><p>정적 IP, Elastic IP 지원</p>
</li>
</ul>
<p>고성능, 저지연 애플리케이션 요구사항에 최적 → ✅</p>
</li>
</ol>
<hr>
<p>Q8. Network Load Balancer의 지원에 포함되는 프로토콜은?</p>
<p><span>1. HTTP</span>
<span>2. HTTPS</span>
<span>3. WebSocket</span>
<span style='color:green'>4. Network Load Balancer</span></p>
<hr>
<p>Q9. Application Load Balancer는 조건에 따라 트래픽을 다른 대상 그룹으로 라우팅할 수 있는데 그 조건이 아닌 것은?</p>
<p><span>1. 호스트 이름</span>
<span style='color:green'>2. 고객의 위치(지역)</span>
<span>3. 요청 URL 경로</span>
<span style='color:red'>4. 소스 IP-주소</span></p>
<p><strong>풀이💡</strong></p>
<ol>
<li><p>호스트 이름(Host Header)</p>
<p>ALB에서 지원 ✅</p>
<p>예: <a href="http://www.example.com">www.example.com</a> → 대상 그룹 A, api.example.com → 대상 그룹 B</p>
</li>
<li><p>고객의 위치(지역)</p>
<p>ALB는 클라이언트 지역 기반 라우팅을 지원하지 않음 ❌</p>
<p>위치 기반 라우팅을 하려면 Route 53 지리 위치 라우팅(Geo DNS) 사용 필요 → 정답 ✅</p>
</li>
<li><p>요청 URL 경로(Path)</p>
<p>ALB에서 지원 ✅</p>
<p>예: /images/* → 대상 그룹 A, /api/* → 대상 그룹 B</p>
</li>
<li><p>소스 IP 주소</p>
<p>ALB는 IP 주소 기반 라우팅을 지원하지 않음 ❌</p>
<p>IP 기반 제어는 Security Group, NACL, WAF 사용</p>
<p>근데 왜 정답이지..?😢 =&gt; 라우팅 조건으로 직접 쓸 수 없지만, WAF나 Security Group에서는 제어 가능해서(좀 애매따리하다..)</p>
</li>
</ol>
<hr>
<p>Q10. Application Load Balancer의 대상 그룹에 등록된 대상이 아닌 것은?</p>
<p><span style='color:green'>1. Network Load Balancer</span>
<span>2. Lambda 함수</span>
<span>3. 비공개 IP 주소</span>
<span >4. EC2 인스턴스</span></p>
<p><strong>풀이💡</strong></p>
<ol>
<li><p>Network Load Balancer (NLB) ✅</p>
<p>대상 그룹에 NLB를 등록할 수 없음</p>
<p>ALB → EC2, Lambda, IP 주소만 라우팅 가능</p>
<p>NLB는 다른 ELB, <U>즉 서로 다른 계층의 로드밸런서이므로 등록 대상 아님</U></p>
</li>
<li><p>Lambda 함수</p>
<p>ALB는 Lambda 함수를 대상으로 직접 호출 가능 ✅</p>
</li>
<li><p>비공개 IP 주소(Private IP)</p>
<p>ALB 대상 그룹에는 EC2 인스턴스의 IP나 VPC 내 Private IP 등록 가능 ✅</p>
</li>
<li><p>EC2 인스턴스</p>
<p>가장 일반적인 대상 ✅</p>
</li>
</ol>
<hr>
<p>Q11. 규정 준수를 위해 최종 사용자에게 고정 static IP 주소를 노출하여 규제 기관에서 승인한 안정적인 방화벽 규칙 작성 시 어떤 유형의 ELB를 선택하시겠습니까?</p>
<p><span>1. Elastic IP가 연결된 Application Load Balancer</span>
<span style='color:green'>2. Network Load Balancer</span>
<span>3. Classic Load Balancer</span></p>
<hr>
<p>Q12. Application Load Balancer에서 사용자 지정 애플리케이션 기반 쿠키를 생성하려고 합니다. 다음 중 쿠키 이름으로 사용할 수 있는 것은 무엇일까요?</p>
<p><span>1. AWSALBAPP</span>
<span>2. AWSALBTG</span>
<span style='color:green'>3. APPUSERC</span>
<span >4. AWSALB</span></p>
<hr>
<p>Q13. us-east-1의 몇몇 EC2 인스턴스에 트래픽을 분산하는 Network Load Balancer가 있습니다. us-east-1b AZ에 2개의 EC2 인스턴스와 us-east-1e AZ에 5개의 EC2 인스턴스가 있습니다. us-east-1b AZ의 EC2 인스턴스에서 CPU 사용률이 더 높다는 것을 확인했습니다. 추가 조사 후 트래픽이 두 AZ에 균등하게 분산되어 있음을 알 수 있습니다. 이 문제를 어떻게 해결하시겠습니까?</p>
<p><span>1. Sticky Session 활성화</span>
<span style='color:green'>2. Cross-Zone Load Balancing 활성화</span>
<span>3. ELB Health Checkes 활성화</span>
<span >4. SSL 종료 활성화</span></p>
<p>로드밸런서가 AZ(가용영역) 단위로 먼저 트래픽을 똑같이 나눈다 = 트래픽이 두 AZ에 균등하게 분산되어 있음</p>
<p><strong>풀이💡</strong></p>
<ol>
<li><p>Sticky Session 활성화</p>
<p>NLB는 세션 기반 서비스가 아니고, 세션 스티키와 무관</p>
</li>
<li><p>Cross-Zone Load Balancing 활성화</p>
<p>트래픽을 전체 인스턴스 기준으로 균등 분산해 CPU 불균형 해결</p>
</li>
<li><p>ELB Health Check 활성화</p>
<p>문제는 “건강 상태”가 아니라 부하 불균형이므로 오답</p>
</li>
<li><p>SSL 종료 활성화</p>
<p>트래픽 분산과 무관. NLB는 대부분 L4 TCP/UDP 로드밸런서라 SSL 종료도 일반적이지 않음.</p>
</li>
</ol>
<hr>
<p>Q14. Application Load Balancer와 Network Load Balancer의 어떤 기능을 통해 하나의 리스너에 여러 SSL 인증서를 로드할 수 있습니까?</p>
<p><span style='color:green'>1. 서버 이름 표시(SNI, Server Name Indication)</span>
<span>2. TLS 종료</span>
<span>3. 호스트 헤더</span>
<span >4. SSL 보안 정책</span></p>
<hr>
<p>Q15. 다음 호스트 이름을 기반으로 트래픽을 3개의 대상 그룹으로 리디렉션하도록 구성된 Application Load Balancer가 있습니다: users.example.com, api.external.example.com 및 checkout.example.com. 이러한 각 호스트 이름에 대해 HTTPS를 구성하려고 합니다. 이 작업을 수행하려면 ALB를 어떻게 구성해야 할까요?</p>
<p><strong>풀이💡</strong></p>
<p><span style='color:red'>1. HTTP에서 HTTPS로의 리디렉션 규칙 사용</span>
<span>2. 보안 그룹 SSL 인증서 사용</span>
<span style='color:green'>3. SNI 사용</span></p>
<p>호스트 이름별(Host header) 로 트래픽을 서로 다른 대상 그룹으로 라우팅하려고 하고, 각 호스트에 대해 HTTPS(각기 다른 TLS 인증서) 를 적용하려고 함</p>
<p>Application Load Balancer(ALB)는 하나의 HTTPS 리스너(포트 443)에 여러 TLS 인증서를 연결할 수 있고, 클라이언트가 TLS 핸드쉐이크 시 서버명(Host)을 제시하면 ALB가 해당 호스트에 맞는 인증서를 선택해 응답. 이 방식이 SNI(Server Name Indication)</p>
<hr>
<p>Q16. 목표 용량과 최대 용량을 모두 3으로 구성한 Auto Scaling Group에서 관리하는 EC2 인스턴스 집합에 호스팅되는 애플리케이션이 있습니다. 또한, CPU 사용율이 60%에 도달하면 ASG를 확장하도록 구성된 CloudWatch Alarm도 생성되어 있습니다. 이 애플리케이션이 갑자기 많은 트래픽을 수신하여 CPU 사용율이 80%라면 어떤 현상이 발생할까요?</p>
<p><span>1. 목표 용량은 4까지 올라가고 최대 용량은 3으로 유지된다.</span>
<span style='color:green'>2. 아무 일도 일어나지 않는다.</span>
<span>3. 목표 용량은 4까지 올라가고 최대 용량은 4으로 유지된다.</span></p>
<p><strong>풀이💡</strong></p>
<p>스케일 아웃(인스턴스 확장)은 최대 용량을 초과할 수 없음</p>
<hr>
<p>Q17. ApplicationLoad Balancer가 전면에 있는 Auto Scaling Group (ASG)이 있습니다. ALB Health Checks을 사용하도록 ASG를 구성했는데 하나의 EC2 인스턴스가 비정상으로 보고되었습니다. EC2 인스턴스는 어떻게 될까요?</p>
<p><span>1. ASG는 인스턴스를 계속 실행하고 애플리케이션을 다시 시작합니다.</span>
<span style='color:red'>2. ASG는 EC2 인스턴스를 분리하고 계속 실행합니다.</span>
<span style='color:green'>3. ASG는 EC2 인스턴스를 종료합니다.</span></p>
<p><strong>풀이💡</strong></p>
<ol>
<li><p>ASG는 인스턴스를 계속 실행하고 애플리케이션을 다시 시작 → ❌</p>
<p>ASG는 Health Check 결과를 기준으로 인스턴스를 교체하는 구조</p>
<p>단순히 애플리케이션 재시작은 하지 않음</p>
</li>
<li><p>ASG는 EC2를 분리하고 계속 실행 → ❌</p>
<p>‘분리’라 함은 트래픽에서 제거하는 것을 의미할 수 있음</p>
<p>하지만 ASG 정책상 Unhealthy 인스턴스는 종료 후 새 인스턴스로 교체</p>
</li>
<li><p>ASG는 EC2 인스턴스를 종료 → ✅</p>
<p>정확한 동작:</p>
<p>ALB Health Check 실패 → ASG가 인스턴스를 Unhealthy로 판단</p>
<p>트래픽에서 제거 → 종료 → 새로운 Healthy 인스턴스 생성</p>
</li>
</ol>
<hr>
<p>Q18. 여러분의 상사가 애플리케이션이 데이터베이스에 전송하는 분당 요청 수를 기반으로 ASG을 스케일링하도록 요청했습니다. 어떻게 해야 할까요?</p>
<p><span>1. 정중하게 불가능하다고 말한다.</span>
<span style='color:green'>2. CloudWatch 사용자 지정 지표를 생성한 다음 이 지표에 대한 CloudWatch 경보를 생성하여 ASG 확장.</span>
<span>3. 세부 모니터링을 활성화한 다음 CloudWatch 경보 생성해 ASG 확장.</span></p>
<p><strong>풀이💡</strong></p>
<ul>
<li><p>2️⃣ CloudWatch 사용자 지정 지표 생성 후 경보를 만들어 ASG 확장 ✅</p>
<p>정확한 방법:</p>
<p>애플리케이션에서 DB 요청 수를 CloudWatch Custom Metric으로 전송</p>
<p>해당 지표에 CloudWatch Alarm 설정</p>
<p>Alarm 기준으로 ASG Scaling Policy 적용</p>
<p>이 방법이면 요청 수 기준으로 자동으로 Scale Out/In 가능</p>
</li>
<li><p>3️⃣ 세부 모니터링(Enhanced Monitoring) 활성화 후 경보 생성 → ❌</p>
<p>세부 모니터링은 EC2 인스턴스 자체 CPU, 네트워크, 디스크 등 기본 지표 해상도 향상</p>
<p>DB 요청 수 같은 애플리케이션 레벨 지표는 제공하지 않음</p>
<p>따라서 세부 모니터링만 활성화한다고 원하는 기준으로 스케일링 불가</p>
</li>
</ul>
<hr>
<p>Q19. 애플리케이션은 Application Load Balancer 및 ASG과 함께 배포됩니다. 현재 ASG를 수동으로 확장하고 EC2 인스턴스에 대한 평균 연결 수가 약 1000개인지 확인하는 확장 정책을 정의하려고 합니다. 어떤 스케일링 정책을 사용해야 할까요?</p>
<p><span style='color:red'>1. 단순 스케일링 정책</span>
<span>2. 단계 스케일링 정책</span>
<span>3. 스케줄 스케일링 정책</span>
<span style='color:green'>4. 대상 추적 정책</span></p>
<p><strong>풀이💡</strong></p>
<ol>
<li><p>단순 스케일링 정책(Simple Scaling) → ❌</p>
<p>단일 CloudWatch Alarm에 따라 정해진 수만큼 인스턴스 증감</p>
<p>문제: 연결 수가 목표치와 달라도 인스턴스 증감량이 고정 → 목표 달성 어려움</p>
</li>
<li><p>단계 스케일링 정책(Step Scaling) → ❌</p>
<p>특정 지표 범위(Step)에 따라 인스턴스 증감량을 조정</p>
<p>연결 수가 약간 변동해도 대응 가능</p>
<p>문제: 목표치를 정확히 맞추는 정책은 아님 → 조정 필요</p>
</li>
<li><p>스케줄 스케일링 정책(Scheduled Scaling) → ❌</p>
<p>특정 시간/요일에 자동 증감</p>
<p>연결 수 기반은 아님 → 이번 시나리오와 무관</p>
</li>
<li><p>대상 추적 정책(Target Tracking Scaling) ✅</p>
<p>특정 지표(Target Value)를 기준으로 ASG 자동 조정</p>
<p>예: Average ALB Connections = 1000 → ASG가 인스턴스 수를 자동으로 조정</p>
<p>목표치를 정확히 유지하려는 경우 가장 적합</p>
</li>
</ol>
<hr>
<p>Q20. Auto Scaling Group에서 관리하는 EC2 인스턴스에서 호스팅되는 애플리케이션이 갑자기 급증한 트래픽을 수신하여 ASG가 확장되고 새 EC2 인스턴스가 시작되었습니다. 트래픽은 지속적으로 증가하지만 ASG는 새 EC2 인스턴스를 즉시 시작하지 않고 5분 후에 시작합니다. 이 동작의 가능한 원인은 무엇일까요?</p>
<p><span style='color:green'>1. 쿨다운 기간</span>
<span>2. 수명 주기 후크</span>
<span>3. 대상 추적 정책</span>
<span>4. 템플릿 시작</span></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS DVA 항해기 - ELB + ASG - ASG]]></title>
            <link>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-ASG</link>
            <guid>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-ASG</guid>
            <pubDate>Sun, 23 Nov 2025 10:13:14 GMT</pubDate>
            <description><![CDATA[<h2 id="asgauto-scaling-group">ASG(Auto Scaling Group)?</h2>
<p>실제 웹 사이트나 애플리케이션은 시간이 지남에 따라 <U>로드</U>가 변한다</p>
<ul>
<li><p>로드❓</p>
<ul>
<li>요청량(RPS, requests per second): 초당 들어오는 HTTP 요청 수</li>
<li>동시 연결/동시 사용자(concurrent users): 동시에 처리해야 하는 세션 수</li>
<li>리소스 사용량: 인스턴스의 CPU 사용률, 메모리 사용, 네트워크 대역폭, 디스크 I/O</li>
<li>지연시간(latency)과 에러율(5xx 등): 로드가 높아지면 응답 시간이 길어지고 에러가 늘어날 수 있음</li>
</ul>
</li>
</ul>
<p>aws에서는 ec2 인스턴스 생성 api 호출로 아주 빠르게 서버를 생성하고 제거할 수 있다</p>
<p>➡️ 이를 자동화 하기 위해서 ASG(Auto Scaling Group)을 쓰는 것</p>
<h3 id="asg의-특징">ASG의 특징</h3>
<ol>
<li><p>늘어난 로드에 맞춰 Scale Out(인스턴스 추가)</p>
</li>
<li><p>줄어든 로드에 맞춰 Scale in(인스턴스 제거)</p>
</li>
<li><p>전체적으로 매개변수를 정의해서 ASG에서 언제든 실행할 수 있는 최소 및 최대 EC2 인스턴스 수를 정할 수 있음</p>
</li>
<li><p>ASG와 로드 밸런서를 연결하면 ASG에 포함된 EC2 인스턴스가 로드 밸런서에 연결</p>
</li>
<li><p>어떤 인스턴스가 비정상이라고 여겨지면 이것을 종료하고 새 인스턴스를 만들어 대체</p>
</li>
<li><p>ASG는 무료이지만 그 아래 생성되는 EC2와 같은 리소스들에 대해서만 비용을 지불하면 됨</p>
</li>
</ol>
<br/>

<h3 id="asg의-동작-방식">ASG의 동작 방식</h3>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/0b50b24b-1b51-4d02-b9a0-39b9150377c8/image.png" alt=""></p>
<ul>
<li>Minimum Capacity =&gt; ASG에 필요한 최소 인스턴스 수 설정</li>
<li>Desired Capacity =&gt; 희망 인스턴스 수</li>
<li>Maximum Capacity =&gt; ASG에 필요한 최대 인스턴스 수</li>
</ul>
<br/>

<h3 id="로드밸런서--asg의-동작방식">로드밸런서 + ASG의 동작방식</h3>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/f4a748fe-1788-41aa-9fef-2bffbd4d39db/image.png" alt=""></p>
<p>ASG에 등록된 인스턴스가 4개면 ELB가 즉시 모든 인스턴스에 트래픽을 분산 =&gt; 사용자는 로드 밸런서 웹 사이트에 접속 가능</p>
<p>ELB 상태 확인 기능을 활용해서 EC2 인스턴스 상태도 점검 가능 =&gt; 상태 확인 결과는 ASG에 전달될 수 있음</p>
<p>➡️ 로드 밸런서가 EC2 인스턴스를 비정상이라고 여기면 ASG가 인스턴스를 종료할 수 있음</p>
<p>스케일 아웃(인스턴스 추가)을 하면 ELB가 마찬가지로 추가된 인스턴스에도 트래픽을 보내 부하를 분산시킴</p>
<br/>

<h3 id="asg-속성-및-구성요소">ASG 속성 및 구성요소</h3>
<ul>
<li><p>Launch Template(옛 버전: Launch Configurations)
➡️ ASG에서 EC2 인스턴스를 시작하는 방법에 관한 정보가 있음</p>
<ul>
<li>AMI</li>
<li>인스턴스 타입(유형)</li>
<li>EC2 사용자 데이터</li>
<li>EBS 볼륨</li>
<li>보안 그룹</li>
<li>IAM 역할</li>
<li>SSH 키페어</li>
<li>네트워크와 서브넷 정보</li>
<li>로드 밸런서 정보 
등</li>
</ul>
</li>
<li><p>최소 크기 / 최대 크키 / 초기 용량</p>
</li>
<li><p>스케일링 정책 정의해야 함</p>
</li>
</ul>
<br/>

<h3 id="cloudwatch-alarms--scaling">CloudWatch Alarms &amp; Scaling</h3>
<p>CloudWatch 경보를 기반으로 ASG에서 스케일 인, 스케일 아웃할 수 있음</p>
<p>클라우드 워치에서 평균 CPU를 관찰하거나, 사용자가 지정해준 지표를 검사하는 방식으로 임계점을 넘기면 알림을 울려 스케일 인, 아웃을 진행할 수 있다</p>
<hr>
<h2 id="asg-실습">ASG 실습</h2>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/b6f568bd-4ed7-4d54-bf66-02db55647a59/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/2de1a0db-b21b-42da-8f10-01d7ff15a48a/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/3fda17c3-9fe4-4572-9656-e0230fde2eaf/image.png" alt="">
<img src="https://velog.velcdn.com/images/poala_0217/post/add4651f-9ce8-4872-809e-c5249e44deb4/image.png" alt="">
<img src="https://velog.velcdn.com/images/poala_0217/post/7fa81354-4762-4d51-bc6c-a4c166ba3acc/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/898511e7-b24f-4327-80a8-1540e8947c85/image.png" alt=""></p>
<p>생성된 MyDemoTemplate 잘 출력되는 것 확인</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/7296db81-8129-4b6c-8d7b-b83659489e04/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/673fa7ff-8d07-4eed-95fc-9b17674da1f3/image.png" alt=""></p>
<p>기존에 만들어놓은 로드밸런서와도 연결</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/cabe473c-99da-47ca-94d8-b83b9d25016e/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/a100965f-1199-419c-aad9-7ef40b6d82cb/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/1af65925-9042-4f7a-9958-1f231254c54a/image.png" alt="">
ASG가 EC2 인스턴스를 생성하기로 결정하면 작업 히스토리에 표시됨
<img src="https://velog.velcdn.com/images/poala_0217/post/c7303b82-39fb-408c-84d2-28acea67c02d/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/a25c95cd-16e9-4436-99f2-6d3ce3e484af/image.png" alt=""></p>
<p>Instance management 탭에서도 확인 가능</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/101e3fe1-add0-465c-8763-cc3c668e6a72/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/efd7a7de-0038-4060-b042-caad96fd79d5/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/4fa6ea8e-934f-4aec-8832-b51e213fc2e3/image.png" alt=""></p>
<p>인스턴스 2개가 생긴 것 확인 가능</p>
<hr>
<h3 id="asg-스케일링-정책">ASG 스케일링 정책</h3>
<ol>
<li><p>동적 스케일링(Dynamic Scaling)</p>
<ul>
<li><p>목표 추적 스케일링(Target Tracking Scaling)
  ➡️ 설정이 매우 간단함 
  ex) CPU 사용률과 같은 ASG에 대한 메트릭을 정의하고 40%와 같은 목표값 정의</p>
</li>
<li><p>단순(Simple) / 단계(Step) 스케일링
➡️ CloudWatch Alarm이 반드시 필요 
ex) CPU &gt; 70% → 인스턴스 2개 추가</p>
</li>
</ul>
</li>
<li><p>예약 스케일링(Scheduled Scaling)
➡️  알려진 사용 패턴을 기반으로 스케일링을 예상
ex) 금요일 오후 5시에 매번 새로운 사용자가 발생 =&gt; 최소 용량을 10으로 증가</p>
</li>
<li><p>예측 스케일링(Predictive Scaling)
 ➡️ AWS 머신러닝이 지속적으로 트래픽 패턴을 예측해 자동으로 스케일링
 반복되는 패턴이 있을 때 좋음
 ex) 쇼핑몰, 월말 배치 작업 등</p>
</li>
</ol>
<h3 id="asg-metrics">ASG Metrics</h3>
<ol>
<li><p>CPU 사용률(CPU Utilization)
➡️ 인스턴스가 요청을 받을 때마다 일반적으로 일종의 계산을 수행
 모든 인스턴스의 평균 CPU 사용률을 살펴본 후 이 비율이 높아지면 인스턴스의 활용도가 더 높다는 의미</p>
</li>
<li><p>요청 수(Request Count)
➡️ 인스턴스 별 요청 count에 따라 스케일링을 진행하는 방식</p>
</li>
<li><p>네트워크 트래픽(Network In / Out)
➡️ 인스턴스가 보내거나 받는 데이터량을 기준으로 스케일링
ex) 업로드와 다운로드가 너무 많아 EC2 인스턴스에 병목현상이 발생될 것이라 예상된다면,
평균 네트워크 사용량을 기준으로 스케일링을 설정하는 것이 좋다</p>
</li>
<li><p>사용자 정의 지표(Custom Metrics)
➡️ CloudWatch에 직접 지표를 만들어서 ASG 스케일링 기준으로 쓸 수 있음
ex) 큐 길이(SQS 메시지 수), 애플리케이션 처리율, DB 연결 수 등</p>
</li>
</ol>
<h3 id="scaling-cooldowns">Scaling Cooldowns</h3>
<p>➡️ ASG에서 인스턴스를 추가하거나 제거한 후 일정 시간 동안 추가 스케일링을 막는 시간 / 서버를 늘렸는데 바로 다시 늘리는 상황을 막기 위한 “안정화 시간” 같은 개념
➡️ 기본적으로 5분의 쿨다운 시간이 적용됨</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/4b3821f3-ecab-495d-90c7-099d17ea999c/image.png" alt=""></p>
<p>💡 서버를 바로 띄울 수 있는 AMI를 쓰면, 서버 세팅 시간을 줄여서 요청을 더 빨리 처리할 수 있고, ASG의 cooldown 시간도 줄일 수 있다</p>
<p>WHY❓
➡️ ASG가 새 EC2를 추가할 때 서버가 준비되는 시간이 길면 cooldown 동안 충분히 효과를 발휘하지 못할 수 있음
  이미 설정이 끝난 AMI를 사용하면 서버가 바로 준비되기 때문에</p>
<ol>
<li>사용자 요청을 빨리 처리 가능</li>
<li>ASG가 다음 스케일링을 판단할 때 cooldown 시간도 최소화 가능</li>
</ol>
<h3 id="instance-refresh인스턴스-새로고침">Instance Refresh(인스턴스 새로고침)</h3>
<p>➡️ ASG 안에 있는 기존 EC2 인스턴스를 순차적으로 종료하고 새 인스턴스로 교체하는 기능
➡️ 새 AMI로 업데이트하거나 설정 변경 후, 모든 인스턴스를 최신 상태로 맞추고 싶을 때 사용
➡️ 새로 생성된 EC2 인스턴스가 실제 트래픽을 처리할 준비가 되는 시간인 Warm-up Time 지정 가능</p>
<ul>
<li>사용 목적</li>
</ul>
<ol>
<li><p>AMI 업데이트 반영
기존 인스턴스는 오래된 AMI로 만들어져 있을 수 있음
새 AMI로 교체하여 보안 패치, 소프트웨어 버전 업데이트 등 적용 가능</p>
</li>
<li><p>구성 변경 반영</p>
<p>Launch Template이나 Launch Configuration 변경 후, ASG 내 모든 인스턴스를 새 설정으로 맞추고 싶을 때</p>
</li>
<li><p>건강한 상태 유지</p>
<p>일부 인스턴스가 오래되거나 문제 있을 때, 점진적으로 교체하면서 서비스 중단 최소화</p>
</li>
</ol>
<ul>
<li><p>주요 옵션</p>
<table>
<thead>
<tr>
<th>옵션</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>MinHealthyPercentage</td>
<td>교체 진행 시 최소 몇 % 인스턴스가 정상이어야 하는지 설정</td>
</tr>
<tr>
<td>Instance Warm-up</td>
<td>새 인스턴스가 준비되는 시간(Helth 체크까지 대기)</td>
</tr>
<tr>
<td>Auto Scaling group selection</td>
<td>특정 ASG만 새로고침 가능</td>
</tr>
</tbody></table>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS DVA 항해기 - ELB + ASG - Connection Draining]]></title>
            <link>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-Connection-Draining</link>
            <guid>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-Connection-Draining</guid>
            <pubDate>Thu, 20 Nov 2025 01:23:50 GMT</pubDate>
            <description><![CDATA[<h2 id="connection-drainingtarget-deregistration-delay">Connection Draining(Target Deregistration Delay)</h2>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/7775baa1-d0d2-4c54-bf8b-ecb1ca70c2e7/image.png" alt=""></p>
<p>인스턴스(또는 타깃)를 서비스에서 빼거나(스케일 인, 교체, 종료) 헬스체크 실패로 제거할 때, 기존에 열린 연결(요청)을 일정 시간 동안 유지해 처리 완료되도록 하고 새로운 연결은 그 인스턴스로 보내지 않게 하는 기능
=&gt; 트래픽을 “부드럽게 끊는” 장치</p>
<p><strong>Classic ELB vs ALB/NLB(=ELBv2) 용어 차이</strong></p>
<ul>
<li><p>Classic ELB: 용어로 Connection Draining이라 부름(콘솔/CLI 옵션 있음)</p>
</li>
<li><p>ALB / NLB (ELBv2 Target Group): Deregistration delay 라고 부름 (초 단위로 설정)
동일한 개념: 제거 시 기존 연결을 일정 시간 허용</p>
</li>
</ul>
<h4 id="필요한-이유">필요한 이유?</h4>
<ul>
<li><p>요청 중단 방지: 사용자의 요청(특히 긴 요청, 업로드/다운로드, WebSocket 등)이 중간에 끊기는 걸 막음</p>
</li>
<li><p>무중단 배포: 인스턴스 교체(Auto Scaling, 배포) 시 서비스 가용성 유지</p>
</li>
<li><p>데이터 무결성: 트랜잭션/세션이 중단되는 사고를 줄임</p>
</li>
</ul>
<h4 id="동작-원리">동작 원리</h4>
<ol>
<li><p>인스턴스/타깃을 Deregister(또는 ELB가 인스턴스 종료를 감지) 요청을 받음</p>
</li>
<li><p>ELB/Target Group은 그 인스턴스로의 새 연결(요청)을 중단시킴</p>
</li>
<li><p>기존에 이미 맺어진 연결이나 이미 전달된 요청(인플라이트 requests)은 지정된 대기 시간(드레이닝 시간) 동안 계속 처리되도록 허용</p>
</li>
<li><p>드레이닝 시간 내에 처리 완료되면 정상적으로 연결 종료</p>
</li>
<li><p>시간이 지나도 연결/요청이 남아있다면 강제 종료(컷오프) 후 완전 제거</p>
</li>
</ol>
<h4 id="설정aws-관점">설정(AWS 관점)</h4>
<ul>
<li><p>Target Group (ALB/NLB): deregistration_delay.timeout_seconds (최대 3600초(1시간) 가능)</p>
<p>예: 기본 300초(5분)인 경우가 많음(계정/설정에 따라 다름)</p>
</li>
<li><p>Classic ELB: Connection Draining 설정에서 Enabled + Timeout(초) 설정 가능</p>
</li>
</ul>
<ul>
<li>ALB&amp;NLB CLI 예시<pre><code class="language-bash">aws elbv2 modify-target-group-attributes \
--target-group-arn &lt;tg-arn&gt; \
--attributes Key=deregistration_delay.timeout_seconds,Value=300
</code></pre>
</li>
</ul>
<pre><code>
* CLB CLI 예시
```bash
aws elb modify-load-balancer-attributes \
  --load-balancer-name my-elb \
  --load-balancer-attributes &#39;{&quot;ConnectionDraining&quot;:{&quot;Enabled&quot;:true,&quot;Timeout&quot;:300}}&#39;
</code></pre><h4 id="세부-동작--주의-포인트">세부 동작 / 주의 포인트</h4>
<ul>
<li><p>새 연결은 차단되지만 기존 연결(keep-alive, WebSocket, TCP 연결 등) 은 유지됨</p>
</li>
<li><p>ALB의 경우, HTTP 요청이 이미 백엔드에 도달한 상태라면 그 요청은 처리되도록 허용</p>
</li>
<li><p>긴 시간 걸리는 요청(대용량 업로드 등)이 있으면 드레이닝 시간을 충분히 길게 잡아야 함</p>
</li>
<li><p>강제 종료 조건: 드레이닝 시간이 끝나면 남은 연결은 강제로 닫힘 — 그러므로 처리시간보다 드레이닝 시간을 길게 잡아야 안전</p>
</li>
<li><p>Health checks: 인스턴스가 헬스체크 실패 상태로 바뀌면 드레이닝이 트리거됨(제거 절차 시작)</p>
</li>
<li><p>Sticky session 영향: 쿠키 기반 세션이 있어도, 드레이닝 중엔 해당 인스턴스로 새 요청을 보내지 않으니 세션 유실 가능성 고려 필요(세션 공유 권장)</p>
</li>
</ul>
<p>‼️ 헬스체크가 즉시 드레이닝을 트리거하진 않고, 헬스체크의 판정(연속 실패 수)이 나와야 드레이닝(제거 절차)이 시작된다
=&gt; 헬스체크가 설정한 unhealthy threshold 만큼 연속 실패하면 그 타깃을 언헬시로 표시하고, 그 시점에 deregistration(제거) 절차/드레이닝이 시작</p>
<h3 id="요약-정리">요약 정리</h3>
<ul>
<li><p>헬스체크가 ‘실패했다 → 바로 드레이닝’이 아니다: 실패는 연속 실패 수로 판정되므로 즉시 트리거 되지 않음(설정에 따라 지연 있음)</p>
</li>
<li><p>드레이닝 중에도 헬스체크는 계속 수행된다</p>
</li>
<li><p>드레이닝 시작 후 타깃이 다시 정상(헬시) 판정을 받으면, ALB는 드레이닝을 중단하고 해당 타깃을 다시 서비스에 포함시킬 수 있다</p>
</li>
<li><p>즉, 일시적 장애(네트워크 일시 오류 등)였고 빠르게 회복되면 제거가 취소될 수 있음</p>
</li>
<li><p>인스턴스가 즉시 죽거나 프로세스가 강제 종료된 경우에는 &#39;드레이닝 대기&#39;가 의미가 없고 이미 맺어진 연결도 끊김 → 사용자 요청 실패</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS DVA 항해기 - ELB + ASG - SSL 인증서]]></title>
            <link>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-SSL-%EC%9D%B8%EC%A6%9D%EC%84%9C</link>
            <guid>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-SSL-%EC%9D%B8%EC%A6%9D%EC%84%9C</guid>
            <pubDate>Wed, 19 Nov 2025 23:48:32 GMT</pubDate>
            <description><![CDATA[<h2 id="ssl--tls">SSL / TLS</h2>
<p>SSL/TLS
    =&gt; 클라이언트와 서버(또는 로드밸런서) 사이의 통신을 암호화해서 중간에서 패킷을 도청하거나 변조하는 걸 막아줌(in-flight encryption)</p>
<ul>
<li><p>SSL(Secure Sockets Layer)
  =&gt; 연결을 암호화할 때 사용</p>
</li>
<li><p>TLS(Transport Layer Security)
  =&gt; SSL의 새 버전 / 전송 계층 보안을 의미</p>
</li>
</ul>
<p> SSL과 TLS 모두 전송 계층과 애플리케이션 계층 사이에서 동작하고 자체 포맷(X.509)은 동일하게 쓰이지만
     1. 프로토콜 문법(핸드셰이크 방법)
    2. 허용하는 암호화 알고리즘(암호 스위트)
    3. 보안 약점 제거 여부 등 기술적 세부사항들이 다르다</p>
<p>퍼블릭 SSL 인증서는 인증 기관에서 발행
    ex) Comodo, GoDayy, GlobalSign, DigiCert, Letsencrypt, ..etc</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/b23ae4a2-1bdf-404f-aa94-53276eae6308/image.png" alt=""></p>
<p>인증서가 적용된 것</p>
<p>SSL 인증서는 사용자가 정한 만료 날짜가 존재 &amp; 인증서의 진위 확인을 위해 주기적으로 갱신해야 함</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/9980b855-3c33-4183-9734-a01effe4125a/image.png" alt=""></p>
<ul>
<li>로드밸런서는 X.509 인증서를 사용하며, 이것을 SSL 또는 TLS 서버 인증서라고 부른다</li>
<li>ACM → AWS 인증서 관리자로 인증서를 등록하고 관리할 수 있다</li>
<li>HTTP 리스너를 설정할 때는 기본 인증서를 지정 &amp; 인증서 목록을 추가해 여러 도메인 지원 가능</li>
<li>클라이언트는 SIN(Server Name Indication: 서버 이름 표기)를 활용해 도달하려는 호스트 이름 지정 가능</li>
<li>HTTPS에 특정 보안 정책을 설정해서 레거시 클라이언트라고 불리는 SSL / TLS 구버전 지원 가능</li>
</ul>
<h2 id="sniserver-name-indiciation">SNI(Server Name Indiciation)</h2>
<p>하나의 IP/포트(보통 :443)에서 여러 도메인의 TLS(HTTPS) 사이트를 호스팅할 수 있게 클라이언트가 TLS 연결 초기에 접속하려는 호스트명(도메인)을 서버에 알려주는 확장</p>
<p>즉, 같은 IP에 siteA.com과 siteB.com이 있어도 각각 다른 인증서를 쓸 수 있게 해준다</p>
<p>클라이언트가 대상 서버의 호스트 이름을 지정하도록 해야한다</p>
<ul>
<li>최초 SSL Handshake 단계에 이루어진다</li>
<li>클라이언트가 &#39;이 웹 사이트에 연결하고 싶다&#39;라고 접속할 웹 사이트를 알려줌으로써 서버는 어떤 인증서를 로드해야 하는지 알 수 있음</li>
<li>모든 클라이언트가 지원하지 않는다</li>
</ul>
<p>ALB &amp; NLB, CloudFront에서만 지원
로드밸런서에 여러 SSL 인증서가 표시되면 ALB나 NLB 떠올리기!</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/1fc6e649-7698-4f28-bbed-3bbfbb48c54d/image.png" alt=""></p>
<p>ALB &amp; NLB vs CLB</p>
<p>ALB &amp; NLB</p>
<ul>
<li>여러 개의 SSL인증서 통해 웹 서비스를 여러 개 둘 수 있다</li>
<li>SNI를 지원하기 때문에 가능</li>
</ul>
<p>CLB</p>
<ul>
<li>하나의 인증서만 지원</li>
<li>만약 여러 호스트를 지원하려면 그에 맞는 클래식 로드밸런서 갯수가 필요함</li>
</ul>
<hr>
<h2 id="ssl-실습">SSL 실습</h2>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/7690f71b-c3a6-4d96-bed5-a418d1ff5c4f/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/e5b5e4b8-af2c-485c-93ea-50ea8279df13/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS DVA 항해기 - ELB + ASG - Cross-Zone Load Balancing]]></title>
            <link>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-Cross-Zone-Load-Balancing</link>
            <guid>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-Cross-Zone-Load-Balancing</guid>
            <pubDate>Mon, 17 Nov 2025 13:06:02 GMT</pubDate>
            <description><![CDATA[<h2 id="cross-zone-load-balancing">Cross-Zone Load Balancing</h2>
<p>AWS 로드밸런서(ALB, NLB, CLB)가 여러 AZ(Availability Zone) 에 배포된 상태에서
각 로드밸런서 노드가 모든 AZ의 인스턴스들에 균등하게 트래픽을 분산시키는 기능</p>
<p>1) 기본 모드(비활성화 시)
    → 각 AZ의 로드밸런서 노드는 자기 AZ 안에 있는 인스턴스에게만 트래픽을 전달함.</p>
<p> 예시) </p>
<p> <img src="https://velog.velcdn.com/images/poala_0217/post/f2b7baf6-5d89-4a89-8039-99a6503ff58b/image.png" alt=""></p>
<p>AZ A: 로드밸런서 노드 1개 + 인스턴스 2개 =&gt; 25%씩
AZ B: 로드밸런서 노드 1개 + 인스턴스 3개 =&gt; 6.25%씩</p>
<p>➡️ 트래픽 분배 결과</p>
<ul>
<li>A =&gt; 25%씩<ul>
<li>B =&gt; 6.25%씩</li>
</ul>
</li>
</ul>
<p>2) Cross-Zone LB 활성화 시
    → 각 AZ의 로드밸런서 노드가 모든 AZ의 인스턴스들에게 트래픽을 골고루 분배함</p>
<p>   <img src="https://velog.velcdn.com/images/poala_0217/post/54906430-2982-4e04-a485-f0281ca0e543/image.png" alt=""></p>
<p>➡️ 트래픽 분배 결과 =&gt; 각 인스턴스에 트래픽이 10%씩 균등 분배됨</p>
<p>ALB의 경우 기본적으로 Cross-Zone Load Balancing이 활성화 되어있음
비활성화는 대상 그룹(Target Group) 레벨에서 가능
데이터가 가용 영역으로 넘어가도 요금이 부과되지 않음(보통은 AZ를 넘어가면 과금)</p>
<p>NLB, GWLB의 Cross-Zone Load Balancing은 비활성화 =&gt; 활성화 시 과금
데이터가 가용 영역으로 넘어가서 과금 되기 때문</p>
<p>CLB Cross-Zone Load Balancing은 비활성화 되어있지만 데이터가 가용 영역으로 넘어가도 요금이 부과되지 않음</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS DVA 항해기 - ELB + ASG - Sticky Sessions]]></title>
            <link>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-Sticky-Sessions</link>
            <guid>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-Sticky-Sessions</guid>
            <pubDate>Mon, 17 Nov 2025 11:48:02 GMT</pubDate>
            <description><![CDATA[<h2 id="sticky-sesisonssession-affinity">Sticky Sesisons(Session Affinity)</h2>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/38d46ee9-bac1-4880-8003-23f6c5ec4ffe/image.png" alt=""></p>
<p>클라이언트가 로드 밸런서에 두 번의 요청을 할 때 백엔드에서 동일한 인스턴스가 요청에 응답하도록 하는 것 
 =&gt; 여러 대의 서버가 있어도, 특정 사용자의 요청을 계속 같은 서버로 보내주는 기능</p>
<p>CLB, ALB, NLB에서 활성화 할 수 있음</p>
<ul>
<li>동작 방식</li>
</ul>
<p>클라이언트가 로드 밸런서로 요청을 보낼 때 쿠키(스티키니스 + 만료날짜 포함된)가 함께 전송</p>
<p>=&gt; 이 쿠키가 만료되면 클라이언트가 다른 EC2 인스턴스로 리다이렉션 될 수 있음</p>
<ul>
<li><p>ALB에서 sticky session의 동작</p>
<p>1) 쿠키 기반 세션 고정</p>
<p>ALB는 쿠키(cookie) 를 사용해서 세션을 고정</p>
<ul>
<li>사용자가 ALB에 요청을 보냄</li>
</ul>
<ul>
<li><p>ALB가 자기 마음대로(정책에 따라) EC2 하나를 골라서 보냄 (예: EC2 #2)</p>
</li>
<li><p>그리고 응답할 때 특별한 쿠키를 내려 줌:
예: AWSALB, AWSALBTG 같은 이름</p>
</li>
</ul>
<p>이 쿠키 안에는:</p>
<ul>
<li>“이 사용자 → 어떤 Target Group/Target으로 붙었는지”에 대한 정보가 들어 있음</li>
</ul>
<p>그 다음 요청부터는:</p>
<ol>
<li><p>브라우저가 ALB에 요청을 할 때 그 쿠키를 같이 보냄</p>
</li>
<li><p>ALB는 쿠키를 보고:</p>
</li>
</ol>
<p>“아 이 유저는 예전에 EC2 #2에 붙어 있던 애네?”
→ 다시 EC2 #2로 고정해서 보냄</p>
<p>2) 세션 지속 시간(만료 시간)
 ALB의 sticky session은 <strong>“타임아웃(지속 시간)”</strong>을 설정할 수 있음</p>
<p>예: 300초(5분), 3600초(1시간) 등</p>
<p>즉, 그 시간 동안은 → 같은 Target으로 고정</p>
<p>시간이 지나면:</p>
<p>쿠키가 만료 → 다시 로드 밸런서 정책(라운드 로빈 등)에 따라 다른 서버로 갈 수도 있음</p>
</li>
</ul>
<ul>
<li><p>Sticky Session의 Use-case</p>
<ol>
<li><p>세션을 서버 메모리에 저장하는 레거시 애플리케이션</p>
</li>
<li><p>서버가 사용자 상태를 메모리에 들고 있을 때</p>
<ul>
<li>시험 시스템(남은 시간/문제 상태가 메모리에 저장)</li>
<li>실시간 설문/게임 룸 상태</li>
</ul>
</li>
<li><p>WebSocket / Long Polling 기반 서비스</p>
<ul>
<li>WebSocket 핸드셰이크나 Long Polling 요청은 서버와 계속 이어지는게 안정 적</li>
</ul>
</li>
<li><p>큰 파일 업로드</p>
<ul>
<li>대용량 업로드 과정에서 서버가 &quot;현재 몇 MB 전송됨&quot; 같은 상태를 메모리에 보유</li>
</ul>
</li>
</ol>
</li>
</ul>
<ul>
<li><p>Sticky Session의 단점</p>
<ol>
<li><p>트래픽 분산이 불균형해질 수 있음(특정 서버에 트래픽 몰림)</p>
</li>
<li><p>서버가 죽으면 그 유저의 세션도 바로 날아감</p>
</li>
<li><p>Auto Scaling 시 새 서버로 교체되면 sticky가 무용지물될 수 있음</p>
</li>
<li><p>Stateless 아키텍처의 장점을 못 가져감</p>
</li>
</ol>
</li>
</ul>
<h3 id="sticky-session을-위한-쿠키의-종류">Sticky Session을 위한 쿠키의 종류</h3>
<ol>
<li><p>애플리케이션 기반 쿠키</p>
<ul>
<li><p>커스텀 쿠키(Custom Cookie)</p>
<ul>
<li>애플리케이션 자체(target group?)에서 생성하는 사용자 정의 쿠키<ul>
<li>애플리케이션에서 필요로 하는 모든 사용자 정의 속성 포함 가능</li>
<li>쿠키 이름은 각 타켓 그룹마다 개별적으로 지정</li>
<li>AWSALB, AWSALBAPP, AWSALBTG와 같은 이름들은 사용해선 안 됨!! =&gt; 예약어</li>
</ul>
</li>
</ul>
</li>
<li><p>애플리케이션 쿠키(Application Cookie)</p>
<ul>
<li>로드 밸런서 자체에서 생성</li>
<li>쿠키 이름 = AWSALBAPP</li>
</ul>
</li>
</ul>
</li>
</ol>
<ol start="2">
<li><p>지속 시간 기반 쿠키</p>
<ul>
<li>로드 밸런서에서 생성</li>
<li>쿠키이름: ALB =&gt; AWSALB / CLB =&gt; AWSELB</li>
<li>특정 시간에 따라 만료되며 지속 시간은 로드 밸런서 자체에서 생성</li>
<li>애플리케이션 기반 쿠키가 있을 때는 지속 시간을 애플리케이션 자체에서 지정 가능</li>
</ul>
</li>
</ol>
<h3 id="sticky-session-설정-실습">Sticky Session 설정 실습</h3>
<p> <img src="https://velog.velcdn.com/images/poala_0217/post/5a967fe7-0514-4b16-8f96-67df40fdc6f9/image.png" alt=""></p>
<p>대상그룹(Target Group) =&gt; 속성 변경(Edit Attributes) =&gt; Stickiness 옵션</p>
<p>새로고침 후 DNS Name 주소로 접근하면</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/d5d0dd81-8de6-4cec-9721-f6c148687f15/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS DVA 항해기 - ELB + ASG - GWLB]]></title>
            <link>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-GWLB</link>
            <guid>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-GWLB</guid>
            <pubDate>Sat, 15 Nov 2025 14:36:12 GMT</pubDate>
            <description><![CDATA[<h2 id="gwlb">GWLB</h2>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/d9ddaac6-409e-40aa-96b5-f36f73be4d9e/image.png" alt=""></p>
<p>방화벽, IDS/IPS, DPI(Deep Packet Inspection) 같은 “네트워크 보안/트래픽 분석 장비”를 AWS에서 대규모로, 자동 스케일링 / 로드밸런싱 / 장애조치까지 묶어서 제공하는 L3 로드 밸런서</p>
<ul>
<li><p>모든 트래픽이 방화벽을 통과하게 하거나 침입 탐지 및 방지 시스템에 사용</p>
</li>
<li><p>IDPS(Intrusion Detection &amp; Prevention System: 침입 탐지/차단 시스템), 심층 패킷 분석 시스템(DPI: Deep Packet Inspection / 패킷의 헤더뿐 아니라 내용(payload) 까지 들여다보는 시스템) 또는 일부 페이로드를 수정할 수 있지만 네트워크 수준에서 가능하다</p>
<p>❔일부 페이로드 수정?</p>
<ul>
<li>악성 코드가 포함된 일부 내용을 지우거나 바꾸거나</li>
</ul>
<ul>
<li><p>민감한 정보(예: 카드 번호)가 평문으로 갈 때 마스킹하거나 암호화 하거나</p>
</li>
<li><p>HTTP 헤더를 삽입/수정해서 보안 정책을 적용하는 것</p>
</li>
</ul>
</li>
<li><p>6081번 포트의 GENEVE 프로토콜을 사용한다</p>
</li>
<li><p>투명 네트워크 게이트웨이처럼 동작 =&gt; 클라이언트 &amp; 서버 입장에선 중간에 뭐가 끼어있는지 모름</p>
</li>
</ul>
<br/>

<h4 id="alb--nlb-vs-gwlb">ALB &amp; NLB vs GWLB</h4>
<p>ALB/NLB는 “서비스(HTTP/TCP)를 여러 서버에 분산”이라면,
GWLB는 “네트워크 장비 역할(방화벽 같은 것)을 여러 인스턴스에 분산”</p>
<table>
<thead>
<tr>
<th>항목</th>
<th>ALB</th>
<th>NLB</th>
<th>GWLB</th>
</tr>
</thead>
<tbody><tr>
<td>계층</td>
<td>L7 (HTTP/HTTPS)</td>
<td>L4 (TCP/UDP/TLS)</td>
<td><strong>L3 (IP)</strong></td>
</tr>
<tr>
<td>주 용도</td>
<td>웹 앱, 마이크로서비스 라우팅</td>
<td>고성능 TCP/UDP 서비스, 고정 IP</td>
<td><strong>네트워크 보안/어플라이언스 트래픽 분산</strong></td>
</tr>
<tr>
<td>라우팅 기준</td>
<td>Host/Path/헤더/쿼리 등 L7</td>
<td>IP/Port/프로토콜</td>
<td>IP 레벨, GENEVE encapsulation</td>
</tr>
<tr>
<td>타깃</td>
<td>EC2, IP, Lambda</td>
<td>EC2, IP, ALB</td>
<td>IP (어플라이언스 인스턴스들)</td>
</tr>
<tr>
<td>Endpoint</td>
<td>-</td>
<td>-</td>
<td><strong>GWLBe(Endpoint)로 타 VPC/서브넷과 연결</strong></td>
</tr>
</tbody></table>
<h3 id="gwlb의-흐름">GWLB의 흐름</h3>
<p>큰 구조: GWLB + GWLBe + 어플라이언스</p>
<ol>
<li><p>Gateway Load Balancer (GWLB)</p>
<ul>
<li><p>L3 로드밸런서</p>
</li>
<li><p>트래픽을 “어플라이언스”로 분산해줌</p>
</li>
</ul>
</li>
</ol>
<ol start="2">
<li><p>Gateway Load Balancer Endpoint (GWLBe)</p>
<ul>
<li><p>각 VPC/Subnet에서 GWLB로 향하는 “문” 역할</p>
</li>
<li><p>사용자는 라우팅 테이블에서 목적지 → GWLBe 로 보내도록 설정</p>
</li>
</ul>
</li>
</ol>
<ol start="3">
<li><p>어플라이언스(네트워크 가상 장비)</p>
<ul>
<li><p>EC2 위에 돌아가는 방화벽/IDS/보안 솔루션</p>
</li>
<li><p>Target Group에 IP로 등록 (타입: ip)</p>
</li>
</ul>
<p>흐름</p>
<p>[VPC/Subnet 라우팅]
 → GWLBe (Gateway Load Balancer Endpoint)</p>
<pre><code>→ GWLB
   → 어플라이언스(방화벽/IDS 등) Target Group
   → 다시 GWLB/GWLBe를 통해 원래 목적지로 복귀</code></pre></li>
</ol>
<h4 id="gwlb의-타겟">GWLB의 타겟</h4>
<ol>
<li><p>EC2 인스턴스</p>
</li>
<li><p>IP 주소 =&gt; 사설 IP</p>
</li>
</ol>
<br/>

<p> 한 줄 정리</p>
<p> GWLB의 주요 기능은 네트워크 트래픽 분석이며 L3 (네트워크 계층)에서 이루어지며 GWLB를 두는 순간 라우트 테이블은 업데이트 되어 이후 트래픽이 GWLB를 거친다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS DVA 항해기 - ELB + ASG - NLB]]></title>
            <link>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-NLB</link>
            <guid>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-NLB</guid>
            <pubDate>Sat, 15 Nov 2025 08:29:49 GMT</pubDate>
            <description><![CDATA[<h2 id="nlb">NLB</h2>
<p>L4(TCP/UDP) 레벨에서, 엄청 높은 성능과 아주 낮은 지연시간으로 트래픽을 분산해주는 로드 밸런서</p>
<p><strong>초당 수백만 요청, 고성능, 소스 IP 보존, TCP, UDP</strong>가 키워드</p>
<p>ALB와 다르게 NLB는 <strong>각 AZ마다 하나의 정적 IP 주소</strong>를 갖고 있음</p>
<p>각 가용 영역에 탄력적 IP 할당 가능
=&gt; IP를 Elastic IP로 고정할 수도 있고, 아니면 AWS가 주는 고정 IP를 쓸 수도 있음</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/81e6759c-c19f-4152-a3ac-5b24bb2cea23/image.png" alt=""></p>
<p>❓고정 IP의 장점?</p>
<ol>
<li><p>NLB가 중단되거나 교체될 때마다 IP 주소를 변경할 필요가 ❌ IP 주소가 고정되어 있기 때문에 클라이언트는 항상 동일한 IP 주소를 통해 액세스 가능</p>
</li>
<li><p>DNS(Domain Name System) 구성을 간소화</p>
</li>
<li><p>NLB에는 SSL/TLS 인증서를 적용할 수 있음. 고정 IP를 사용하면 인증서를 한 번만 구매하고 설치한 후에도 IP 주소 변경 없이 계속 사용할 수 있음</p>
</li>
<li><p>방화벽 또는 보안 그룹과 같은 보안 정책을 쉽게 적용할 수 있음. IP 주소가 변경되지 않기 때문에 정책을 설정하거나 업데이트할 때마다 변경 작업이 필요하지 않음</p>
</li>
<li><p>고정 IP를 사용하면 다른 서비스와의 통합 및 구성 관리도 단순화</p>
</li>
</ol>
<br/>

<h3 id="nlb의-동작방식">NLB의 동작방식</h3>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/7e542d5a-e097-470a-bc3c-7d44c5cc84ee/image.png" alt=""></p>
<ol>
<li><p>DNS → NLB IP 선택</p>
</li>
<li><p>클라이언트 → NLB 연결 맺기</p>
</li>
<li><p>NLB가 타깃(EC2/IP) 선택</p>
</li>
<li><p>NLB ↔ 타깃(EC2) 간 트래픽 전달</p>
</li>
</ol>
<br/>

<ul>
<li>대상그룹</li>
</ul>
<ol>
<li><p>EC2 인스턴스</p>
</li>
<li><p>IP 주소 → 하드코딩된 IP주소 혹은 프라이빗 IP (인스턴스와 자체 서버를 로드밸런서 타겟 그룹으로 등록한다면 )</p>
</li>
<li><p>ALB 앞에 배치 가능</p>
</li>
</ol>
<p><strong>NLB를 통해 고정 IP 주소</strong>를 얻을 수 있고 이후 ALB로 <strong>HTTP 유형의 트래픽을 처리하는 모든 규칙들 사용</strong> 가능</p>
<br/>

<ul>
<li><p>NLB가 지원하는 상태 체크(Health Check)</p>
<ol>
<li><p>TCP =&gt; 네트워크/포트 레벨 살아있음”만 보는 가장 기초적인 체크</p>
</li>
<li><p>HTTP</p>
</li>
<li><p>HTTPS</p>
</li>
</ol>
</li>
</ul>
<p>  백엔드 애플리케이션이 HTTP/HTTPS로 응답할 수 있다면, TCP보다 HTTP/HTTPS 헬스 체크로 더 정확한 상태 확인이 가능</p>
<hr>
<h3 id="alb-실습">ALB 실습</h3>
<p>  <img src="https://velog.velcdn.com/images/poala_0217/post/45978ebc-036e-44cf-a324-1fc4c6d70899/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/7f55b9f1-5611-4b46-9086-4909917014eb/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/c4397723-2c9b-4a83-be1f-a9bc9a8cabf0/image.png" alt=""> AZ마다 AWS에서 고정 IP 주소 할당 / EIP(Elastic IP)가 있으면 EIP 할당 가능</p>
<p>NLB를 위한 SG(Secuirty Group) 만들기 
<img src="https://velog.velcdn.com/images/poala_0217/post/dca4e6f8-b890-4683-8b78-a01125fed131/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/8a7a03a6-8484-4d5d-9b1a-169e2194b081/image.png" alt=""></p>
<p>새로 생성한 SG 그룹 적용해주기</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/a5ef7b72-a974-402c-b4c9-856c4ce53cf2/image.png" alt=""></p>
<p>새로운 대상 그룹(Target Group) 만들어주기</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/1bb0aaf2-2722-4004-b7d8-29c7a8e04316/image.png" alt=""></p>
<p>다시 NLB 생성화면으로 돌아오기</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/f93bc2f6-aa6a-4517-83cd-3f102eaf75a9/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/2583a92a-2be2-4447-a5fb-9e0a13cadd8f/image.png" alt=""></p>
<p>생성 완료!</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/5743446e-4869-4052-8f8d-aec68b7d0623/image.png" alt=""></p>
<p>생성된 NLB의 DNS Name으로 접속해보니 타임아웃 발생</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/d587cda7-720a-49f9-825d-b3981d470b5f/image.png" alt=""></p>
<p>인스턴스의 SG 설정을 살펴보니 HTTP가 앞전에 설정해둔 ALB 보안그룹만 허용되어 있다</p>
<p>NLB 보안그룹도 추가해주자! </p>
<p>❓WHY ?
=&gt; 네트워크 로드 밸런서에서는 밸런서의 보안 그룹을 정의하지 않는다
=&gt; 네트워크 로드 밸런서로 들어온 모든 트래픽이 곧장 EC2 인스턴스로 들어간다
=&gt; 들어온 트래픽을 허용할지 말지는 EC2 인스턴스 보안그룹이 정한다</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/4254670e-138a-4644-97c5-7388c002d3d1/image.png" alt=""></p>
<p>다시 대상그룹(Target Group)을 살펴보면 Healthy라고 출력되는 것 확인 가능!
<img src="https://velog.velcdn.com/images/poala_0217/post/259cf7d8-9e0f-4d7d-a383-8b920d64e94e/image.png" alt=""></p>
<p>DNS Name 주소로 접근하면 </p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/1a016ab3-9df2-4087-a7a7-b06435463320/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/0606df61-4ebb-4cc0-8bad-000de4fb37ad/image.png" alt=""></p>
<p>잘 연결됨을 확인할 수 있다!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS DVA 항해기 - ELB + ASG - ALB]]></title>
            <link>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-ALB</link>
            <guid>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-ALB</guid>
            <pubDate>Sat, 15 Nov 2025 06:51:51 GMT</pubDate>
            <description><![CDATA[<h2 id="alb">ALB</h2>
<p>URL, Host, 헤더, 메서드 같은 “HTTP 내용”을 보고
어떤 Target으로 보낼지 세밀하게 골라주는 <strong>L7 HTTP 전용 로드 밸런서</strong></p>
<p>클라이언트 ←→ ALB(공개 IP/도메인) ←→ Target Group(EC2, ECS, Lambda, IP 등)</p>
<ul>
<li><p><strong>WebSocket, HTTP/2 지원</strong></p>
<p>BUT HTTP/2 위에서 WebSocket를 돌리는게 아님</p>
<p>ALB에서 HTTP/2는 클라이언트 ↔ ALB 구간에서만 지원</p>
<p>[브라우저] -- HTTP/2 --&gt; [ALB] -- HTTP/1.1 --&gt; [EC2/ECS 등]</p>
<p>ALB는 평범한 HTTP 요청에 대해선 HTTP/2를 지원하고, 별도로 WebSocket 연결도 지원</p>
</li>
</ul>
<ul>
<li><p><strong>리다이렉트(클라이언트에게 다른 URL로 가라고 응답) 지원</strong></p>
<p>ALB Listener Rule의 Action(동작) 중 하나</p>
</li>
</ul>
<p>  동작 방식:</p>
<ol>
<li><p>ALB가 요청을 받음</p>
</li>
<li><p>Rule 조건(Host, Path 등)에 매치됨</p>
</li>
<li><p>Target Group으로 안 보내고, 브라우저한테 3xx 응답 + Location 헤더를 돌려줌</p>
</li>
<li><p>브라우저가 그 Location으로 다시 요청을 보냄</p>
</li>
</ol>
<p>  예시) </p>
<p>  <img src="https://velog.velcdn.com/images/poala_0217/post/2de781cc-6a3b-440b-9268-873dffa92e4b/image.png" alt=""></p>
<ul>
<li><p><strong>경로 라우팅 지원</strong></p>
<p>URL의 “경로(Path)”를 보고 어떤 Target Group으로 보낼지 결정하는 기능</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/e095ef77-d1a2-44fc-ab88-a3f02c842cf8/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/c63007a6-ef77-4c7f-a317-6db7831c4cb1/image.png" alt=""></p>
<p>호스트 이름에 기반한 라우팅도 가능
<img src="https://velog.velcdn.com/images/poala_0217/post/bdaeccb9-9374-44f0-ad90-37701f08a002/image.png" alt=""></p>
</li>
</ul>
<ul>
<li>쿼리 문자열 &amp; 헤더 기반한 라우팅 지원
<img src="https://velog.velcdn.com/images/poala_0217/post/8e0146a7-1677-4140-9f9b-4bdcb313f24a/image.png" alt=""></li>
</ul>
<br/>

<p style="font-size:22px;font-weight:bold">ALB는 마이크로서비스와 컨테이너 기반 애플리케이션에 가장 좋은 로드밸런서 ‼️</p>

<p>포트 매핑 기능이 있어서 EC2 인스턴스의 동적 포트로의 리다이렉션을 가능하게 함</p>
<h3 id="alb의-타겟-그룹">ALB의 타겟 그룹</h3>
<ol>
<li>EC2 인스턴스(오토 스케일링 그룹으로 관리될 수 있음)</li>
<li>ECS 작업</li>
<li>Lambda 함수</li>
<li>IP 주소 =&gt; 사설 IP 주소여야만 함</li>
</ol>
<p>ALB는 여러 대상 그룹으로 라우팅 할 수 있으며</p>
<p>Health Check(상태 확인)은 대상 그룹 레벨에서 이루어짐</p>
<hr>
<h2 id="alb-실습">ALB 실습</h2>
<ul>
<li><p>ALB 생성
<img src="https://velog.velcdn.com/images/poala_0217/post/8c1e56f1-5f6b-4609-9f7d-4fc1b3b684da/image.png" alt="">
HTTP, HTTPS가 허용된 SG를 적용한 인스턴스 2개를 생성해준다</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/51018b79-3ad4-4a0b-b069-66e19b627e8d/image.png" alt="">
<img src="https://velog.velcdn.com/images/poala_0217/post/7abf0c02-18c5-4143-b48a-fb3437e029a6/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/368b37e8-d6d1-4192-b716-3432945f6a7b/image.png" alt=""></p>
<p>얼마나 되는 가용 영역에 로드밸런서를 배포할지 정해야 함</p>
<p>Security groups를 설정할 차례인데 HTTP 트래픽만 허용하는 SG 그룹 생성</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/fe9f0cf8-46f4-4e9d-be54-79db3611d09c/image.png" alt="">
<img src="https://velog.velcdn.com/images/poala_0217/post/b466b8be-9f26-4fe2-8bed-2088139adb5a/image.png" alt=""><img src="https://velog.velcdn.com/images/poala_0217/post/b81ff87b-bbca-4f3e-b36b-68c710a3e868/image.png" alt="">
<img src="https://velog.velcdn.com/images/poala_0217/post/7bb38a18-5cbe-42c6-8b40-83804f11166b/image.png" alt="">
다음 버튼을 클릭하면</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/abf26c9d-6016-4d9e-95f1-d64d9108339f/image.png" alt=""></p>
<p>Include as pending below 클릭</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/421c1fad-597c-40f8-9374-c793a71d22ec/image.png" alt="">
다시 ALB 생성 화면으로 넘어오면</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/48a467d0-9316-4bba-858b-057a45a86784/image.png" alt=""></p>
<p>80 포트에 있는 로드 밸런스의 리스너와 연결
<img src="https://velog.velcdn.com/images/poala_0217/post/dfc1103a-69e0-4079-8933-c25b707a3ac1/image.png" alt=""></p>
<p>생성하고 ALB가 active된 상태가 되면 DNS name이 부여되는데
<img src="https://velog.velcdn.com/images/poala_0217/post/a4911721-68a4-44a5-9f60-6a2c9b725556/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/8c8f3990-870d-4dd7-9988-a0be015a80a6/image.png" alt="">새로고침시마다 ALB에서 리다이렉션 해주는 인스턴스가 다름을 확인할 수 있다</p>
</li>
</ul>
<br/>

<ul>
<li><p>EC2    인스턴스에 로드밸런서를 통해서만 액세스하게 하는 법</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/9f918b56-75b5-470c-bb31-6ccac91d39c1/image.png" alt=""></p>
<p>EC2 인스턴스에 연결된 SG로 가서 Edit Inbound rules 클릭</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/0b1db0de-6c39-43d6-a810-c36cf0aa7007/image.png" alt=""></p>
<p>ELB의 SG 접근만 허용하도록 선택</p>
<p>적용 후 EC2 Public Address로 접근하려고 하면 타임아웃 발생</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/f6d036af-d53d-4646-9bab-a4881bf5c384/image.png" alt=""></p>
<p>하지만 로드밸런서의 DNS Name 주소로 접근하면</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/b75ee526-ca01-4ac5-84bc-17703e70be92/image.png" alt=""></p>
<p>정상작동</p>
<br/>
</li>
<li><p>애플리케이션 밸런서 규칙</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/b4834658-979d-4fbb-805f-2e3d5a647970/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/5b79e8c1-8582-49bd-ba4a-8e21d410a8e6/image.png" alt=""> 모든 요청이 demo-tg-alb로 보내지게 되어있음
Add Rule 버튼을 클릭해서 더 복잡하게 설정 가능</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/1d71c49f-d9dc-4d56-9161-22b4931a5d58/image.png" alt=""> Conditions =&gt; 무엇을 요청의 필터로 사용할 것인지 선택</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/d4c22ebf-64a5-45cd-a55c-7b221a2c6552/image.png" alt=""> 우선 난 Path로 선택하고 /error일 때 요청이 보내지도록 Rule 추가</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/85ddd48a-acb7-4431-be67-87a2d7f40872/image.png" alt=""> 그 다음으로는 조건이 맞는다면 어떤 액션을 취할지 정의해야 함
난 여기서 Return fixed response =&gt; 404 =&gt; Not Found, custom error!를 지정하겠다</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/99961e90-51b0-4aaa-ac39-a0136552878a/image.png" alt=""> 규칙이 여러개일 수 있기 때문에 우선순위를 정해줘야 함! 1이 가장 높은 우선순위!!</p>
<p>규칙을 적용하고 나서 다시 DNS name값을 복사하고 끝에 &quot;/error&quot;를 붙여주면</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/d31ed8e0-2f4c-4a9b-a43f-09d34e9c248a/image.png" alt=""></p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/b2039b19-ef0a-4b52-bc76-13421b31988c/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS DVA 항해기 - ELB + ASG - ELB]]></title>
            <link>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-ELB</link>
            <guid>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-ELB-ASG-ELB</guid>
            <pubDate>Thu, 13 Nov 2025 14:05:38 GMT</pubDate>
            <description><![CDATA[<details>
  <summary>
    <span style="font-weight:bold;font-size:22px">고가용성 & 확장성</span></summary>
  <div>
  확장성과 고가용성은 서로 연결되어 있긴 하지만 엄연히 다른 개념

<p>  <span style="font-weight:bold">확장성(Scalability)</span> =&gt; 부하(트래픽)가 늘어날 때, 성능을 유지하기 위해 시스템 리소스를 늘릴 수 있는 능력</p>
<p>확장성의 2가지 종류</p>
<ol>
<li><p><strong>수직</strong> 확장(Vertical Scailability)</p>
<ul>
<li><p>인스턴스의 크기를 확장하는 것 = 더 큰 머신으로 바꾸는 것
ex) EC2 t3.medium → m5.4xlarge 로 교체</p>
<p>데이터베이스와 같이 분산되지 않은 시스템에서 흔히 사용
RDS, ElastiCache 등의 데이터베이스에서 쉽게 찾을 수 있음</p>
</li>
<li><p>구조는 그대로, “<U><strong>몸집</strong></U>만 키우는” 방식</p>
</li>
<li><p>장점: 구조가 단순하고 애플리케이션 코드를 거의 건드리지 않아도 됨</p>
</li>
<li><p>단점: 확장할 수 있는 정도에 한계가 있다</p>
</li>
</ul>
</li>
</ol>
<br/>

<ol start="2">
<li><p><strong>수평</strong> 확장(Horizontal Scailability = elasticity)</p>
<ul>
<li>애플리케이션에서 인스턴스나 시스템의 수를 늘리는 방법 = 분배 시스템 
ex) EC2 여러 대 + ALB
ECS/EKS에서 Task/Pod 수를 늘리기
RDS Read Replica 여러 개 만들어 읽기 분산</li>
</ul>
<p>웹이나 현대적 애플리케이션은 대부분 분배 시스템</p>
</li>
</ol>
 <br/>

<pre><code>&lt;span style=&quot;font-weight:bold&quot;&gt;고가용성&lt;/span&gt;</code></pre><p>   =&gt; 장애가 나도 서비스가 계속 살아있도록 만드는 설계
   =&gt; 애플리케이션 또는 시스템을 적어도 둘 이상의 AZ나 데이터 센터에서 가동
    <br/> 
    <br/>
왜 필요한가?</p>
<ul>
<li><p>서버, 디스크, 네트워크, AZ… 뭐든 언제든 죽을 수 있음 그럼에도 불구하고 서비스는 계속 돌아가야 함</p>
</li>
<li><p>“한 개가 죽어도 다른 시스템이 대신 일하도록” 만드는 게 HA 설계</p>
</li>
</ul>
<hr>
<p>EC2</p>
<ul>
<li><p>수직 확장 (인스턴스의 크기를 늘리는 것)</p>
<ul>
<li><p>수평 확장(오토 스케일링 그룹 &amp; 로드 밸런서에도 적용 가능한 개념)</p>
<ul>
<li>스케일 인 =&gt; 인스턴스 수가 줄어드는 것</li>
<li>스케일 아웃 =&gt; 인스턴스 수가 늘어나는 것</li>
</ul>
</li>
</ul>
</li>
<li><p>고가용성</p>
<ul>
<li>다중 AZ가 활성화된 오토 스케일링 그룹</li>
<li>다중 AZ가 활성화된 로드 밸런서</li>
</ul>
</li>
</ul>
  </div>
</details>

<hr>
<h2 id="로드-밸런싱load-balancing">로드 밸런싱(Load Balancing)</h2>
<h3 id="❓-로드-밸런서">❓ 로드 밸런서</h3>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/8e6c61ef-8ed3-4d0f-8a4e-94dd2c88b17f/image.png" alt=""></p>
<h4 id="❔-로드-밸런서load-balancer가-하는-일">❔ 로드 밸런서(Load Balancer)가 하는 일</h4>
<p> <strong>“트래픽 분배기 + 보안관 + 건강검진기”</strong> 역할을 함
<br/></p>
<ol>
<li><p>트래픽 분배</p>
<ul>
<li>사용자의 요청(HTTP, HTTPS, TCP 등)을 받아서</li>
</ul>
<p>뒤에 있는 여러 EC2 인스턴스(= Target/Backend)에게 나눠줌</p>
</li>
<li><p>Health Check (헬스 체크)</p>
<ul>
<li><p>인스턴스 상태를 주기적으로 체크</p>
</li>
<li><p>죽어 있으면 그 서버로는 더 이상 트래픽 안 보냄 =&gt; 한 서버가 죽어도 서비스는 계속 동작 (고가용성)</p>
</li>
</ul>
</li>
</ol>
<ol start="3">
<li><p>스케일링과 궁합</p>
<ul>
<li><p>Auto Scaling Group이 인스턴스를 늘리거나 줄이면,</p>
</li>
<li><p>로드 밸런서가 그 인스턴스들을 자동으로 붙였다 떼었다 하면서 트래픽 분배  </p>
</li>
</ul>
</li>
</ol>
<ol start="4">
<li><p>단일 진입점 (Single Point of Access)</p>
<ul>
<li><p>사용자는 로드 밸런서의 DNS 이름 하나만 알고 접속 =&gt; 사용자는 본인이 어떤 인스턴스에 연결되었는지 알 수 ❌</p>
</li>
<li><p>그 뒤에 서버가 몇 대든, 어떤 AZ에 있든 상관 없음
→ IP 바뀌는 개별 EC2 대신, 고정된 접점이 되어 줌</p>
</li>
</ul>
</li>
</ol>
<ol start="5">
<li><p>보안/암호화 처리 역할 → SSL 종료</p>
<p>클라이언트와 HTTPS 연결을 로드 밸런서에서 종료</p>
<p>= SSL/TLS Termination / Offloading</p>
<ul>
<li><p>인증서를 로드 밸런서에서 관리하고,
백엔드에는 HTTP로 넘기거나 다시 HTTPS로 재암호화해서 넘김</p>
</li>
<li><p>효과:</p>
</li>
</ul>
<p>개별 서버에서 TLS 설정/인증서 관리 안 해도 됨</p>
<p>암복호화 부담을 LB가 떠안아서 백엔드 부담↓</p>
<p>필요하다면 end-to-end 암호화도 구성 가능 (LB ↔ 백엔드도 HTTPS)</p>
<br/>

</li>
</ol>
<h4 id="❔-로드-밸런서가-필요한-이유">❔ 로드 밸런서가 필요한 이유</h4>
<ul>
<li><p>부하를 다수의 다운스트림 인스턴스로 분산하기 위해</p>
</li>
<li><p>하나의 액세스 포인트를 노출하기 위해</p>
</li>
<li><p>다운스트림 인스턴스의 오류를 핸들링하기 위해 &amp; 헬스체크</p>
</li>
<li><p>SSL 종료를 제공</p>
</li>
<li><details>
<summary>쿠키로 고정도 강화</summary>
<div>
  고정도(affinity / stickiness) => 같은 클라이언트(브라우저)에서 오는 요청을 계속 같은 백엔드 인스턴스로 보내 주는 정도


</li>
</ul>
<pre><code>고정도를 만드는 방법은 여러 가지인데, 대표적으로:

1. IP 기반: 같은 클라이언트 IP면 같은 서버로 보내기

2. 쿠키 기반: 브라우저에 심어둔 쿠키 값으로 같은 서버로 보내기
=&gt; “쿠키로 고정도를 강화할 수 있다”는 말은</code></pre><p>  → IP만 믿지 말고, 쿠키를 사용해서 더 안정적으로 “같은 서버로 묶어라” 라는 의미</p>
<pre><code>Why❓

➡️ IP는 바뀔 수 있음
모바일, 4G/5G, 회사 프록시, NAT 뒤에 있을 때</code></pre><p>  여러 사용자가 같은 공인 IP를 공유하기도 함</p>
<p>  반면 쿠키는 브라우저 단위로 저장됨</p>
<p>  그 브라우저에서 오는 요청엔 항상 같은 쿠키가 딸려옴
  → 훨씬 “누가 누군지”를 안정적으로 구분 가능</p>
<p>  “고정도(affinity)를 강화한다 = 한 사용자를 더 정확하게 같은 서버에 붙여준다”</p>
<pre><code>---</code></pre><p>  Example)</p>
<pre><code>예를 들어 ALB + EC2 구조에서:

사용자가 브라우저로 https://example.com 접속

로드 밸런서(ALB) 가 첫 요청을 서버 A로 보냄

이때 ALB가 특정 쿠키(예: AWSALB, AWSALBTG 같은 LB 쿠키) 를 응답에 실어 브라우저에 내려줄 수 있어

이후 요청에서 브라우저는 항상 그 쿠키를 붙여서 요청함

ALB는 쿠키를 보고 “아, 이 쿠키는 서버 A로 붙어 있던 애네?” 하고</code></pre><p>  → 계속 서버 A로 라우팅</p>
  </div>
</details>



<ul>
<li>영역에 걸친 고가용성을 가짐</li>
<li>클라우드 내에서 개인 트래픽과 공공 트래픽을 분리 가능</li>
</ul>
<br/>

<h4 id="elb를-사용하는-이유">ELB를 사용하는 이유?</h4>
<ol>
<li><p>운영 부담 줄어드는 AWS 관리형 서비스</p>
<p>직접 로드 밸런서(Nginx, HAProxy, keepalived 등)를 구축하면:</p>
<p>설치, 설정, 패치, 모니터링, 장애 대응, 스케일링까지 전부 내가 해야 함</p>
<p>ELB는 fully managed:</p>
<p>OS, 소프트웨어 패치, 스케일링, 고가용성 설계 등을 AWS가 맡음
→ 운영(운영 인력·시간) 비용이 줄어든다
→ 시험 키워드: “undifferentiated heavy lifting을 AWS가 대신해준다”</p>
</li>
</ol>
<ol start="2">
<li>ELB가 다른 AWS 서비스들이랑 붙어서 ‘세트로’ 동작하도록 설계돼 있다<ul>
<li>EC2, EC2 Auto Scaling Groups, Amazon ECS</li>
<li>AWS Certificate Mananger(ACM), CloudWatch</li>
<li>Route 53, AWS WAF, AWS Global Accelerator</li>
</ul>
</li>
</ol>
<br/>


<h4 id="elb의-health-check">ELB의 Health Check</h4>
<p>실제 애플리케이션 레벨로 두드려 보는 것</p>
<ol>
<li><p>포트</p>
<p> 타겟 인스턴스(EC2 등)에서 어느 포트로 요청을 보낼 건지</p>
<ul>
<li>EC2가 80포트에서 웹 서버 실행 중이면</li>
</ul>
<p>=&gt;  Health Check Port = 80</p>
</li>
</ol>
<ul>
<li><p>앱 서버가 8080포트에서만 떠 있으면</p>
<p>=&gt; Health Check Port = 8080</p>
</li>
</ul>
<p>*
traffic port 로 하면</p>
<p> =&gt; Target Group에 설정된 포트(예: 80, 443 등)를 그대로 따라감</p>
<p>  그래서 “포트로 Health Check를 한다” =</p>
<p>  “ELB가 <strong>각 타겟의 지정된 포트에 직접 접속해서 확인</strong>한다”는 뜻</p>
<br/>

<ol start="2">
<li><p>라우트</p>
<p>특정 URL 경로(라우트)”로 GET을 날려 보고 응답 코드로 판별</p>
<p>예시:</p>
<ul>
<li>Health check path: /</li>
</ul>
</li>
</ol>
<ul>
<li><p>Health check path: /health</p>
<ul>
<li><p>Health check path: /status</p>
</li>
<li><p>Health check path: /actuator/health (Spring Boot 같은 거)</p>
</li>
</ul>
</li>
</ul>
<pre><code class="language-text">http://타겟IP:포트/health

  http://10.0.1.23:8080/health</code></pre>
<p>응답값이 200~399 → Healthy / 500, 타임아웃 등 → Unhealthy</p>
<br/>


<h3 id="aws의-관리형-로드-밸런서-종류">AWS의 관리형 로드 밸런서 종류</h3>
<ol>
<li>CLB(2009) - v1<ul>
<li>HTTP, HTTPS, TCP, SSL, secure TCP 지원</li>
</ul>
</li>
</ol>
<ol start="2">
<li><p>ALB(2016) -v2</p>
<ul>
<li>HTTP, HTTPS, WebSocket 프로토콜 지원</li>
</ul>
</li>
<li><p>NLB(2017) - v2</p>
<ul>
<li>TCP, TLS(secure TCP), UDP 프로토콜 지원</li>
</ul>
</li>
<li><p>GWLB(Gateway Load Banlancer: 2020)</p>
<ul>
<li>3계층(네트워크 레이어에서 동작) - IP 프로토콜에서 작동</li>
</ul>
</li>
</ol>
<br/>

<h3 id="load-balancer-security-groups">Load Balancer Security Groups</h3>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/0d67b949-b50e-4bae-bdfc-6cd6963bd92f/image.png" alt=""></p>
<p>EC2의 Security Groups Rule은 포트 80 HTTP 트래픽 &amp; 소스는 IP 범위가 아닌 LB의 SG가 된다. </p>
<p>→ EC2 인스턴스는 Load Balancer에서 온 트래픽만을 허용하게 되는 강화된 보안 메커니즘이 되는 것</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS DVA 항해기 - EC2 인스턴스 스토리지 - EBS vs EFS]]></title>
            <link>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80-EBS-vs-EFS</link>
            <guid>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80-EBS-vs-EFS</guid>
            <pubDate>Tue, 11 Nov 2025 09:49:22 GMT</pubDate>
            <description><![CDATA[<h3 id="ebs">EBS</h3>
<ul>
<li><p>한번에 하나의 인스턴스만 연결할 수 있다(multi-attach(다중 연결)가 되는 io1/io2 제외)</p>
</li>
<li><p>AZ(Availability Zone)에 고정됨</p>
</li>
<li><p>EBS의 gp2 볼륨은 디스크 크기가 증가해야 IO가 증가 BUT gp3, io1 볼륨 유형은 디스크 크기와 무관하게 IO 증가 가능</p>
</li>
<li><p>EBS에서 AZ간에 볼륨을 옮기려면 스냅샷을 이용해야 함
  =&gt; 스냅샷을 생성 후 다른 AZ에 복원하기</p>
</li>
<li><p>EBS 볼륨 백업이 IO를 사용하므로 애플리케이션이 많은 트래픽을 처리하고 있을 경우에는 실행하면 안 됨 =&gt; 성능에 영향을 줄 수 있기 때문</p>
</li>
</ul>
<ul>
<li>EC2 인스턴스가 종료되면 기본적으로 인스턴스의 EBS 루트 볼륨도 종료됨 =&gt; 이는 설정에서 비활성화 가능</li>
</ul>
<h3 id="efs">EFS</h3>
<ul>
<li><p>서로 다른 가용 영역의 수백 개의 인스턴스에 연결 가능
=&gt; 하나의 EFS 파일 시스템으로 다른 여러 mount(탑재) 대상을 가질 수 있다
=&gt; 여러 인스턴스가 하나의 파일 시스템을 공유할 수 있다</p>
</li>
<li><p>WordPress 사용시 매우 유용하고 리눅스 인스턴스에서만 사용 가능</p>
<ul>
<li>가격
EFS가 EBS보다 비싼 편이지만 비용 절감을 위해 EFS-IA 활용 가능 </li>
</ul>
</li>
</ul>
<h3 id="인스턴스-스토어">인스턴스 스토어</h3>
<p> 물리적으로 EC2 인스턴스에 연결 =&gt; 인스턴스가 없어지면 스토리지 또한 잃음</p>
<hr>
<h3 id="ebs-vs-efs-vs-ec2-인스턴스-스토어-표로-정리">EBS vs EFS vs EC2 인스턴스 스토어 표로 정리</h3>
<table>
<thead>
<tr>
<th>항목</th>
<th><strong>EBS</strong></th>
<th><strong>EFS</strong></th>
<th><strong>EC2 Instance Store</strong></th>
</tr>
</thead>
<tbody><tr>
<td>스토리지 타입</td>
<td><strong>블록 스토리지</strong> (디스크)</td>
<td><strong>네트워크 파일 스토리지</strong> (NFS 파일 시스템)</td>
<td><strong>로컬 블록 스토리지</strong> (호스트 물리 디스크)</td>
</tr>
<tr>
<td>어디에 붙는지</td>
<td>특정 <strong>EC2 인스턴스에 디스크처럼 연결</strong></td>
<td>여러 <strong>EC2 인스턴스에서 공유 마운트</strong></td>
<td>EC2 인스턴스가 올라가는 <strong>물리 서버에 직접 연결</strong>된 디스크</td>
</tr>
<tr>
<td>데이터 지속성 (인스턴스 종료 시)</td>
<td>인스턴스 <strong>중지/시작, 종료 후에도</strong> 볼륨만 안 지우면 데이터 유지</td>
<td>EFS는 EC2와 독립된 서비스 → 인스턴스와 상관없이 <strong>계속 유지</strong></td>
<td><strong>인스턴스 stop/terminate, 호스트 장애 나면 데이터 날아감</strong> (ephemeral)</td>
</tr>
<tr>
<td>수명 주기</td>
<td>EC2와 <strong>느슨하게 연결됨</strong> (EC2 죽어도 EBS는 따로 존재)</td>
<td>EC2랑 완전 독립 서비스</td>
<td>특정 인스턴스 + 물리 호스트와 <strong>운명 공동체</strong> 느낌</td>
</tr>
<tr>
<td>범위 (스코프)</td>
<td><strong>AZ 단위</strong> (ap-northeast-2a 같은 AZ에 귀속, 같은 AZ 인스턴스만 붙일 수 있음)</td>
<td><strong>리전 단위(Regional)</strong>, 내부적으로 멀티 AZ 복제</td>
<td><strong>단일 호스트</strong> (같은 인스턴스 안에서만)</td>
</tr>
<tr>
<td>공유 여부</td>
<td>기본은 <strong>한 인스턴스에만 연결</strong> (일부 타입만 Multi-Attach로 여러 인스턴스 연결 가능하지만 제한적)</td>
<td>여러 인스턴스에서 동시에 <strong>읽기/쓰기 공유</strong></td>
<td>같은 인스턴스 내에서만 사용, <strong>다른 인스턴스랑 공유 불가</strong></td>
</tr>
<tr>
<td>성능 특성</td>
<td>저지연 블록 I/O, IOPS/Throughput 선택 가능 (gp3, io1/io2 등)</td>
<td>파일 단위 처리량/동시접속에 최적화, 자동으로 처리량 확장</td>
<td><strong>가장 빠른 스토리지 중 하나</strong> (호스트에 직접 붙은 NVMe/SSD라서)</td>
</tr>
<tr>
<td>용량 관리</td>
<td><strong>미리 용량 프로비저닝</strong> (예: 100GiB), 나중에 크기/IOPS 조정 가능</td>
<td>저장된 데이터 양에 따라 <strong>자동 확장/축소</strong> (서버리스 느낌)</td>
<td>인스턴스 타입이 제공하는 <strong>고정 용량</strong> (사용자가 크기 못 바꿈)</td>
</tr>
<tr>
<td>내구성/복제</td>
<td>AZ 내에서 자동 복제, 스냅샷으로 S3에 백업 가능</td>
<td>기본적으로 <strong>멀티 AZ 복제</strong>, 높은 내구성 및 가용성</td>
<td>물리 디스크 – 호스트 장애 나면 데이터 손실. AWS 차원의 자동 복제 없음</td>
</tr>
<tr>
<td>백업 방법</td>
<td><strong>EBS Snapshot</strong> (시험 단골 키워드)</td>
<td>AWS Backup, 데이터 복제/동기화 스크립트</td>
<td>직접 <strong>EBS/S3로 복사</strong>해야 함 (스냅샷 같은 기능 없음)</td>
</tr>
<tr>
<td>요금 구조</td>
<td>프로비저닝한 <strong>용량 + 성능(IOPS/Throughput)</strong> 기준 과금</td>
<td>사용한 <strong>저장 용량 + 요청량/처리량</strong> 기준 과금 (Standard/IA 등)</td>
<td>인스턴스 요금에 <strong>포함</strong>된 개념 (별도 스토리지 비용 X)</td>
</tr>
<tr>
<td>대표 사용 사례</td>
<td>- EC2 루트 볼륨(OS) <br> - RDS 같은 DB 직접 EC2에 설치 <br> - 트랜잭션 많은 애플리케이션</td>
<td>- 웹 서버 여러 대가 공유하는 정적 컨텐츠 <br> - 사용자 홈 디렉토리 <br> - 리눅스 NFS 기반 공유 스토리지</td>
<td>- 캐시, 버퍼, 임시 파일 <br> - 고성능이지만 <strong>유실돼도 되는 데이터</strong> (예: Redis 캐시, 일시적인 스크래치 공간)</td>
</tr>
<tr>
<td>지원 OS/프로토콜</td>
<td>EC2 OS에서 디스크로 인식 (리눅스/윈도우 둘 다)</td>
<td>리눅스 <strong>NFS(v4)</strong> 기반 (윈도우는 EFS 직접 X → FSx for Windows 사용)</td>
<td>EC2 내부에서 일반 디스크처럼 보임 (ext4/xfs 등)</td>
</tr>
<tr>
<td>관리 난이도</td>
<td>타입/용량/IOPS 등 설계 필요</td>
<td>파일시스템 하나 만들고 마운트, 용량 자동 관리</td>
<td>사이즈/내구성 조정 불가, 데이터 날아갈 수 있어서 <strong>애플리케이션 레벨 설계 필요</strong></td>
</tr>
</tbody></table>
<br/>

<hr>
<p>오답노트</p>
<p>Q. 여러분은 기본 저장소에 대해 310,000의 IOPS를 요구하는 고성능 데이터베이스가 있습니다. 다음 중 무엇을 추천해야 할까요?</p>
<span style="color:green">
1. EC2 인스턴스 스토어 사용</span>

<ol start="2">
<li><p>EBS gp2 드라이브 사용</p>
</li>
<li><p>EBS io1 드라이브 사용</p>
</li>
</ol>
<p><span style="color:red">4. EBS io2 Block Express 드라이브 사용</span></p>
<p>내가 고른 답: 4
정답: 1</p>
<p>1번을 고르지 않은 이유:
    DB처럼 중요한 데이터를 인스턴스를 종료하면 날아가는 인스턴스 스토어에 사용한다고? 라고 생각함</p>
<pre><code>DB 같은 “중요 데이터” → EBS(io1/io2)
Instance Store → 캐시/임시 데이터
“아니 DB를 인스턴스 스토어에 올리라고??” 라는 의문</code></pre><p>근데 이 문제는 “내구성”보다 <strong>“IOPS”라는 성능 조건</strong>에만 꽂혀 있는 문제</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS DVA 항해기 - EC2 인스턴스 스토리지 - EFS]]></title>
            <link>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80-EFS</link>
            <guid>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80-EFS</guid>
            <pubDate>Mon, 10 Nov 2025 23:56:23 GMT</pubDate>
            <description><![CDATA[<h2 id="efs">EFS</h2>
<p>같은 리전 내 여러 AZ에 배치된 EC2/ECS/EKS/Lambda가 NFS(2049)로 동시에 마운트하는 공유 파일시스템 / 다른 리전에서 직접 마운트는 불가</p>
<p>EC2는 서로 다른 AZ에 흩어져 있어도 된다</p>
<p>EFS는 “같은 리전” 안이라면 그 여러 AZ의 EC2들이 하나의 EFS를 함께(동시에) 마운트해 쓸 수 있다</p>
<p>   =&gt; 즉, 리전(Region) = 서울/도쿄 같은 “큰 구역”, AZ = 그 안의 서로 떨어진 데이터센터 묶음
  EFS는 “서울 리전”에 만들면 서울 리전의 AZ들(예: ap-northeast-2a, 2b, 2c) 어디에 있는 EC2든 같은 EFS 폴더를 공유할 수 있음</p>
<ul>
<li>특징<ul>
<li>가용성이 높다</li>
<li>확장성이 뛰어나다(자동으로 확장됨)</li>
<li>비싸다(EBS의 gp2 볼륨의 약 3배)</li>
<li>사용량에 따라 비용을 지불(프로비저닝 할 필요가 없음)</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/8de9dfe6-8a9e-4698-8e18-15bb7670743d/image.png" alt=""></p>
<p>다른 AZ에 위치한 인스턴스들을 EFS를 통해 동일한 네트워크 파일 시스템에 동시에 연결 가능</p>
<h4 id="use-case">Use Case</h4>
<ul>
<li>콘텐츠 관리</li>
<li>웹 서빙</li>
<li>데이터 공유</li>
<li>Wordpress</li>
</ul>
<p>EFS에 대한 액세스를 제어하려면 보안 그룹을 설정해야 함</p>
<p><span style="font-size:20px;background-color:yellow">💡 EFS는 윈도우가 아닌 <strong>Linux 기반 AMI</strong>와만 호환된다 ‼️</span></p>
<p>보안</p>
<ul>
<li>EFS는 저장되는 파일·메타데이터를 ‘미사용 상태(at rest)’에서 KMS 키로 자동 암호화할 수 있다
=&gt; 즉, 디스크에 얹힐 때는 암호문, EC2/ECS/EKS/Lambda가 읽을 땐 평문으로 보인다(자동 복호화)</li>
</ul>
<br/>


<h4 id="efs-퍼포먼스">EFS 퍼포먼스</h4>
<p>EFS는 수천 개의 NFS 클라이언트가 동시에 붙을 수 있고, 처리량도 10 GiB/s를 넘길 수 있으며, 저장 용량은 자동으로 페타바이트(PB) 규모까지 확장</p>
<p>EFS 성능은 크게 두 축으로 스케일 됨</p>
<ol>
<li><p>Performance mode (파일시스템 생성 시 결정)</p>
<ul>
<li>General Purpose: 대부분 워크로드, 낮은 지연(ex: 웹 서버, CMS)</li>
<li>Max I/O: 아주 많은 파일/클라이언트가 동시에 접근하는 대규모 분산 워크로드에서 총 처리량 극대화(지연 다소↑ 가능) (ex: 빅데이터, 미디어 처리)</li>
<li>암기: “동시성·파일 수가 엄청 많다” → Max I/O.</li>
</ul>
</li>
<li><p>Throughput mode (운영 중 변경 가능)</p>
<ul>
<li><p>Bursting(기본(1TB)): 저장 용량에 비례해 기본 처리량 + 버스트 크레딧 제공.</p>
<ul>
<li>데이터가 작은데 지속 고처리량이 필요하면 크레딧이 바닥날 수 있음</li>
</ul>
</li>
<li><p>Provisioned Throughput: 저장 용량과 무관하게 처리량을 고정 예약</p>
<ul>
<li>“작은 용량 + 지속 고성능”에 적합.</li>
</ul>
</li>
<li><p>Elastic Throughput: 워크로드 변동을 자동 추적해 처리량을 탄력 적용(운영 단순화, 사용량 기반 과금) =&gt; 워크로드를 예측하기 어려울 때 유용</p>
</li>
</ul>
</li>
</ol>
<ul>
<li><p>결정법</p>
<p>1) 평균적/보통 패턴 → Bursting(저렴·간편)</p>
<p>2) 작은 데이터 + 상시 고부하 → Provisioned</p>
<p>3) 예측 불가한 변동 → Elastic</p>
</li>
</ul>
<ol start="3">
<li><p>IOPS는 처리량에 종속</p>
<p>EFS는 블록 스토리지(EBS)처럼 “고정 IOPS”를 잡는 모델이 아님</p>
<p>작은 IO가 많으면 IOPS 수요가 커지고, 큰 IO는 처리량(Throughput) 한도에 더 민감</p>
<p>필요 시 Provisioned/Elastic로 처리량을 확보하고, 클라이언트 측 NFS 파라미터(rsize/wsize), 병렬성, 워커 수로 실효 IOPS를 끌어올림</p>
</li>
</ol>
<br/>  

<h4 id="efs-스토리지-클래스">EFS 스토리지 클래스</h4>
<p>? Storage tiers</p>
<p>=&gt; 파일 접근 빈도에 따라 다른 등급(클래스)로 자동 이동시키는 기능을 말하고, 며칠(정책) 후 IA/Archive로 내리거나, 접근 시 다시 Standard로 올리는 것까지 설정</p>
<ol>
<li><p>가용성(위치) 축 — “<strong>어디에</strong> 저장하느냐”</p>
<ul>
<li><p>Standard (Regional): </p>
</li>
<li><p>자주 액세스하는 파일을 위한 계층</p>
</li>
<li><p>다중 AZ 설정이 있는 경우 내구성·가용성 측면에서 볼 때 사용하는 것이 좋음</p>
</li>
<li><p>One Zone: </p>
</li>
<li><p>단일 AZ에 저장 → 더 저렴/낮은 지연 가능하지만 AZ 장애 리스크↑ (백업 필수 권장: 백업은 기본적으로 활성화하도록 설정되어 있음)</p>
</li>
<li><p>액세스 빈도가 낮은 스토리지 계층과 호환됨</p>
</li>
</ul>
</li>
<li><p>접근 빈도(Access) 축 — “<strong>얼마나 자주</strong> 읽히느냐”</p>
<ul>
<li><p>Frequent Access: 자주 접근하는 데이터에 맞춘 등급(기본)</p>
</li>
<li><p>IA (Infrequent Access): 
드물게 접근하는 파일용
요청/조회 비용(파일 검색) 비용이 발생하지만 저장하면 비용이 감소함
최소 보관 기간 요금(예: ~30일)이 적용될 수 있음</p>
</li>
</ul>
</li>
</ol>
<ul>
<li>Archive:
거의 액세스하지 않는 데이터용(1년에 몇 번 정도) 50% 정도 저렴</li>
</ul>
<p>전반적으로 올바른 EFS 스토리지 클래스를 사용하면 최대 90%의 비용 절감 가능</p>
<hr>
<h2 id="efs-실습">EFS 실습</h2>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/22ce9ad6-5a2b-494d-954b-a071fd37ed64/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/5a29a61e-45eb-485b-a5d4-2feaafb5c20a/image.png" alt=""></p>
<p>VPC는 default로 진행하되 Customize로 옵션을 살펴보겠다</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/dc14224c-caca-410e-b984-37babc64ecb6/image.png" alt=""></p>
<p>Regional을 선택하면 다중 AZ가 지원된다</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/8121f4f9-07bc-4023-a381-71d5791f9c1b/image.png" alt=""></p>
<p>하지만 One Zone을 선택하면 AZ를 하나 특정해야 함</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/14367b89-8095-461e-8e9f-2782ad20901f/image.png" alt=""></p>
<p>백업은 활성화된 채로 유지하는 것이 좋음</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/c5046ce8-7442-4f86-aeb7-524a039ec851/image.png" alt=""></p>
<p>IA나 아카이브로 전환했다가 다시 스탠다드로 전환 가능</p>
<p>ex) 30일동안 파일에 액세스 하지 않으면 IA로 이동 / 90일동안 액세스하지 않으면 아카이브로 이동</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/07efa2aa-0ad6-4d88-ab62-5c36d418b7be/image.png" alt=""></p>
<p>Enhanced =&gt; elastic과 Provisioned을 그룹화하는 카테고리에 불과함</p>
<ul>
<li><p>Elastic: 트래픽에 맞춰 자동으로 처리량을 확장/과금(스파이크/예측 어려운 워크로드에 적합)</p>
</li>
<li><p>Provisioned: 용량과 무관하게 처리량을 고정 예약(지속 고처리량, 예측 가능한 워크로드)</p>
</li>
<li><p>Bursting: 파일시스템 크기와 버스트 크레딧에 비례해 처리량 제공(기본값, 단 단발성 피크 중심)</p>
</li>
</ul>
<details>
  <summary>EFS의 “버스트 크레딧(Burst Credits)”이란?</summary>
  <div>


<p>  Bursting 처리량 모드에서만 쓰이는 토큰 같은 개념이야.</p>
<p>  파일시스템마다 <strong>용량(저장한 데이터 양)</strong>에 비례한 <strong>기본 처리량(베이스라인)</strong>이 있음</p>
<p>  네 I/O가 이 베이스라인보다 낮게 쓰일 때는 크레딧이 쌓이고,
  베이스라인보다 높게 쓰고 싶을 때는 크레딧을 소모해서 일시적으로 더 빠르게 달릴 수 있어.</p>
<ul>
<li><p>흐름 요약</p>
<p>한가할 때(트래픽↓) → 베이스라인 이하 사용 → 크레딧 적립</p>
<p>바쁠 때(트래픽↑) → 베이스라인 초과 사용 → 크레딧 사용해 고처리량 버스트</p>
<p>크레딧 소진 → 다시 베이스라인 속도로 제한(성능이 확 느려진 느낌)</p>
<p>포인트: 저장 용량이 작을수록 베이스라인이 낮아 크레딧을 빨리 다 써버릴 수 있음</p>
<p>반대로 용량이 클수록(몇 TiB 이상) 베이스라인 자체가 높아 버스트 없이도 꽤 오래 빠르게 버틸 수 있음</p>
</div>
</details>



</li>
</ul>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/bb69f57d-0af6-4308-87b4-b1dbeabb8fd4/image.png" alt=""></p>
<p>us-ease-? 존에 대한 EFS 네트워크 설정</p>
<p>EFS를 위한 SG(Security Group) 만들어주기</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/e4922194-84d0-4a4c-b8b7-eec959013945/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/7270a259-eb70-4060-8e42-27b8889c62f4/image.png" alt=""></p>
<p>그 다음 단계들은 선택 사항이라서 건너뛰고 Create File system 클릭</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/b64c61f0-2cf7-425c-a244-2286bdeb29d9/image.png" alt=""></p>
<p>잘 생성된 것 확인 가능</p>
<p>EC2 인스턴스에 EFS를 연결해볼건데 Instance 생성시 </p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/d1597a3c-788b-4ee7-8d43-bb0de910423c/image.png" alt=""></p>
<p>우측 하단 부 &quot;Edit&quot; 버튼 클릭</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/114440ca-6aa8-4c81-a30d-f47794e9ec52/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/9d1c44f1-7824-4aff-96c1-9c4766b4e3de/image.png" alt=""></p>
<p>네트워크 설정에서 Subnet을 설정해줘야 EFS 연동 가능</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/18a5a299-6da3-4a2b-b2ea-496fe90dcc4b/image.png" alt=""></p>
<p>Instance A로 이름을 지어서 us-east-1a를 선택했다</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/94fd4f1d-036c-4f01-9300-0c833a2e3287/image.png" alt=""></p>
<p>Add shared file system 클릭</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/be5eaa8f-9ba2-4238-8bd8-3b8e57a21994/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/dfb92a82-7bb0-48a5-a430-992bf42e772b/image.png" alt="">
Automatically mount shared file system by attaching required user data script</p>
<p>=&gt; EC2를 띄울 때 “유저 데이터(User data) 스크립트”를 자동으로 붙여서 EFS를 부팅 시점에 알아서 마운트해 주는 옵션</p>
<p>유저 데이터 스크립트가 EC2 첫 부팅 때 자동 실행되어 아래 작업 실시</p>
<ol>
<li><p>필요 패키지 설치</p>
<p> amazon-efs-utils(또는 NFS 클라이언트) 설치</p>
</li>
<li><p>마운트 지점 준비</p>
<p> 예: mkdir -p /mnt/efs</p>
</li>
<li><p>마운트 수행(보통 TLS 포함)</p>
<p> 예: mount -t efs -o tls fs-XXXX:/ /mnt/efs</p>
<p> Access Point를 쓰면 fs-XXXX:AP-YYYY:/ 형태로 마운트</p>
<p> /etc/fstab 등록(부팅 시 자동 마운트)</p>
</li>
<li><p>재부팅해도 자동으로 붙도록 엔트리를 추가</p>
<p> 예: fs-XXXX:/ /mnt/efs efs _netdev,tls 0 0</p>
</li>
</ol>
<p>즉, 인스턴스를 만들자마자 사람이 SSH로 들어가서 설치/마운트 설정을 하지 않아도 되도록 자동화해 주는 “부팅 초기화 스크립트”</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/3724c07a-c9db-43bb-894a-b7ce80e7f2fe/image.png" alt=""></p>
<p>EFS를 붙여서 확실히 인스턴스 생성하는데 시간이 걸린다</p>
<p>같은 방식으로 Instance B를 만들어 같은 EFS를 연결</p>
<p>EFS의 네트워크 탭으로 가면</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/c6dd6ac2-59aa-435e-9f15-e4cccdbf99c8/image.png" alt=""></p>
<p>각 가용 영역에 여러 보안 그룹이 존재하는 것 확인 가능
=&gt; 우리가 연결한 efs-demo 말고도 EC2 콘솔이 대신 생성해 EFS 파일 시스템에 연결</p>
<p>EFS에서 “보안(시큐리티) 자동 설정” 체크 + 여러 AZ 선택 ⇒ 선택한 각 AZ의 서브넷마다 “마운트 타깃(ENI)”을 만들고, 그 ENI에 지정한 SG가 붙음</p>
<p>EC2 인스턴스를 us-east-1a/1b에만 띄웠더라도, EFS를 us-east-1의 다른 AZ(1c/1d …)까지 선택했다면 그 AZ들에도 마운트 타깃이 생성되고 동일/지정 SG들이 붙어 보이는 게 정상</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/ff9909e9-d9b3-433d-94b7-61f3e720a5f7/image.png" alt=""></p>
<p>efs-sg-2 SG 그룹 상세 &gt; Inbout rules를 확인하면 NFS 프로토콜 유형과 2049 포트 허용하는 것 확인 가능</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/7ca5643a-12f2-4b98-8948-1be9ed34ea56/image.png" alt=""></p>
<p>Instance A Connect &amp; Instance B Connect</p>
<p>Instance A로 Connect된 터미널 창에 다음과 같은 명령어 입력
<img src="https://velog.velcdn.com/images/poala_0217/post/e67da7de-94ce-47d9-9698-ed5d2f2c5b97/image.png" alt=""></p>
<p>EC2 인스턴스로부터 EFS 파일 시스템에 파일 생성 &amp; 가용 영역 us-east-1a</p>
<p>Instance B로 이동해서 아래와 같은 명령어를 입력하면 Instance A에서 생성한 파일을 찾을 수 있다</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/1624a136-0adc-462a-b447-195a3c6df148/image.png" alt=""></p>
<p>두 EC2 인스턴스 모두 EFS 파일 시스템이 네트워크 드라이브로 마운트 된 것</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS DVA 항해기 - EC2 인스턴스 스토리지 - EBS 볼륨 유형 + EBS 다중 연결]]></title>
            <link>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80-EBS-%EB%B3%BC%EB%A5%A8-%EC%9C%A0%ED%98%95-EBS-%EB%8B%A4%EC%A4%91-%EC%97%B0%EA%B2%B0</link>
            <guid>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80-EBS-%EB%B3%BC%EB%A5%A8-%EC%9C%A0%ED%98%95-EBS-%EB%8B%A4%EC%A4%91-%EC%97%B0%EA%B2%B0</guid>
            <pubDate>Sun, 09 Nov 2025 13:17:10 GMT</pubDate>
            <description><![CDATA[<h2 id="ebs-볼륨-종류">EBS 볼륨 종류</h2>
<p><span style="font-size:20px">1. gp3 (General Purpose SSD)</span></p>
<ul>
<li><p>용도: 웹/앱 서버, 중소형 DB 등 대부분의 일반 워크로드</p>
</li>
<li><p>특징: </p>
<ul>
<li>비용 효율 최고, 새 프로젝트의 사실상 기본값 / 부팅 가능(SSD)</li>
<li>IOPS와 처리량을 독립적으로 설정 가능</li>
</ul>
<ul>
<li>주의: 인스턴스의 EBS 대역폭 한도도 병목이 될 수 있음(인스턴스 스펙 고려)</li>
</ul>
</li>
</ul>
<p><span style="font-size:20px">2. gp2 (General Purpose SSD, 레거시)</span></p>
<ul>
<li><p>용도: 기존 레거시 워크로드 호환 / 시스템 부팅 볼륨, 가상 데스크톱, 개발 및 테스트 환경에 사용</p>
</li>
<li><p>특징: </p>
<ul>
<li><p>gp2는 레거시 취급이라 새로 선택하진 않음(점진적 gp3 전환 권장) / SSD 타입은 EC2의 루트 볼륨로 쓸 수 있음</p>
</li>
<li><p>비용 효율적인 스토리지이면서 낮은 대기시간을 제공</p>
</li>
<li><p>IOPS와 처리량이 서로 연결되어 있다</p>
</li>
</ul>
</li>
</ul>
<p><span style="font-size:20px">3. io1 (Provisioned IOPS SSD)</span></p>
<ul>
<li><p>용도: 지연 민감·트랜잭션성 DB(OLTP), I/O 집약 워크로드</p>
</li>
<li><p>특징: Multi-Attach 지원(io1/io2 전용) → 같은 AZ의 여러 인스턴스에 동시 연결(특수 파일시스템/클러스터링 전제) / 일부 리전 제약 있음</p>
</li>
<li><p>주의: 비용 높음. 부팅 가능(SSD)</p>
</li>
</ul>
<p><span style="font-size:20px">4. io2 (Provisioned IOPS SSD)</span></p>
<ul>
<li><p>용도: 미션 크리티컬 DB, 높은 내구성과 일관 I/O 필요</p>
</li>
<li><p>파생: io2 Block Express(초대형/초고성능 볼륨) 옵션</p>
</li>
<li><p>특징: 비용 높음, 부팅 가능(SSD)</p>
</li>
</ul>
<p><span style="font-size:20px">5. st1 (Throughput Optimized HDD)</span></p>
<ul>
<li><p>용도: 대용량 순차 I/O(로그 처리, 빅데이터, ETL 등) =&gt; 큰 파일을 길게/연속으로 읽고 쓰는 작업</p>
</li>
<li><p>특징: 부팅 불가(HDD), 랜덤 I/O/저지연에는 부적합 / 저비용 대용량 볼륨</p>
</li>
</ul>
<p><span style="font-size:20px">6. sc1 (Cold HDD)</span></p>
<ul>
<li>용도: 아주 드물게 접근하는 대용량 데이터(콜드/아카이브 성향)</li>
</ul>
<ul>
<li>특징: 부팅 불가(HDD), 최저 비용/최저 성능</li>
</ul>
<br/>

<p><span style="font-size:19px;font-weight:bold">HDD vs SDD</span></p>
<table>
<thead>
<tr>
<th>구분</th>
<th>HDD (예: <strong>st1</strong>, <strong>sc1</strong>)</th>
<th>SSD (예: <strong>gp3</strong>, <strong>gp2</strong>, <strong>io1</strong>, <strong>io2</strong>)</th>
</tr>
</thead>
<tbody><tr>
<td>동작 방식</td>
<td>기계식(회전+헤드 이동)</td>
<td>반도체(전자식)</td>
</tr>
<tr>
<td>지연시간(Latency)</td>
<td>큼(헤드 이동/회전 대기)</td>
<td>작음(즉시 접근)</td>
</tr>
<tr>
<td>랜덤 I/O (IOPS)</td>
<td>약함</td>
<td>강함</td>
</tr>
<tr>
<td>순차 처리량(Throughput)</td>
<td><strong>큰 파일 연속 처리에 유리</strong></td>
<td>충분히 좋지만 비용↑</td>
</tr>
<tr>
<td>내구성/충격 민감</td>
<td>기계식이라 상대적 약함</td>
<td>기계 부품 없어 유리</td>
</tr>
<tr>
<td>비용/GB</td>
<td><strong>저렴</strong></td>
<td>비쌈</td>
</tr>
<tr>
<td>부팅 볼륨</td>
<td><strong>불가</strong>(EBS st1/sc1)</td>
<td><strong>가능</strong>(gp3/gp2/io1/io2)</td>
</tr>
<tr>
<td>적합 워크로드</td>
<td>로그/백업/ETL 같은 <strong>대용량 순차 처리</strong></td>
<td>DB/OLTP/메타데이터/일반 서버 등 <strong>랜덤·혼합 I/O</strong></td>
</tr>
</tbody></table>
<br/>

<p><span style="font-size:20px;font-weight:bold">EBS 볼륨 타입</span></p>
<table>
<thead>
<tr>
<th>타입</th>
<th>성격/용도</th>
<th>성능 모델</th>
<th>특징(시험 포인트)</th>
<th>부팅 가능</th>
</tr>
</thead>
<tbody><tr>
<td><strong>gp3</strong> (General Purpose SSD)</td>
<td>대부분의 일반 워크로드, 웹/앱 서버, 중소형 DB</td>
<td><strong>기본 IOPS/처리량 제공 + 필요량을 별도 프로비저닝</strong></td>
<td>비용 효율 최고. <strong>IOPS·Throughput을 용량과 독립적으로 설정</strong> 가능(베이스라인 존재). 신규 배포의 디폴트.</td>
<td>✅</td>
</tr>
<tr>
<td><strong>gp2</strong> (General Purpose SSD, 레거시)</td>
<td>기존 레거시 워크로드 호환</td>
<td><strong>용량에 비례해 IOPS 증가, 버스트 크레딧</strong></td>
<td>새로 쓰진 않음(마이그레이드 대상). <strong>버스트 크레딧</strong> 고갈 시 성능 저하.</td>
<td>✅</td>
</tr>
<tr>
<td><strong>io1</strong> (Provisioned IOPS SSD)</td>
<td>트랜잭션성 DB(OLTP), 지연 민감 워크로드</td>
<td><strong>IOPS를 명시적으로 프로비저닝</strong></td>
<td>고성능/안정적 IOPS 필요 시. 오늘날은 io2 권장.</td>
<td>✅</td>
</tr>
<tr>
<td><strong>io2</strong> (Provisioned IOPS SSD)</td>
<td>미션 크리티컬 DB, 고내구성 필요</td>
<td><strong>IOPS 프로비저닝(내구성↑)</strong></td>
<td>io1 대비 <strong>내구성 향상</strong>. Nitro 기반에서 큰 IOPS/처리량 가능. <em>io2 Block Express</em>로 초대형·초고성능 지원(옵션).</td>
<td>✅</td>
</tr>
<tr>
<td><strong>st1</strong> (Throughput Optimized HDD)</td>
<td><strong>대용량 순차 I/O</strong>(빅데이터, 로그 처리, ETL)</td>
<td><strong>처리량(Throughput) 중심 + 버스트</strong></td>
<td><strong>HDD 계열</strong>, 비용/GB 저렴. <strong>부팅 볼륨 불가</strong>. 랜덤 I/O·저지연에는 부적합.</td>
<td>❌</td>
</tr>
<tr>
<td><strong>sc1</strong> (Cold HDD)</td>
<td><strong>드물게 접근</strong>하는 대용량 데이터(아카이브 성향)</td>
<td><strong>낮은 처리량 + 버스트</strong></td>
<td>가장 저렴한 HDD. <strong>부팅 불가</strong>, 성능 낮음. 백업/콜드 데이터에만.</td>
<td>❌</td>
</tr>
</tbody></table>
<p>EBS 볼륨중에 <span style="color:plum"><strong>루트 볼륨(os가 부팅되는 곳)이 되는게 SSD 계열</strong></span></p>
<hr>
<h2 id="ebs-다중-연결">EBS 다중 연결</h2>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/267f2598-dee4-4f66-a76a-637588508ee0/image.png" alt=""></p>
<p>EBS 볼륨 중 io1 및 io2 제품군에서만 사용할 수 있음</p>
<p>각 인스턴스는 고성능 볼륨에 대한 전체 읽기 및 쓰기 권한을 갖게 됨
ex) 인스턴스 A, B, C 모두가 동시에 그 하나의 블록 디바이스에 읽기/쓰기를 할 수 있음</p>
<p>⚠️ 중요한 주의점</p>
<p>일관성/락은 AWS가 보장하지 않음 → 클러스터 파일시스템(GFS2, OCFS2) 또는 애플리케이션 락을 반드시 사용해야 함</p>
<p>Use case</p>
<ol>
<li>클러스터화된 linux 애플리케이션</li>
<li>애플리케이션에서 동시 쓰기 작업을 관리하는 경우</li>
</ol>
<p>다중 연결의 제한</p>
<ol>
<li>지정된 가용 영역 내에서만 사용 가능</li>
<li>하나의 볼륨은 <strong>한 번에 최대 <span style="background-color:yellow">16개</span>의 EC2 인스턴스에 부착</strong>할 수 있다</li>
</ol>
<p>다중 연결이 동작하려면 클러스터를 인식할 수 있는 파일 시스템을 사용해야 함
=&gt; 일반 ext4/xfs 같은 단일 호스트용 FS를 그대로 공유하면 100% 데이터 손상</p>
<p><span style="font-size:19px"><strong>why❓</strong></span>
여러 대가 동시에 같은 디스크에 쓰면 서로 누가 먼저/어디에 썼는지 조율이 안 돼서
메타데이터가 꼬이고(저널 충돌),각자 메모리에 들고 있던 캐시 내용이 서로 모순이 되고, 결국 파일시스템이 손상</p>
<p>여러 노드가 동시에 접근하려면, OS/파일시스템 레벨에서 분산 잠금(DLM), 저널 공유/조율, 캐시 무효화 규칙, 펜싱(fencing) 등을 갖춘 <strong>“클러스터 인식 파일시스템”</strong>이 꼭 필요함
대표 예: GFS2, OCFS2 (여러 노드가 같은 블록 장치를 안전하게 공유하도록 설계됨)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS DVA 항해기 - EC2 인스턴스 스토리지 - EC2 인스턴스 스토어]]></title>
            <link>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%8A%A4%ED%86%A0%EC%96%B4</link>
            <guid>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%8A%A4%ED%86%A0%EC%96%B4</guid>
            <pubDate>Sun, 09 Nov 2025 12:10:39 GMT</pubDate>
            <description><![CDATA[<p>EBS는 네트워크로 붙는 블록 스토리지라서 성능이 좋지만, “물리적으로 로컬 디스크(NVMe Instance Store)만큼 무제한은 아니다”</p>
<p>❓왜 “네트워크 드라이브 + 제한된 성능”이라고 할까?</p>
<ul>
<li><p>네트워크 경유: EBS는 인스턴스 바깥의 스토리지 장비에 저장되고, 전용 네트워크로 블록 I/O를 주고받아요. 로컬 장치가 아니라서 <strong>추가 지연(latency)</strong>이 발생</p>
</li>
<li><p>볼륨 자체 한도: 각 볼륨 타입(gp3, io2, st1 등)은 IOPS/Throughput 상한이 있음 (원하는 만큼 무한히 늘지 않음)</p>
</li>
<li><p>인스턴스 한도: 인스턴스 타입별로 EBS 대역폭(GB/s)과 총 IOPS에 상한이 있어음 =&gt; 볼륨이 빨라도, 인스턴스가 허용하는 총량을 넘을 수 없음</p>
</li>
<li><p>버스트/크레딧 모델: 일부 타입은 버스트 크레딧이 있어 짧게는 빠르지만 지속 부하는 떨어질 수 있음</p>
</li>
</ul>
<ul>
<li>멀티테넌시: 동일 AZ 내 여러 사용자가 공유하는 인프라 위에서 돌아가므로, 일부 상황에서 변동성이 있을 수 있음(요즘은 꽤 안정적이지만 개념적으로 존재)</li>
</ul>
<br/>

<p><span style="font-size:22px">💡 하드웨어적인 고성능이 필요하면 <strong>EC2 인스턴스 스토어</strong>를 사용❗️</span></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/c3d67ff9-e968-432b-8c85-4d8d4a0df52a/image.png" alt=""></p>
<p><span style="font-size:22px"><strong>EC2 vs EC2 Instance vs EC2 Instance Store vs EBS</strong></span></p>
<ul>
<li><p>EC2: 컴퓨트 서비스 이름(플랫폼)</p>
</li>
<li><p>EC2 인스턴스: 그 서비스 위에서 실행되는 가상 머신(네가 띄우는 서버)</p>
</li>
<li><p>EC2 Instance Store: 인스턴스가 올라가는 물리 호스트에 붙은 로컬 NVMe 디스크(옵션) / 인스턴스 타입에 따라 있을 수도, 없을 수도 있음
보통 …d, i3/i4 같은 일부 인스턴스 타입이 그 로컬 디스크를 탑재</p>
</li>
<li><p>EBS: 네트워크로 붙는 영속 블록 스토리지(같은 AZ에 있어야 attach 가능)</p>
</li>
</ul>
<p>EC2 Instance Store를 쓰는 이유?</p>
<ul>
<li><p>더 나은 I/O(저장장치에 읽고/쓰는 속도와 반응성) performance를 위해</p>
<details>
<summary>I/O Performance</summary>
<div>

<ol>
<li>지연시간(Latency)</li>
</ol>
</li>
</ul>
<pre><code>“한 번 읽기/쓰기 요청을 처리하는 데 걸리는 시간”(ms, µs)
낮을수록 즉각 반응. 데이터베이스 트랜잭션처럼 작고 랜덤한 작업에 중요.</code></pre><ol start="2">
<li><p>IOPS (Input/Output Operations Per Second)</p>
<p>&quot;1초에 읽기 /쓰기를 몇 번 처리하나&quot; (보통 작은 블록, 랜덤 I/O 가정)</p>
<p>수치가 높을수록 작은 요청을 많이 동시에 처리 가능. 키–값 저장소, OLTP DB 등에 핵심.</p>
</li>
<li><p>처리량/스루풋(Throughput)</p>
<p> “초당 몇 MB/GB를 연속으로 옮기나” (MB/s, GB/s).</p>
<p> 큰 파일을 순차적으로 이동/처리하는 작업(ETL, 로그 압축, 영상 처리)에 중요.</p>
</div>
</details>

</li>
</ol>
<ul>
<li>왜 EC2 Instance Store가 I/O에 유리하냐?</li>
</ul>
<p>   로컬 NVMe라서 <U>네트워크를 안 타고 바로 호스트 디스크에 접근 →
지연시간이 매우 낮고, IOPS/처리량이 크게 나옴</U></p>
<p> 단, 휘발성이라 중지/종료/호스트 이슈 시 데이터가 사라짐 → 캐시/임시/버퍼/스크래치 용도에 적합
 =&gt; 필요에 따라 백업이나 복제를 해두는 것이 좋다</p>
<br/>

<p><strong>Instance Store vs EBS</strong></p>
<table>
<thead>
<tr>
<th>항목</th>
<th><strong>Instance Store(로컬 NVMe)</strong></th>
<th><strong>EBS(네트워크 블록 스토리지)</strong></th>
</tr>
</thead>
<tbody><tr>
<td>지연/속도</td>
<td><strong>매우 낮은 지연·고성능</strong></td>
<td>좋지만 네트워크 경유</td>
</tr>
<tr>
<td>지속성</td>
<td><strong>휘발성</strong>(중지/종료/호스트 이슈 시 소실)</td>
<td><strong>영속</strong></td>
</tr>
<tr>
<td>관리 기능</td>
<td>스냅샷/암호화/크로스AZ 없음(직접 설계)</td>
<td><strong>스냅샷·암호화·크기조정</strong> 등 풍부</td>
</tr>
<tr>
<td>루트 볼륨</td>
<td>가능(Instance-store-backed: <strong>정지/시작 불가</strong>)</td>
<td><strong>표준</strong>(EBS-backed: 정지/시작 가능)</td>
</tr>
<tr>
<td>사용처</td>
<td>캐시/스크래치/빌드 temp, 초고 I/O</td>
<td>DB 데이터, 영속 파일, 일반 워크로드</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS DVA 항해기 - EC2 인스턴스 스토리지 - AMI]]></title>
            <link>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80-AMI</link>
            <guid>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80-AMI</guid>
            <pubDate>Sun, 09 Nov 2025 09:22:37 GMT</pubDate>
            <description><![CDATA[<h2 id="❓-amiamazon-machine-image">❓ AMI(Amazon Machine Image)</h2>
<p>=&gt; 커스터마이징된 인스턴스로부터 만들어진 이미지(템플릿)
=&gt; OS/소프트웨어/설정을 캡처한 부팅 이미지
=&gt; 부팅에 필요한 디스크 스냅샷(루트 볼륨), 블록 디바이스 매핑, 권한 정보를 정적인 묶음으로 가진 설계도</p>
<p>AWS에서 생성한 AMI를 사용하거나 사용자 지정 AMI를 만들 수 있다</p>
<p>자체적으로 AMI를 생성하면 부팅과 구성에 시간이 단축됨</p>
<p>-&gt; EC2 인스턴스에 설치하고자 하는 모든 소프트웨어가 AMI를 통해서 사전에 패키징 되기 때문</p>
<p>AMI ID는 해당 리전에서만 유효. 다른 리전에서 쓰려면 AMI 복사 필요(새 ID 생성)</p>
<h3 id="ami-유형">AMI 유형</h3>
<ul>
<li><p>Amazon 제공</p>
</li>
<li><p>내 프라이빗</p>
<ul>
<li>AMI를 만든 소유 계정만 볼 수 있고, 그 계정만 인스턴스를 띄울 수 있음</li>
<li>복사: 같은 계정 내 리전 간 복사 가능(복사하면 새 AMI ID)</li>
<li>요금: 스냅샷/스토리지는 소유 계정이 부담</li>
</ul>
</li>
<li><p>공유(계정 대상)</p>
<ul>
<li><p>특정 다른 AWS 계정 ID에 ‘런치 권한’을 부여해 그 계정이 이 AMI로 인스턴스를 띄울 수 있게 한 상태</p>
</li>
<li><p>주의(암호화 시 3종 세트)</p>
<ul>
<li>AMI 런치 권한 공유<ul>
<li>(암호화된) 스냅샷 공유</li>
<li>KMS 키 사용 권한 부여
이 셋이 모두 되어야 상대 계정에서 실제로 사용/복사 가능</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code>* 복사/소유권: 공유받은 계정이 **자기 계정으로 AMI를 ‘복사’**하면, 그 복사본은 공유받은 계정 소유가 됨(권장 패턴)
* 요금: 원본 보관 비용은 원본 소유 계정이 부담(공유만 했을 뿐). 상대가 복사하면 복사본 비용은 상대 계정 부담
* 용도: 멀티계정(Prod/Dev/보안계정) 간 표준 이미지 배포, 파트너/자회사 제공</code></pre><ul>
<li><p>퍼블릭</p>
<ul>
<li>누구나 검색/사용 가능(전체 공개)</li>
<li>조건: AMI와 해당 스냅샷도 퍼블릭이어야 함</li>
<li>제한: 암호화된 AMI는 퍼블릭 불가, Marketplace AMI도 퍼블릭 전환 불가</li>
<li>용도: 커뮤니티 배포(예: 교육용 베이스 이미지), 오픈 샘플</li>
</ul>
</li>
</ul>
<ul>
<li><p>Marketplace</p>
<ul>
<li>다른 사람이 생성한 AMI(잠재적으로 팔 수 있는?)</li>
</ul>
</li>
</ul>
<br/>

<p><strong>표로 한눈에 정리</strong></p>
<table>
<thead>
<tr>
<th>구분</th>
<th>볼 수 있는 대상</th>
<th>누가 런치?</th>
<th>스냅샷/키 요구</th>
<th>복사</th>
<th>전형적 용도</th>
</tr>
</thead>
<tbody><tr>
<td>내 프라이빗</td>
<td>소유 계정만</td>
<td>소유 계정</td>
<td>기본(추가 없음)</td>
<td><strong>가능</strong>(리전 간)</td>
<td>사내 표준/운영용</td>
</tr>
<tr>
<td>공유(계정 대상)</td>
<td>지정한 계정</td>
<td>소유 + <strong>지정 계정</strong></td>
<td>(암호화 시) <strong>스냅샷+KMS 권한</strong> 공유</td>
<td><strong>상대가 자기 계정으로 복사 권장</strong></td>
<td>멀티계정 배포/파트너 제공</td>
</tr>
<tr>
<td>퍼블릭</td>
<td><strong>모두</strong></td>
<td><strong>누구나</strong></td>
<td>스냅샷도 퍼블릭, <strong>암호화 불가</strong></td>
<td>사용자가 자기 계정으로 복사 가능</td>
<td>공개 배포/학습용</td>
</tr>
</tbody></table>
<br/>

<h3 id="ami-process">AMI Process</h3>
<ol>
<li>EC2를 시작하고 사용자 지정으로 바꾼다(customize)</li>
<li>인스턴스를 중지시켜 데이터 무결성을 확보(선택 사항)
 콘솔에서 No reboot 체크를 해제(재부팅 허용)하면 파일시스템 일관성이 더 좋음
 윈도우는 Sysprep, 리눅스는 서비스 중지/fsfreeze/sync 같은 방법도 좋음</li>
<li>AMI 구축 =&gt; AMI 생성 시 블록 디바이스 매핑에 포함된 모든 EBS 볼륨의 스냅샷이 같이 만들어짐 </li>
<li>생성된 해당 AMI를 사용해 인스턴스를 실행</li>
</ol>
<hr>
<h3 id="ami-생성해보기내-프라이빗-ver">AMI 생성해보기(내 프라이빗 ver.)</h3>
<p>먼저 인스턴스를 새로 생성하고</p>
<p>생성된 인스턴스 =&gt; 우클릭 =&gt; Image and Templates =&gt; Create Image 클릭🖱️❇️</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/3b0fdb14-12ee-4e54-a50e-be438ca25e8a/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/4144f068-972a-4951-a60a-b74d58f20e8d/image.png" alt=""></p>
<p>생성된 AMI로 인스턴스 생성 가능
<img src="https://velog.velcdn.com/images/poala_0217/post/e961a890-5e3c-4660-8ff7-70f455ac5d7d/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/bdae975e-d542-4598-96b9-3c4ef99833e2/image.png" alt=""></p>
<p>My AMIs에 보면 직전에 내가 생성했던 AMI가 목록에 나타나는 것을 확인할 수 있다</p>
<p>User Data에 생성한 AMI에 이미 설치 명령어가 다 입력되어 있어서</p>
<pre><code class="language-bash">yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd</code></pre>
<p>새로 생성한 인스턴스에는 아래 항목만 입력해주고 AMI를 연결했다</p>
<pre><code class="language-bash"># Use this for your user data (script from top to bottom)
# install httpd (Linux 2 version)
#!/bin/bash
echo &quot;&lt;h1&gt;Hello World from $(hostname -f)&lt;/h1&gt;&quot; &gt; /var/www/html/index.html</code></pre>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/b3e127f1-0a99-429d-9c6e-3b926766bbec/image.png" alt=""></p>
<p>Public IP 주소로 접근하면 페이지가 정상 출력되는 것을 확인할 수 있다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS DVA 항해기 - EC2 인스턴스 스토리지 - EBS + EBS 스냅샷 ]]></title>
            <link>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80-EBS-EBS-%EC%8A%A4%EB%83%85%EC%83%B7</link>
            <guid>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80-EBS-EBS-%EC%8A%A4%EB%83%85%EC%83%B7</guid>
            <pubDate>Sun, 09 Nov 2025 07:35:47 GMT</pubDate>
            <description><![CDATA[<h2 id="❓ebselastic-block-store-volume">❓EBS(Elastic Block Store) Volume</h2>
<p>=&gt; 인스턴스가 실행 중인 동안 연결 가능한 네트워크 드라이브(실제 물리적인 연결이 있는 것은 아님)</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/4dd116c0-41a0-4625-9e2f-5db0ea9c06f4/image.png" alt=""></p>
<p>EBS 볼륨을 사용하면 인스턴스가 종료된 후에도 데이터 지속 가능 =&gt; 인스턴스를 재성성하고 EBS 볼륨을 마운트하면 데이터를 다시 받을 수 있음</p>
<p><strong>AZ 단위 리소스라서, EC2와 같은 AZ에 있어야 붙일 수 있음</strong>
    ex) EBS 볼륨이 us-east-1a에서 생성 =&gt; us-east-1b 인스턴스에 붙일 수 ❌</p>
<p>   하지만 스냅샷을 이용하면 다른 가용영역(AZ)로도 옮길 수 있음</p>
<p><strong>CCP 레벨</strong>:
    하나의 EBS는 하나의 인스턴스에만 마운트 가능 BUT 하나의 인스턴스는 여러개의 EBS를 가질 수 있다‼️</p>
<p><strong>Associate 레벨</strong>:
    일부 EBS 타입에 한해 여러 EC2 동시 부착 가능</p>
<p>EBS 볼륨이 인스턴스와 통신하기 위해서는 네트워크가 필요 =&gt; 컴포터가 다른 서버에 도달할 때 지연이 발생할 수 있음</p>
<p>EBS 볼륨은 네트워크 드라이브기 때문에 인스턴스에 빠르게 붙기도 떨어지기도 함</p>
<p>용량을 미리 결정해야 함(size: GB, IOPS(단위 초당 전송 수))
why?</p>
<ol>
<li><p>블록 주소 공간 고정 필요</p>
<ul>
<li>OS는 디스크를 “0번 블록~N번 블록”처럼 연속된 주소 범위로 인식
=&gt; 이 범위를 초기에 선언해야 파티션/파일시스템을 안정적으로 만들 수 있음 (중간에 맘대로 줄였다 늘리면 데이터 맵이 깨짐)</li>
</ul>
</li>
<li><p>예측 가능한 성능·격리</p>
<ul>
<li>EBS는 멀티 테넌트 스토리지 위에 <strong>프로비저닝(예약)</strong>된 논리 디스크를 만들어 주는 구조</li>
<li><strong>크기와 타입에 따른 성능/내구성 보장(특히 io1/io2의 IOPS 보장)</strong>을 위해 자원을 미리 예약해야 함</li>
<li>gp3는 IOPS/처리량을 용량과 분리해 설정할 수 있지만, 기본이 되는 블록 공간(GB)은 여전히 정의해야 해야 함</li>
</ul>
</li>
</ol>
<ol start="3">
<li><p>과금 모델과 리소스 관리</p>
<ul>
<li>EBS는 GB-월 단위로 과금(스냅샷/프로비저닝 IOPS/Throughput은 별도)
=&gt; 미리 크기를 정하면 AWS 입장에서도 용량 계획·파편화 관리가 가능하고, 사용자 입장에서도 비용 예측이 쉽다</li>
</ul>
</li>
<li><p>스냅샷/복구·마이그레이션의 일관성</p>
<ul>
<li>스냅샷은 증분 백업이지만, 복구 시엔 동일한 블록 주소 범위로 복원</li>
<li>주소 공간이 고정되어 있어야 스냅샷 → 볼륨 재생성/리전 복사/FSR 같은 기능이 안전하게 동작</li>
</ul>
</li>
</ol>
<p>ec2 인스턴스를 통해 ebs 볼륨을 생성하는 경우 &quot;종료 시 삭제&quot; 속성이 존재</p>
<p>기본적으로 <strong>root EBS 볼륨은 인스턴스 종료와 함께 삭제</strong>되도록 설정</p>
<h3 id="ebs-볼륨-만들어보기">EBS 볼륨 만들어보기</h3>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/38a3b9ca-dc6f-49c2-9f5d-1cc89965e134/image.png" alt=""></p>
<p>EC2 Instance에서 인스턴스 클릭 후 Storage 탭을 클릭하면 Block devices에서 지금 사용중인 EBS가 보인다</p>
<p>대부분의 경우 (= EBS-backed AMI사용)
EC2를 생성하면 루트 EBS 볼륨이 자동으로 함께 생성·붙음</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/a0c62555-1af9-4abe-80f2-da26aa23b67c/image.png" alt=""></p>
<p>Create volume 버튼 클릭</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/fdd38b6d-991c-47b3-b3a1-2e44db63c04e/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/d478ac92-8697-4672-b1f3-33793e296cdf/image.png" alt=""></p>
<p>EC2&gt; Instances에 Networking 탭에서 Availability zone 확인 가능</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/60c9da3b-77dd-4a42-88df-b45d2dc834ab/image.png" alt="">
<img src="https://velog.velcdn.com/images/poala_0217/post/145ab7ad-a0d2-48e0-acc7-c667cab39b07/image.png" alt=""></p>
<p>인스턴스를 선택하고 볼륨을 연결한다</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/4179248c-c53d-4e9f-b68d-86cfe5f9b6bf/image.png" alt=""></p>
<p>다시 Instances의 내 인스턴스에서 Storage 탭을 클릭해서 스크롤한 다음 Block devices를 확인하면 방금 연결한 볼륨이 목록에 뜨는 것을 확인할 수 있다</p>
<p>인스턴스를 종료하면 EBS 볼륨은 어떻게 될까?</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/71d55a51-08e2-47d6-829b-330656fdb044/image.png" alt=""></p>
<p>최상단의 EBS 볼륨을 보면 Delete on termiation에 Yes 표시가 되어있는데</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/5018a070-ae92-49b5-b2e2-1cb3cccd07a7/image.png" alt=""></p>
<p>이는 Instance를 생성할 때 우리가 Delete on termination에 Yes로 체크했기 때문이다</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/43587d2d-dddb-4676-9961-17827523e2eb/image.png" alt=""></p>
<p>실제로 내가 Instance를 종료하고 다시 EBS 볼륨 목록을 조회하면</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/095e2b4b-756a-48d0-b4f7-337b30308f67/image.png" alt=""></p>
<p>첫번째 EBS 볼륨이 사라진 것을 확인할 수 있다</p>
<hr>
<h2 id="ebs-스냅샷">EBS 스냅샷</h2>
<p>EBS 볼륨의 특정 시점에서의 백업 /EBS의 데이터 저장 상태에 대해 사진(백업본)을 찍어둔 개념</p>
<p>EBS 스냅샷을 다른 가용 영역 또는 다른 리전에 복사 가능</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/5f1e0f31-8f00-4cd0-821f-dd7ebfee43e1/image.png" alt=""></p>
<p>EBS 볼륨을 한 인스턴스에서 다른 인스턴스로 전송하는 방법이라고도 할 수 있다</p>
<h3 id="특징">특징</h3>
<ol>
<li><p>증분 백업: <strong>첫 스냅샷은 사용 중 블록 전체</strong>, 이후엔 <strong>변경 블록만 저장</strong> → 비용/시간 절감</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/aeeb59d4-eefb-40a2-9238-767538e42720/image.png" alt=""></p>
<p>맨 왼쪽부터 스냅샷이 생성된 순서에 따라 &quot;Snapshots A-&gt; B-&gt; C&quot;로 표현하고 있으며, 볼륨에 대한 데이터가 변경될 때마다 스냅샷을 생성하는 순서를 &quot;State&quot;로 표현하고 있다.</p>
<p>State 1 부터 살펴보면, 15GiB 용량을 가진 EBS 볼륨에서 10GiB의 데이터를 가지고 있고, 해당 볼륨에 대한 첫번째 스냅샷을 생성한다면 스냅샷 A가 가진 용량은 10GiB가 됨</p>
<p>State 2 에서는 기존 EBS 볼륨의 10GiB 데이터에서 4GiB의 데이터가 변경(changed)되었는데, 해당 시점에서 두번째 스냅샷을 생성한다면 스냅샷 B는 변경된 4GiB의 데이터를 가지며, 변경되지 않은 6GiB에 대해서는 스냅샷 A의 부분을 참조(referenced)</p>
<p>(❕이 시점에서 10GiB 데이터를 가진 볼륨에 대한 스냅샷이 2개 생성되었지만 실제로 스냅샷이 가진 데이터의 크기는 A -&gt; 10GiB + B -&gt; 4 GiB으로 14GiB가 됨)</p>
<p>State 3 에서는 기존 10GiB 데이터를 가지고 있는 볼륨에 2GiB 크기의 새로운 데이터가 추가(added)되었으며, 해당 시점에서 세번째 스냅샷을 생성한다면 스냅샷 C는 새로 추가된 2GiB의 데이터를 가지며, 스냅샷 A의 6GiB, 스냅샷 B의 4GiB의 데이터를 참조(referenced)</p>
<p>정리하자면,</p>
<p>Snapshot A : 10GiB 데이터를 가짐 (EBS 볼륨이 가지고 있는 데이터 용량 : 10GiB)
Snapshot B : 4GiB 데이터를 가짐 (EBS 볼륨이 가지고 있는 데이터 용량 : 기존의 6GiB + 변경된 4GiB)
Snapshot C : 2GiB 데이터를 가짐 (EBS 볼륨이 가지고 있는 데이터 용량 : 기존의 10GIB + 추가된 2GIB 으로 12GiB)
Snapshot A + B + C 저장에 필요한 S3의 용량은 10 + 4 + 2 로 16GiB이 된다. 따라서 사용자는 16GiB에 대한 스냅샷 비용을 지불하면 됨</p>
<p>(❕ 스냅샷은 EBS의 데이터를 S3에 백업하는 방식으로 생성)</p>
</li>
</ol>
<ol start="2">
<li><p>복원 성능: 스냅샷에서 만든 볼륨은 지연 로딩(lazy loading) → 초기 읽기 지연</p>
<ul>
<li>해결: Fast Snapshot Restore(FSR) 활성화(특정 AZ 예열) 또는 수동 프리리드<ul>
<li>FSR(Fast Snapshot Restore)?
=&gt; 스냅샷을 처음 사용할 때 대기 시간이 없도록 스냅샷을 완전히 초기화하는 것
=&gt; 스냅샷이 매우 클 때 EBS 볼륨을 초기화하거나 빠르게 인스턴스화해야하는 경우에 유리
=&gt; 하지만 비용이 많이 든다</li>
</ul>
</li>
</ul>
</li>
</ol>
<ol start="3">
<li><p>비용/보존: GB-월로 과금(증분 기준) + API 호출</p>
<ul>
<li><p>Snapshot Archive: 장기보관용 저렴, 대신 복원에 몇 시간</p>
<ul>
<li>스냅샷을 최대 75%% 더 저렴한 아카이브 티어로 옮길 수 있는 기능</li>
<li>스냅샷을 아카이브 티어로 옮기면 아카이브를 복원하는 데 24시간에서 72시간 정도 걸림</li>
</ul>
</li>
<li><p>Recycle Bin: 삭제 보호(보존 규칙)</p>
<ul>
<li>EBS 스냅샷을 영구적으로 삭제하는 대신 휴지통에 보관 =&gt; 실수로 삭제한 경우 복구가 가능</li>
<li>보관 기간은 하루에서 1년까지 설정 가능!</li>
</ul>
</li>
</ul>
</li>
</ol>
<hr>
<h3 id="ebs-스냅샷-만들기">EBS 스냅샷 만들기</h3>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/3904b6a2-2bed-48e7-80dc-120d91598086/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/e33774c2-817a-4538-9cb1-26a43ed1f1c5/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/688f037b-605b-4bbe-aaa9-a75fccb8a58e/image.png" alt=""></p>
<p>생성된 스냅샷의 복제본을 다른 리전에 만들 수 있다</p>
<p>또 다르게 스냅샷을 만든 다음 그것으로 볼륨을 생성할 수도 있다</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/c668e410-25e2-447b-9051-d6924e82d5c2/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/abea45a8-f555-4f4e-9623-61df6b7290fa/image.png" alt=""></p>
<p>AZ를 일부러 다른 곳을 선택해보겠다</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/ddd6e4fe-cf9b-4ba0-bedf-f4057121ff97/image.png" alt=""></p>
<p>생성 후 Volumes 탭에 들어가면 2개의 볼륨이 있는 것을 확인할 수 있는데 하나는 Snapshot ID가 명시되어 있어 스냅샷으로 만든 것을 확인할 수 있다</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/97280e5c-72c3-4a46-9e64-bf73ea9a9db8/image.png" alt=""></p>
<p>Snapshot 메뉴 우측 상단에 Recycle bin이라는 버튼이 있다</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/fea65864-88ab-4c04-9ff7-9eb14ddbe792/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/b1dfe74d-a860-4ae2-b885-4d3490ede241/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/268e444e-2c06-4658-ae44-b1c8dc47b4e3/image.png" alt=""></p>
<p>Rule 이름, 복구하려는 리소스 타입, 보존 기간 등을 설정할 수 있다</p>
<p>다시 스냅샷 영역으로 가서 삭제를 진행해준다</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/a8a4622d-4c3a-4d53-bc05-f3cada0b9723/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/1c050aa2-b4b1-4d68-aabe-1a75d3b35e0d/image.png" alt=""></p>
<p>하지만 Recycle Bin의 Resources에 들어가보면 방금 내가 삭제했던 EBS snapshot이 목록에 나타나는 것을 확인할 수 있다</p>
<p>여기서 Recover 가능‼️</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS DVA 항해기 - EC2 인스턴스 + IAM 역할 + EC2 인스턴스 구매시 옵션]]></title>
            <link>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-IAM-%EC%97%AD%ED%95%A0-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EA%B5%AC%EB%A7%A4%EC%8B%9C-%EC%98%B5%EC%85%98</link>
            <guid>https://velog.io/@poala_0217/AWS-DVA-%ED%95%AD%ED%95%B4%EA%B8%B0-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-IAM-%EC%97%AD%ED%95%A0-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EA%B5%AC%EB%A7%A4%EC%8B%9C-%EC%98%B5%EC%85%98</guid>
            <pubDate>Tue, 04 Nov 2025 02:33:54 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/poala_0217/post/8ba11633-789b-47d7-b5de-94c172c35cbc/image.png" alt=""></p>
<p>자격 증명을 위해 aws configure 명령을 통해서
IAM의 Access Key, Secret Access Key 등을 입력하는 건 권장하지 않음</p>
<h4 id="1-장기-키static-key-노출-위험">1. 장기 키(Static Key) 노출 위험</h4>
<p>  키가 로컬 디스크 ~/.aws/credentials에 저장되어서
  노트북 분실·멀웨어·로그/스크립트 유출·깃에 실수로 커밋 등으로 유출되면 장기간 악용될 수 있음
  EC2 내부에 aws configure로 키를 저장해두면: 그 인스턴스에 SSH/RDP/SSM/Instance Connect로 OS 접근 가능한 사람은 cat ~/.aws/credentials로 바로 읽을 수 있음</p>
<h4 id="2-로테이션폐기-번거로움">2. 로테이션/폐기 번거로움</h4>
<p>사람이 쓰는 장기 키는 주기적 교체가 귀찮고, 여러 장비에 퍼지면 정리/폐기 난이도↑ (Credential sprawl)</p>
<h4 id="3-mfa세션-보안이-약함">3. MFA/세션 보안이 약함</h4>
<p>장기 키는 기본적으로 MFA가 강제되지 않음. 탈취되면 바로 API 호출 가능
반면 임시 자격증명(STS) 는 만료시간이 있어 피해를 줄임</p>
<p>이를 대신해 IAM Role(역할)을 사용할 수 있다</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/1590bbcd-841b-4d82-b44c-79fa52bf794b/image.png" alt=""></p>
<p>지금은 실행중인 인스턴스에 IAM Role이 비어있다</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/b9a7f1cb-b676-4e1a-acb3-9536a0118115/image.png" alt=""></p>
<p>Actions &gt; Security &gt; Modify IAM role로 진입</p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/3b5df8f2-a232-4116-9521-51db640fa0e2/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/e7dca68f-74de-4b60-97f5-5c9a2c483eb3/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/poala_0217/post/a8b0e15e-c212-4edf-a294-8dc70df7ae38/image.png" alt=""></p>
<p>aws iam list-users 명령어가 정상 실행되는 이유는 DemoRoleForEC2라는 Role에 IAMReadOnlyAccess 권한이 있기 때문이다</p>
<hr>
<h3 id="ec2-인스턴스-구매-옵션">EC2 인스턴스 구매 옵션</h3>
<h4 id="1-온디맨드on-demand">1) 온디맨드(On-Demand)</h4>
<ul>
<li><p>과금: 초/시간 단위로 사용한 만큼만!</p>
</li>
<li><p>장점: 최대로 유연(즉시 생성/종료, 약정 없음)</p>
</li>
<li><p>단점: 장기 사용 시 단가가 가장 비쌈</p>
</li>
<li><p>적합: 개발/테스트, 트래픽 예측 어려운 초반 운영 / 연속적인 단기 워크로드</p>
<ul>
<li><p>과금 단위</p>
<ul>
<li><p>초 단위(최소 60초): Linux, Windows(및 Windows + SQL 버전들), 주요 리눅스 배포판들(예: Amazon Linux, Ubuntu, RHEL 등)</p>
</li>
<li><p>시간당 과금: 그 외 OS 타입</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<br/>

<h4 id="2-세이빙스-플랜savings-plans">2) 세이빙스 플랜(Savings Plans)</h4>
<ul>
<li><p>개념: “시간당 일정 금액(ex: 시간당 $0.50) 커밋(1년/3년)”을 약속하면 그 범위 내 사용에 할인 요금 적용</p>
</li>
<li><p>종류</p>
<ul>
<li><p>Compute Savings Plans: 가장 유연. 리전 내 모든 인스턴스 패밀리/사이즈/OS/테넌시 및 Fargate/Lambda까지 할인</p>
</li>
<li><p>EC2 Instance Savings Plans: 특정 패밀리(예:m7i) 기준으로 할인(리전 내 사이즈/OS 변경은 허용)</p>
</li>
</ul>
</li>
<li><p>지불 방식: All Upfront / Partial / No Upfront (선결제 클수록 할인↑).</p>
</li>
<li><p>장점: 예약 인스턴스보다 변경 유연성↑, 할인폭 큼</p>
</li>
<li><p>단점: 커밋 금액 미사용분도 비용 발생</p>
</li>
<li><p>적합: 상시 안정적 사용량이 있고, 인스턴스 다양성/이동이 잦을 때</p>
</li>
<li><p>❓실제 사용이 커밋보다 많으면??(예: $0.80)</p>
<ul>
<li>$0.50 구간은 SP 할인, <strong>초과</strong> $0.30은 <strong>온디맨드 요율로 과금</strong></li>
</ul>
</li>
</ul>
<br/>

<h4 id="3-예약-인스턴스reserved-instances">3) 예약 인스턴스(Reserved Instances)</h4>
<ul>
<li><p>개념: 특정 조건(리전·플랫폼·패밀리 등)에 1년/3년 약정으로 할인</p>
</li>
<li><p>종류</p>
<ul>
<li><p>Standard Reserved Instances: <strong>예측 가능한 장기 워크로드</strong>(1년/3년 상시 가동) 에 쓰는 옵션/ 할인 최대(약정 조건 변경 거의 불가)</p>
</li>
<li><p>Convertible Reserved Instances: 조건 변경 가능(동등/상위 가치로 교환), 할인은 Standard보다 낮음</p>
</li>
</ul>
</li>
<li><p>영역</p>
<ul>
<li>Regional RI: 리전 단위 할인(자동 적용)</li>
<li>Zonal RI: 특정 AZ 고정 + 용량 보장(Capacity Reservation 포함).</li>
</ul>
</li>
<li><p>지불 방식: All(전체 선결제)/Partial(부분 선결제)/No Upfront(선결제 x)</p>
</li>
<li><p>장점: 예측 가능한 장기 워크로드에 높은 할인</p>
</li>
<li><p>단점: 유연성 낮음, 초과/미달 사용 시 최적화 필요</p>
</li>
<li><p>적합: 고정적으로 켜져 있는 백엔드, DB 등</p>
</li>
</ul>
<p>💡 마켓 플레이스에서 사고 팔 수 있다..!</p>
<br/>

<h4 id="4-스팟-인스턴스spot">4) 스팟 인스턴스(Spot)</h4>
<ul>
<li><p>개념: 미사용 EC2 용량을 최대 90% 저렴하게 사용, 중단(회수) 가능성 존재</p>
</li>
<li><p>특징: 회수 전 2분 알림, 중단 시 종료/정지/하이버네이트 동작 선택 가능(유형/지원에 따라) / <strong>단기 워크로드</strong>에 적합</p>
</li>
<li><p>장점: 대폭 저렴</p>
</li>
<li><p>단점: 언제든 회수 가능, 상태 저장/세션형 서비스엔 부적합</p>
</li>
<li><p>적합: 배치/ETL, 데이터 분석, 이미지 처리, 컨테이너 워커, 분산 빌드/테스트</p>
</li>
<li><p>팁: 다중 인스턴스 패밀리+AZ 혼합, “용량-최적” 할당전략, 체크포인트/재시도 설계.</p>
</li>
</ul>
<br/>

<h4 id="5-전용-호스트dedicated-host">5) 전용 호스트(Dedicated Host)</h4>
<ul>
<li><p>개념: 물리적 서버 전체를 예약 / 물리 서버 자체를 소유한 듯 배정받아 라이선스·배치까지 세밀 제어</p>
</li>
<li><p>과금 : 호스트 단위 과금(on-demand(초/시간당 과금) / reserved(1 또는 3년))</p>
</li>
<li><p>장점:</p>
<ul>
<li>BYOL((Bring Your Own License)(Windows/SQL Server/Oracle 등) 소켓/코어 기반 라이선스 규칙을 지키기 쉬움</li>
<li>감사/규제에 필요한 서버 식별·배치 제어 가능</li>
<li>인스턴스 배치/고정성을 세밀하게 관리.</li>
</ul>
</li>
<li><p>단점: </p>
<ul>
<li>비용 높고 유연성 낮음(호스트 고정 비용)</li>
<li>호스트 용량 계획 필요(과소/과대 배치 리스크)</li>
</ul>
</li>
<li><p>시험 keyword: </p>
<ul>
<li>물리적 코어 </li>
<li>기본 네트워크 소켓 가시성을 기반으로 비용을 청구<br/>

</li>
</ul>
</li>
</ul>
<h4 id="6-전용-인스턴스dedicated-hostinstances">6) 전용 인스턴스(Dedicated Host/Instances)</h4>
<ul>
<li><p>개념: </p>
<ul>
<li>단일 테넌트 하드웨어에서 가상 인스턴스를 쓰는 방식</li>
<li>다른 고객의 인스턴스가 같은 물리 서버에 같이 올라오지 않도록 보장하지만, 그 물리 서버(호스트)에 대한 식별·제어권은 없음. 과금도 인스턴스 단위</li>
</ul>
</li>
<li><p>장점:</p>
<ul>
<li>설정이 비교적 간단(테넌시를 Dedicated로 지정)</li>
<li>물리적 격리가 필요하지만 서버 소켓/코어 단위 라이선스 관리가 필요 없을 때 적합</li>
</ul>
</li>
</ul>
<br/>

<h4 id="7-온디맨드-용량-예약odcr-on-demand-capacity-reservations">7) 온디맨드 용량 예약(ODCR, On-Demand Capacity Reservations)</h4>
<ul>
<li><p>개념: 특정 AZ/타입 용량을 미리 확보(비용은 인스턴스를 켜든 안 켜든 온디맨드 요율)</p>
<p>시간 약정이 없어서 할인도 없다..!</p>
</li>
<li><p>조합: 세이빙스 플랜 또는 RI와 결합하면 예약된 용량에도 할인율 적용 가능</p>
</li>
<li><p>적합: 이벤트/출시일 등 용량 보장이 중요한 경우</p>
<p>인스턴스 실행 여부와 상관없이 과금</p>
</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>