레이블이 Dev인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Dev인 게시물을 표시합니다. 모든 게시물 표시

2025년 3월 12일 수요일

현재 실행 중인 컨테이너를 새로운 이미지로 생성/저장/로드하는 방법

✅ 현재 실행 중인 컨테이너를 새로운 이미지로 생성/저장/로드하는 방법

  1. 실행 중인 컨테이너를 새로운 이미지로 커밋

    docker commit jenkins jenkins-with-plugins:2.492.2
    
  2. 이미지 저장

    docker save -o jenkins-with-plugins.tar jenkins-with-plugins:2.492.2
    
  3. 이미지 압축파일을 이미지로 로드

    docker load -i jenkins-with-plugins.tar
    

 

2025년 3월 6일 목요일

AWS Secrets Manager vs AWS Systems Manager Parameter Store

 AWS Secrets Manager와 AWS Systems Manager Parameter Store는 둘 다 애플리케이션의 구성 정보를 안전하게 저장하고 관리할 수 있도록 하는 서비스이지만, 주요 차이점이 있다.

1. 기능 및 사용 목적

항목 AWS Secrets Manager AWS Systems Manager Parameter Store
주요 목적 데이터베이스 암호, API 키, 인증 정보 같은 민감한 보안 정보를 저장 및 자동 회전 애플리케이션 설정, 구성 값, 비밀번호 등 다양한 키-값 데이터 관리
자동 키 회전 지원 (RDS, DocumentDB, Redshift와 연계 가능) 미지원 (수동으로 변경 필요)
IAM 권한 관리 IAM 정책으로 세밀한 접근 제어 가능 IAM 정책으로 접근 제어 가능하지만 보안 기능이 제한적
암호화 AWS KMS 기본 지원 기본적으로 AWS KMS 사용 가능하지만 선택 사항
버전 관리 여러 버전의 보안 정보를 저장하고 롤백 가능 기본적으로 버전 관리 지원
비용 별도 비용 발생 (사용량 기준 과금) 기본 기능은 무료, 고급 기능(고급 파라미터)은 유료

2. 보안 및 암호화

  • Secrets Manager는 보안이 중요한 민감한 정보를 저장하고, 자동으로 비밀번호를 회전할 수 있어 보안 관리가 강화된다.
  • Parameter Store도 KMS를 활용한 암호화 기능을 제공하지만, 기본적으로 보안 비밀번호 회전 기능은 없다.

3. 비용

  • Secrets Manager는 비밀번호 회전 및 보안 기능을 포함하여 추가 비용이 발생한다.
  • Parameter Store의 표준 파라미터는 무료이며, 고급 파라미터(암호화된 값 포함) 사용 시 추가 비용이 발생한다.

4. 사용 사례

사용 사례 AWS Secrets Manager AWS Systems Manager Parameter Store
데이터베이스 암호 관리 ⭕ (수동 관리)
API 키 및 인증 정보 저장
애플리케이션 구성 값 저장 ⭕ (비효율적)
비밀번호 자동 회전 필요
운영 환경에서 설정값 관리

5. 결론

  • Secrets Manager자동 비밀번호 회전 및 보안 강화가 필요한 경우 적합하다. (예: RDS, API 키 등 민감한 정보)
  • Parameter Store는 일반적인 애플리케이션 설정 값 관리에 유리하며, 비용 절감이 필요한 경우 더 적합하다.

즉, 보안이 중요한 경우 Secrets Manager, 일반적인 설정 관리는 Parameter Store를 사용하는 것이 좋다. 🚀

2024년 11월 8일 금요일

웹 애플리케이션의 시스템 성능 개선과 트러블슈팅

웹 애플리케이션의 시스템 성능 개선과 트러블슈팅을 위한 일반적인 방법은 다음과 같다.

1. 성능 개선 방안

a) 캐싱(Caching)

  • 데이터베이스 캐싱: 자주 조회되는 데이터를 캐시(예: Redis, Memcached)에 저장해 DB 부하를 줄인다.
  • 컨텐츠 캐싱: Cloudflare 같은 CDN 서비스를 통해 이미지, JS, CSS 파일 등 정적 파일을 캐싱하여 빠르게 제공한다.
  • 페이지 캐싱: 사용자 세션에 따라 달라지지 않는 페이지는 캐시하여 렌더링 시간을 줄인다.

b) 데이터베이스 최적화

  • 인덱스 최적화: 자주 사용하는 쿼리의 칼럼에 적절히 인덱스를 설정하여 조회 성능을 높인다.
  • 쿼리 최적화: 쿼리를 단순화하고 복잡한 연산을 줄여 쿼리 실행 시간을 줄인다.
  • 데이터 정규화 및 비정규화: 정규화로 데이터 중복을 최소화하고, 필요한 경우 비정규화로 빠른 읽기 성능을 지원한다.

c) 비동기 처리 및 분산 처리

  • 비동기 요청 처리: 오래 걸리는 작업(예: 파일 처리, 데이터 분석)은 비동기로 처리하여 사용자 경험을 개선한다.
  • 분산 작업 처리: Redis, Kafka, RabbitMQ 등의 메시지 큐를 활용해 비동기 분산 처리를 적용한다.

d) 네트워크 최적화

  • CDN 사용: 전 세계에 분산된 CDN 서버로부터 데이터를 제공하여 사용자와의 물리적 거리를 줄인다.
  • HTTP/2 및 Keep-Alive 사용: 다중 요청을 병렬로 처리하고, 연결을 유지해 다수의 리소스 로딩 시간을 줄인다.
  • Gzip 압축: 텍스트 기반 파일을 Gzip으로 압축하여 전송 시간을 절감한다.

e) 웹 서버 최적화

  • 서버 자원 모니터링: CPU, 메모리, 네트워크 I/O 등의 리소스 사용량을 주기적으로 확인해 병목 현상을 파악하고 개선한다.
  • 로드 밸런싱: 웹 서버 여러 대로 트래픽을 분산하여 서버 과부하를 방지한다.
  • 컨테이너 오케스트레이션: Docker, Kubernetes를 사용해 애플리케이션을 효율적으로 배포하고 스케일링한다.

2. 트러블슈팅 방안

a) 성능 모니터링 및 로깅

  • 애플리케이션 성능 모니터링(APM): Datadog, New Relic, Prometheus 등을 사용해 트랜잭션 및 요청 시간을 추적하여 성능 저하 원인을 파악한다.
  • 로그 분석: Elastic Stack, Splunk 등의 로그 분석 도구로 예외 발생 원인 및 에러 로그를 조사해 이슈를 해결한다.

b) 데이터베이스 트러블슈팅

  • 쿼리 성능 분석: 쿼리 실행 계획을 통해 쿼리 실행 속도가 느린 원인을 분석하고 최적화한다.
  • 잠금(lock) 현상 분석: 데이터베이스 잠금으로 인해 트랜잭션이 지연되는 문제를 확인하고 잠금이 걸리지 않도록 구조를 조정한다.

c) 네트워크 및 API 트러블슈팅

  • 패킷 캡처 도구 활용: Wireshark, tcpdump 등을 이용해 네트워크 패킷을 분석하고 성능 병목 구간을 파악한다.
  • API 성능 테스트 및 타임아웃 설정: API 응답 시간이 긴 경우에는 시간 초과 설정을 조정하거나, API 속도를 높이기 위한 최적화 방안을 모색한다.

d) 코드 최적화

  • 메모리 누수 방지: GC 로그를 통해 메모리 누수가 발생하는지 확인하고, 메모리 누수를 일으키는 코드 수정 및 객체 관리를 개선한다.
  • 코드 프로파일링: CPU 및 메모리 사용량을 분석해 성능에 영향을 주는 비효율적인 코드(예: 중복 연산)를 최적화한다.

e) 서버 및 인프라 문제 해결

  • 서버 리소스 조정: 서버 스펙 업그레이드 또는 서버 대수를 조정하여 병목 현상을 해결한다.
  • 컨테이너 상태 확인 및 재배포: 오작동하는 컨테이너가 있다면 상태를 확인하고 재배포하여 안정성을 확보한다.

2024년 9월 24일 화요일

헤드리스 아키텍처 Headless

"헤드리스"라는 단어는 본래의 의미에서 "머리(Head)가 없는" 것을 가리킨다. 헤드리스 아키텍처에서 이 용어를 사용한 이유는, 전통적인 소프트웨어 아키텍처와 비교할 때 프론트엔드(사용자 인터페이스, 즉 '머리'에 해당하는 부분)가 백엔드와 분리되어 독립적으로 동작하기 때문이다.

이유 및 배경:

  1. 전통적인 시스템 구조:
    • 과거의 전통적인 커머스 시스템이나 CMS(콘텐츠 관리 시스템)에서는 프론트엔드(웹페이지 UI)와 백엔드(서버, 데이터베이스, 비즈니스 로직)가 긴밀하게 결합된 형태로 동작했다. 백엔드는 데이터 및 로직을 처리하고, 동시에 프론트엔드를 통해 사용자에게 데이터를 표시하는 역할까지 담당했다. 여기서 프론트엔드가 일종의 "머리" 역할을 했다.
  2. 헤드리스 구조:
    • 헤드리스 아키텍처에서는 백엔드가 "머리(프론트엔드)"가 없는 상태로, 단순히 데이터를 처리하고 API로 결과를 제공한다. 프론트엔드는 백엔드와 독립적으로 존재하며, REST API 또는 GraphQL을 통해 필요한 데이터를 받아서 처리하고 사용자에게 보여준다.
    • 여기서 "머리(Head)"에 해당하는 프론트엔드가 사라졌으므로, 이를 "헤드리스"라고 부른다.

장점:

  • 프론트엔드와 백엔드의 독립성: 프론트엔드를 다양한 기술로 자유롭게 구축할 수 있다. 웹, 모바일 앱, IoT 등 다양한 플랫폼에 적용 가능.
  • 유연성: 하나의 백엔드에 여러 "헤드"(웹사이트, 모바일 앱 등)를 연결할 수 있어 다양한 사용자 경험을 제공할 수 있다.

"헤드리스"라는 용어는 백엔드가 특정 프론트엔드에 종속되지 않고, 다양한 프론트엔드로 확장 가능한 상태를 나타내기 위해 사용된다.

2024년 8월 14일 수요일

마우스 클릭과 더블클릭 구분하여 더블클릭 방지 처리 : JavaScript ES6 React

click 이벤트와 dblclick 이벤트를 사용하고, 클릭을 setTimeout으로 일정 시간 동안 지연시켜 더블클릭인지 단일 클릭인지 확인하는 방법을 사용한다.

JavaScript로 작성한 후 React 버전으로 수정 작성하였다.

모듈 파일 (handlers.js)

setupDblClickHandler 함수는 더블 클릭 시 클릭 타이머를 정리하는 역할만 수행한다.

// handlers.js

const clickTimeouts = new WeakMap();

export function setupClickHandler(element, handleClick) {
    element.addEventListener("click", function(event) {
        clearTimeout(clickTimeouts.get(element)); // 기존 타이머 클리어
        const timeout = setTimeout(function() {
            handleClick(event);
        }, 500); // 500ms 후에 클릭 이벤트로 처리
        clickTimeouts.set(element, timeout); // 새로운 타이머 저장
    });
}

export function setupDblClickHandler(element) {
    element.addEventListener("dblclick", function() {
        clearTimeout(clickTimeouts.get(element)); // 기존 타이머 클리어
    });
}

메인 파일 (main.js)

// main.js

import { setupClickHandler, setupDblClickHandler } from './handlers.js';

document.addEventListener("DOMContentLoaded", function() {
    // 예제 핸들러 함수
    function exampleClickHandler(event) {
        alert(`Single Click Detected on element: ${event.target.id}`);
    }

    // 요소를 동적으로 선택
    var button1 = document.getElementById("myButton1");
    var button2 = document.getElementById("myButton2");

    // 동적 핸들러를 각 요소에 설정
    setupClickHandler(button1, exampleClickHandler);
    setupClickHandler(button2, exampleClickHandler);
    setupDblClickHandler(button1);
    setupDblClickHandler(button2);
});

HTML 파일

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dynamic Element and Handler</title>
</head>
<body>
    <button id="myButton1">Click or Double Click Me</button>
    <button id="myButton2">Another Button</button>

    <script type="module" src="main.js"></script>
</body>
</html>

코드 설명

  1. setupClickHandler: 클릭 이벤트가 발생하면 타이머를 설정하여 단일 클릭 이벤트를 처리한다.
    • 이전 타이머를 정리하고 새로운 타이머를 설정하여 500ms 후에 handleClick 함수를 호출한다.
  2. setupDblClickHandler: 더블 클릭 이벤트가 발생하면 타이머를 정리한다.
    • 클릭 타이머를 정리하여 단일 클릭 이벤트가 호출되지 않도록 한다.
  3. exampleClickHandler: 단일 클릭 이벤트 핸들러로, 클릭된 요소의 ID를 alert 창에 표시한다.
  4. HTML 파일: main.jstype="module"로 포함하여 모듈 시스템을 사용한다.

주의 사항

  • 이 구조에서는 더블 클릭 시 추가 로직을 처리하지 않는다. 만약 더블 클릭에 다른 동작을 추가하고 싶다면, setupDblClickHandler 함수를 다시 확장해야 한다.
  • 최신 브라우저 환경에서 작동하도록 설계되었기 때문에 구형 브라우저에서는 ES6 모듈과 WeakMap 지원을 확인해야 한다.

React에서 사용 가능하도록 수정한 버전 1

React에서 setupClickHandlersetupDblClickHandler 기능을 제공하는 방법으로, 커스텀 훅을 사용하여 단일 클릭과 더블 클릭을 구분하는 로직을 구현할 수 있다. 커스텀 훅은 재사용 가능한 로직을 추상화하고 컴포넌트에서 쉽게 사용할 수 있도록 도와준다.

아래는 useClickHandler라는 커스텀 훅을 작성하고 이를 React 컴포넌트에서 사용하는 예시이다.

1. useClickHandler 커스텀 훅 작성

hooks/useClickHandler.js

단일 클릭과 더블 클릭을 처리할 수 있는 useClickHandler 훅을 작성한다. 이 훅은 clickHandler를 인자로 받아서 클릭 이벤트와 더블 클릭 이벤트를 처리한다.

// hooks/useClickHandler.js

import { useRef, useEffect } from 'react';

export function useClickHandler(clickHandler) {
    const clickTimeoutRef = useRef(null);

    useEffect(() => {
        // 타이머를 클리어하는 함수
        const clearClickTimeout = () => {
            if (clickTimeoutRef.current) {
                clearTimeout(clickTimeoutRef.current);
                clickTimeoutRef.current = null;
            }
        };

        const handleClick = (event) => {
            clearClickTimeout();
            clickTimeoutRef.current = setTimeout(() => {
                clickHandler(event);
            }, 300); // 300ms 후에 클릭 이벤트로 처리
        };

        const handleDblClick = () => {
            clearClickTimeout(); // 더블 클릭 시 타이머 클리어
        };

        return { handleClick, handleDblClick };
    }, [clickHandler]);

    return { handleClick, handleDblClick };
}

2. React 컴포넌트에서 훅 사용

useClickHandler 훅을 사용하여 클릭 이벤트와 더블 클릭 이벤트를 처리하는 예제 컴포넌트를 작성한다.

components/ClickHandlerComponent.js

// components/ClickHandlerComponent.js

import React from 'react';
import { useClickHandler } from '../hooks/useClickHandler';

export function ClickHandlerComponent() {
    const { handleClick, handleDblClick } = useClickHandler((event) => {
        alert(`Single Click Detected on element: ${event.target.id}`);
    });

    return (
        <div>
            <button
                id="myButton1"
                onClick={handleClick}
                onDoubleClick={handleDblClick}
            >
                Click or Double Click Me
            </button>
            <button
                id="myButton2"
                onClick={handleClick}
                onDoubleClick={handleDblClick}
            >
                Another Button
            </button>
        </div>
    );
}

3. 앱 컴포넌트

React 앱에서 ClickHandlerComponent를 사용.

App.js

// App.js

import React from 'react';
import { ClickHandlerComponent } from './components/ClickHandlerComponent';

function App() {
    return (
        <div className="App">
            <h1>React Click and Double Click Handler</h1>
            <ClickHandlerComponent />
        </div>
    );
}

export default App;

4. 프로젝트 구조

/project-root
    ├── /src
    │    ├── /components
    │    │    └── ClickHandlerComponent.js
    │    ├── /hooks
    │    │    └── useClickHandler.js
    │    └── App.js
    ├── index.html
    └── index.js

코드 설명

  1. useClickHandler:
    • clickTimeoutRef를 사용하여 클릭 타이머를 관리한다.
    • handleClickhandleDblClick 함수는 각각 클릭과 더블 클릭 이벤트를 처리한다.
    • clearClickTimeout 함수는 타이머를 클리어하여 단일 클릭과 더블 클릭을 구분한다.
    • useEffectclickHandler가 변경될 때마다 새로 등록된 핸들러를 업데이트 한다.
  2. ClickHandlerComponent 컴포넌트:
    • useClickHandler 훅을 사용하여 클릭 및 더블 클릭 핸들러를 생성한다.
    • 각 버튼에 handleClickhandleDblClick을 이벤트 핸들러로 설정한다.
  3. App 컴포넌트:
    • ClickHandlerComponent를 사용하여 버튼 클릭 이벤트를 처리합니다.

추가 사항

  • 의존성 관리: useClickHandler 훅은 clickHandler가 변경될 때마다 타이머를 관리하도록 의존성을 설정한다.
  • 타이머 관리: 타이머는 useRef로 관리되어 컴포넌트가 리렌더링되더라도 상태가 유지된다.

React에서 사용 가능하도록 수정한 버전 2

React에서 이벤트 핸들러를 설정하고 단일 클릭과 더블 클릭을 구분하기 위해, Hook을 사용하여 상태를 관리할 수 있다. 아래 예시에서는 useEffectuseRef를 사용하여 DOM 이벤트를 설정하고, useState를 사용하여 클릭 타이머 상태를 관리한다.

1. Custom Hook (useClickHandler.js)

먼저, 클릭과 더블 클릭 핸들러를 설정하는 Custom Hook을 정의한다.

// useClickHandler.js

import { useEffect, useRef } from 'react';

const useClickHandler = (elementRef, handleClick) => {
  const clickTimeoutRef = useRef(null);

  useEffect(() => {
    const element = elementRef.current;

    const handleSingleClick = (event) => {
      clearTimeout(clickTimeoutRef.current);
      clickTimeoutRef.current = setTimeout(() => {
        handleClick(event);
      }, 300); // 300ms 후에 클릭 이벤트로 처리
    };

    const handleDoubleClick = (event) => {
      clearTimeout(clickTimeoutRef.current); // 더블 클릭 시 타이머 클리어
    };

    if (element) {
      element.addEventListener('click', handleSingleClick);
      element.addEventListener('dblclick', handleDoubleClick);
    }

    // Cleanup 이벤트 리스너
    return () => {
      if (element) {
        element.removeEventListener('click', handleSingleClick);
        element.removeEventListener('dblclick', handleDoubleClick);
      }
    };
  }, [elementRef, handleClick]);
};

export default useClickHandler;

2. 컴포넌트 파일 (MyComponent.js)

Custom Hook을 사용하여 단일 클릭 이벤트 핸들러를 설정하는 컴포넌트를 작성한다.

// MyComponent.js

import React, { useRef } from 'react';
import useClickHandler from './useClickHandler';

const MyComponent = () => {
  const buttonRef1 = useRef(null);
  const buttonRef2 = useRef(null);

  const handleClick = (event) => {
    alert(`Single Click Detected on element: ${event.target.id}`);
  };

  useClickHandler(buttonRef1, handleClick);
  useClickHandler(buttonRef2, handleClick);

  return (
    <div>
      <button id="myButton1" ref={buttonRef1}>Click or Double Click Me</button>
      <button id="myButton2" ref={buttonRef2}>Another Button</button>
    </div>
  );
};

export default MyComponent;

코드 설명

  1. Custom Hook (useClickHandler.js):
    • useClickHandlerelementRefhandleClick을 인자로 받는다.
    • clickTimeoutRefuseRef를 사용하여 클릭 타이머를 저장한다.
    • useEffect를 사용하여 컴포넌트가 마운트될 때 이벤트 리스너를 설정하고 언마운트될 때 정리한다.
    • 단일 클릭 이벤트를 처리하는 handleSingleClick과 더블 클릭 시 타이머를 정리하는 handleDoubleClick을 정의한다.
  2. 컴포넌트 파일 (MyComponent.js):
    • buttonRef1buttonRef2는 각각 두 버튼의 참조를 저장한다.
    • handleClick은 단일 클릭 이벤트 핸들러로, 클릭된 요소의 idalert로 표시한다.
    • useClickHandler를 사용하여 각 버튼에 대해 클릭 핸들러를 설정한다.
    • 버튼 요소에 ref 속성을 설정하여 DOM 요소를 참조할 수 있게 한다.

React 애플리케이션 구조

/src
    /components
        MyComponent.js
    /hooks
        useClickHandler.js
    index.js

React 애플리케이션 설정

index.js

애플리케이션의 진입점으로, MyComponent를 렌더링.

import React from 'react';
import ReactDOM from 'react-dom';
import MyComponent from './components/MyComponent';

ReactDOM.render(
  <React.StrictMode>
    <MyComponent />
  </React.StrictMode>,
  document.getElementById('root')
);

2024년 8월 13일 화요일

docker-compose : 특정 서비스 최신 이미지 강제로 Pull 한 후 다시 시작

docker-compose 명령을 사용하여 특정 서비스의 최신 이미지를 강제로 pull 한 후 재실행하려면 docker-compose pull 명령과 docker-compose up 명령을 결합하여 사용할 수 있다.

단계별 설명

  1. ECR 로그인

    aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <aws_account_id>.dkr.ecr.<region>.amazonaws.com
    
  2. 이미지 Pull

    docker-compose pull 명령을 사용하여 최신 이미지를 pull 한다. 특정 서비스만 pull 할 수 있다:

    docker-compose pull app
    
  3. 서비스 재실행

    docker-compose up 명령을 사용하여 특정 서비스를 재실행:

    docker-compose up -d app
    

두 명령을 한 번에 실행:

docker-compose pull app && docker-compose up -d app

자동화를 위한 스크립트

위의 명령을 쉘 스크립트로 만들어 사용하면 더 편리하게 사용할 수 있다.

#!/bin/bash

# ECR 로그인
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <aws_account_id>.dkr.ecr.<region>.amazonaws.com

# 최신 이미지 pull
docker-compose pull app

# 서비스 재실행
docker-compose up -d app

2024년 6월 28일 금요일

AWS Freetier 프리티어 사용 및 과금 발생 확인: 퍼블릭 IPv4

 

1. 서비스 구성

프런트엔드 Front-end

  • React NextJS SSR
  • S3 + CloudFront

백엔드 Back-end

  • Python
  • Docker + uvicorn
  • ALB + Auto Scaling + EC2 + S3

실 운영환경으로 구성하기 위하여 백엔드 서비스에 ALB와 오토스케일링 그룹까지 생성하였다.

처음 생각한 백엔드 서비스 구성은 ALB + Fargate + ECS + ECR 이었지만 프리티어를 사용해야 하기 때문에 Fargate는 포기함.

NextJS로 구현한 프런트 사이트도 정상적으로 동작하였고 프런트에서 백엔드 API도 정상적으로 호출되어 서비스는 문제없이 구축되었다.

2. 과금 정보 및 비용 관리

AWS 루트 계정의 과금 정보 및 비용 관리 홈으로 이동 후 프리 티어를 확인하였다.

사용 중인 프리 티어 목록을 확인할 수 있다.

청구 예정 금액은 청구서로 이동하여 확인 가능하다.

3. 청구서 과금 발생 !!

며칠 서비스 운영 후 청구서를 확인해 보니 과금이 발생하고 있었다.

  • 위 청구서 캡쳐 참조

Virtual Private Cloud (VPC)

정확히는 VPC에서 사용되는 Public IPv4 Addresses 에 대하여 과금이 발생하였다.

프리 티어로 사용되는 시간만큼 합산하여 무료가 될 것으로 생각하였으나 과금 체계는 다른 것으로 보인다.

  1. $0.00 per In-use public IPv4 address per hour for EC2 Free Tier
  2. $0.005 per In-use public IPv4 address per hour

2번으로 과금되는 서비스가 무엇일까?

4. 과금 원인 파악

EC2 > 네트워크 및 보안 > 네트워크 인터페이스 로 이동하여 목록을 확인해 보니 퍼블릭 IPv4 주소가 3개가 생성되어 있었다.

EC2 인스턴스에서 1개, ALB에 연결된 VPC의 서브넷 2개에서 각각 1개 생성하여 총 3개의 퍼블릭 IP가 생성됨.

EC2의 파이썬 도커에서 외부 공공 API를 호출해야 하기 때문에 EC2에서는 퍼블릭 IP가 필요하였다.

결국 ALB를 삭제하고 프런트 엔드에서 호출하는 백엔드 API의 도메인은 ALB 대신 EC2의 도메인으로 변경하여 다시 배포하였다.

ALB 대신 NLB 사용하여 서브넷을 하나만 사용하도록 하여 LB용 퍼블릭 IP를 1개만 생성하도록 하면 EC2 1개 NLB 1개 사용으로 2개 모두 프리 티어 대상이 될 수도 있을 듯 하다. (구성 후 확인은 하지 않았다)


AWS Support 답변

안녕하세요, AWS 고객지원팀입니다.

프리 티어 사용 중 발생한 VPC 요금과 관련하여 문의해 주신 것으로 이해하였습니다.
답변에 앞서, 2024년 2월 1일자로 서비스 연결 여부에 관계없이 모든 퍼블릭 IPv4 주소에 대해 시간당 IP당 0.005 USD의 요금이 부과되는 점 참고해 주시기 바랍니다. IPv4 주소 요금과 관련한 자세한 내용은 다음 링크에서 확인할 수 있습니다:

https://aws.amazon.com/ko/blogs/korea/new-aws-public-ipv4-address-charge-public-ip-insights/

Elastic Compute Cloud 인스턴스와 연결된 IPv4 주소의 경우, 1년간의 프리 티어 사용량에 해당하여 비용이 발생하고 있지 않습니다. 다만, EC2 외 서비스의 퍼블릭 IPv4 주소에 대해서는 프리 티어 사용량에 해당하지 않아 비용이 발생하고 있습니다.

문의하신 VPC 요금을 중단하기 위해서는 VPC에서 요청자 관리형 네트워크 인터페이스를 생성한 모든 리소스를 종료하거나 삭제해야 합니다. 예를 들어 퍼블릭 IPv4를 사용하는 Application Load Balancer(ALB)를 종료하고 NAT 게이트웨이, 전송 게이트웨이 VPC 연결 및 인터페이스 VPC 엔드포인트를 삭제해야 하는 점 참고해 주시기 바랍니다.


프리 티어 사용 시 청구서를 꼭 확인해야 하고 대부분은 VPC의 퍼블릭 IPv4에서 과금이 발생할 수 있을 것으로 보인다.

관련 사이트 및 블로그