<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>삽질기록</title>
    <link>https://try-it.tistory.com/</link>
    <description>상상 컨테이너</description>
    <language>ko</language>
    <pubDate>Thu, 27 Aug 2026 10:30:05 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>copcat</managingEditor>
    <image>
      <title>삽질기록</title>
      <url>https://tistory1.daumcdn.net/tistory/4335150/attach/9f72a985d84d45d38a41b329a4f2b94b</url>
      <link>https://try-it.tistory.com</link>
    </image>
    <item>
      <title>Gradle 의존성 이해하기</title>
      <link>https://try-it.tistory.com/76</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;build.gradle&lt;/code&gt;에 의존성을 추가하다 보면 다음과 같은 설정을 자주 보게 됩니다.&lt;/p&gt;
&lt;pre class=&quot;sml&quot;&gt;&lt;code&gt;dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-webmvc'
    runtimeOnly 'com.mysql:mysql-connector-j'
    testImplementation 'org.testcontainers:mysql'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 다음과 같은 의문이 생깁니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;왜 Spring MVC는 &lt;code&gt;implementation&lt;/code&gt;일까요?&lt;/li&gt;
&lt;li&gt;MySQL 드라이버는 왜 &lt;code&gt;runtimeOnly&lt;/code&gt;일까요?&lt;/li&gt;
&lt;li&gt;Testcontainers는 왜 &lt;code&gt;testImplementation&lt;/code&gt;일까요?&lt;/li&gt;
&lt;li&gt;&lt;code&gt;compileOnly&lt;/code&gt;는 정확히 언제 사용하는 걸까요?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서는 Gradle configuration을 단순히 외우기보다, 어떤 기준으로 선택하는지 이해해보겠습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 컴파일과 런타임의 차이&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 컴파일과 런타임을 구분해야 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;컴파일&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java 소스 코드를 JVM이 실행할 수 있는 바이트코드로 변환하는 과정입니다.&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;.java 파일 &amp;rarr; 컴파일러 &amp;rarr; .class 파일&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 소스 코드에서 사용하는 클래스와 인터페이스를 컴파일러가 알아야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 다음 코드가 있습니다.&lt;/p&gt;
&lt;pre class=&quot;crystal&quot;&gt;&lt;code&gt;import org.springframework.web.bind.annotation.RestController;

@RestController
public class TicketController {
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴파일러는 &lt;code&gt;RestController&lt;/code&gt;가 어떤 타입인지 알아야 합니다. 따라서 Spring MVC 라이브러리가 컴파일 classpath에 있어야 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;런타임&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴파일된 애플리케이션을 실제로 실행하는 시점입니다.&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;./gradlew bootRun&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;런타임에는 다음과 같은 작업이 발생할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터베이스 연결&lt;/li&gt;
&lt;li&gt;JDBC 드라이버 탐색&lt;/li&gt;
&lt;li&gt;리플렉션&lt;/li&gt;
&lt;li&gt;ServiceLoader 기반 구현체 탐색&lt;/li&gt;
&lt;li&gt;Spring Boot 자동 구성&lt;/li&gt;
&lt;li&gt;설정 파일을 통한 구현체 선택&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴파일할 때 직접 타입을 사용하지 않았더라도 실행 중에 필요한 라이브러리가 있을 수 있습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Gradle configuration은 의존성의 출입증입니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;implementation&lt;/code&gt;, &lt;code&gt;runtimeOnly&lt;/code&gt;, &lt;code&gt;testImplementation&lt;/code&gt;은 단순한 라벨이 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gradle에 다음 정보를 알려주는 설정입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;언제 필요한가?&lt;/li&gt;
&lt;li&gt;어떤 소스에서 사용하는가?&lt;/li&gt;
&lt;li&gt;다른 프로젝트에 공개해야 하는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gradle은 선언된 configuration을 바탕으로 작업별 classpath를 만듭니다.&lt;/p&gt;
&lt;pre class=&quot;gradle&quot;&gt;&lt;code&gt;의존성 선언
    &amp;darr;
Gradle이 작업별 classpath 계산
    &amp;darr;
컴파일&amp;middot;실행&amp;middot;테스트가 classpath 사용&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대표적인 classpath는 다음과 같습니다.&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Classpath&lt;/th&gt;
&lt;th&gt;사용 시점&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;compileClasspath&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;main 코드 컴파일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;runtimeClasspath&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;애플리케이션 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;testCompileClasspath&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;테스트 코드 컴파일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;testRuntimeClasspath&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;테스트 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Configuration과 실제 classpath의 관계를 단순화하면 다음과 같습니다.&lt;/p&gt;
&lt;pre class=&quot;clean&quot;&gt;&lt;code&gt;implementation
    ├─ compileClasspath
    └─ runtimeClasspath

runtimeOnly
    └─ runtimeClasspath

testImplementation
    ├─ testCompileClasspath
    └─ testRuntimeClasspath&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. &lt;code&gt;implementation&lt;/code&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;implementation&lt;/code&gt;은 현재 애플리케이션의 컴파일과 실행에 필요한 기본 configuration입니다.&lt;/p&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-webmvc'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 애플리케이션 코드에서 직접 Spring 타입을 사용한다고 가정해보겠습니다.&lt;/p&gt;
&lt;pre class=&quot;crystal&quot;&gt;&lt;code&gt;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TicketController {

    @GetMapping(&quot;/tickets&quot;)
    public String tickets() {
        return &quot;tickets&quot;;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드를 컴파일하려면 Spring MVC가 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 애플리케이션을 실행하려면 Spring MVC의 실제 구현체도 필요합니다.&lt;/p&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;컴파일: Spring 타입을 직접 사용
실행: Spring MVC 애플리케이션 실행&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &lt;code&gt;implementation&lt;/code&gt;을 사용합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;code&gt;implementation&lt;/code&gt;을 선택하는 기준&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 질문에 &amp;ldquo;예&amp;rdquo;라고 답할 수 있다면 &lt;code&gt;implementation&lt;/code&gt;을 우선 고려하면 됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;main 코드에서 직접 import하는가?&lt;/li&gt;
&lt;li&gt;어노테이션이나 인터페이스로 사용하는가?&lt;/li&gt;
&lt;li&gt;컴파일할 때 필요한가?&lt;/li&gt;
&lt;li&gt;애플리케이션 실행에도 필요한가?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재처럼 하나의 Spring Boot 애플리케이션을 만드는 경우에는 대부분의 일반적인 라이브러리가 &lt;code&gt;implementation&lt;/code&gt;으로 들어갑니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. &lt;code&gt;runtimeOnly&lt;/code&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;runtimeOnly&lt;/code&gt;는 컴파일할 때 직접 타입을 사용할 필요는 없지만, 애플리케이션 실행 중에는 필요한 의존성입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대표적인 예가 MySQL JDBC 드라이버입니다.&lt;/p&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;dependencies {
    runtimeOnly 'com.mysql:mysql-connector-j'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션 코드에서 보통 다음과 같은 코드를 직접 작성하지 않습니다.&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;import com.mysql.cj.jdbc.Driver;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대신 Spring Boot와 JDBC가 설정된 JDBC URL을 바탕으로 실행 중에 드라이버를 찾습니다.&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;spring:
  datasource:
    url: jdbc:mysql://localhost:3306/ticketing&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MySQL 드라이버의 사용 시점은 다음과 같습니다.&lt;/p&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;컴파일: 애플리케이션 코드에서 드라이버 타입을 직접 사용하지 않음
실행: MySQL 연결을 만들기 위해 드라이버 필요&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &lt;code&gt;runtimeOnly&lt;/code&gt;가 적절합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;code&gt;implementation&lt;/code&gt;으로 넣으면 안 되는가?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 선언해도 애플리케이션은 동작할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;clean&quot;&gt;&lt;code&gt;implementation 'com.mysql:mysql-connector-j'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 &lt;code&gt;runtimeOnly&lt;/code&gt;가 의도를 더 정확하게 표현합니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 애플리케이션 코드는 MySQL 드라이버 구현 타입을 직접 사용하지 않지만, 실행할 때는 드라이버가 필요합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, &lt;code&gt;runtimeOnly&lt;/code&gt;는 의존성의 사용 범위를 더 좁게 선언하는 방법입니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. &lt;code&gt;testImplementation&lt;/code&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;testImplementation&lt;/code&gt;은 테스트 코드의 컴파일과 실행에만 필요한 의존성입니다.&lt;/p&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;dependencies {
    testImplementation 'org.testcontainers:mysql'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Testcontainers를 사용하는 테스트는 다음과 같이 작성할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;MySQLContainer&amp;lt;?&amp;gt; mysql =
        new MySQLContainer&amp;lt;&amp;gt;(&quot;mysql:8.4&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 타입은 운영 애플리케이션 코드가 아니라 테스트 코드에서만 사용합니다.&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;운영 애플리케이션: Testcontainers 불필요
테스트 코드: MySQLContainer 타입 필요&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &lt;code&gt;testImplementation&lt;/code&gt;을 사용합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;중요한 점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;testImplementation&lt;/code&gt;은 테스트 컴파일에만 사용된다는 뜻이 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 코드에서 직접 타입을 사용해야 하므로 다음 두 시점에 필요합니다.&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;테스트 컴파일: MySQLContainer 타입을 알아야 함
테스트 실행: 실제 컨테이너를 실행해야 함&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 운영 애플리케이션의 main runtime classpath에는 포함되지 않습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. &lt;code&gt;compileOnly&lt;/code&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;compileOnly&lt;/code&gt;는 컴파일할 때는 필요하지만, 애플리케이션 실행 시에는 해당 실행 환경이 제공한다고 가정하는 의존성입니다.&lt;/p&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;dependencies {
    compileOnly 'jakarta.servlet:jakarta.servlet-api:버전'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의미는 다음과 같습니다.&lt;/p&gt;
&lt;pre class=&quot;gradle&quot;&gt;&lt;code&gt;컴파일: 필요
애플리케이션 실행 classpath: 포함하지 않음&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 애플리케이션 서버가 Servlet API를 제공한다고 가정할 수 있다면, 소스 코드를 컴파일하기 위한 타입 정보만 필요할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;code&gt;compileOnly&lt;/code&gt;를 잘못 사용하면?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행할 때 실제로 필요한 라이브러리를 &lt;code&gt;compileOnly&lt;/code&gt;로 선언하면 문제가 발생합니다.&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;컴파일 성공
    &amp;darr;
애플리케이션 실행
    &amp;darr;
ClassNotFoundException
또는 NoClassDefFoundError&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &lt;code&gt;compileOnly&lt;/code&gt;를 사용할 때는 반드시 다음을 확인해야 합니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 환경이 정말 이 라이브러리를 제공하는가?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 환경이 제공하지 않는다면 &lt;code&gt;implementation&lt;/code&gt;을 사용해야 합니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. Lombok은 왜 &lt;code&gt;compileOnly&lt;/code&gt;인가?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lombok은 조금 특수한 예시입니다.&lt;/p&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;dependencies {
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같은 코드를 작성한다고 가정해보겠습니다.&lt;/p&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;@Getter
public class Ticket {
    private Long id;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lombok은 컴파일 과정에서 getter 메서드를 생성합니다.&lt;/p&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;public Long getId() {
    return id;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 시점에는 이미 getter 코드가 생성되어 있으므로 Lombok 라이브러리 자체가 필요하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 설정의 역할은 다음과 같습니다.&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;설정&lt;/th&gt;
&lt;th&gt;역할&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;compileOnly&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;컴파일러가 Lombok 어노테이션 타입을 알 수 있게 함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;annotationProcessor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;컴파일 중 실제 코드를 생성&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 Lombok은 다음과 같습니다.&lt;/p&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;컴파일: 필요
코드 생성: 필요
실행: 불필요&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;8. &lt;code&gt;testRuntimeOnly&lt;/code&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;testRuntimeOnly&lt;/code&gt;는 테스트 소스 코드에서 타입을 직접 사용하지 않지만, 테스트 실행 순간에 필요한 의존성입니다.&lt;/p&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;dependencies {
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 코드에서 직접 &lt;code&gt;junit-platform-launcher&lt;/code&gt;의 타입을 import하지는 않지만, 테스트 실행 엔진이 동작하려면 필요할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;테스트 코드 컴파일: 불필요
테스트 실행: 필요&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 경우 &lt;code&gt;testRuntimeOnly&lt;/code&gt;를 사용합니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;9. &lt;code&gt;api&lt;/code&gt;와 &lt;code&gt;implementation&lt;/code&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;api&lt;/code&gt;는 여러 프로젝트가 함께 사용하는 라이브러리 모듈에서 중요합니다.&lt;/p&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;plugins {
    id 'java-library'
}

dependencies {
    api 'com.fasterxml.jackson.core:jackson-databind:버전'
    implementation 'org.apache.commons:commons-lang3:버전'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 라이브러리의 public API에 외부 라이브러리 타입이 등장한다면 &lt;code&gt;api&lt;/code&gt;를 고려합니다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;public interface TicketPolicy {

    ExternalTicketType findTicket(Long ticketId);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;ExternalTicketType&lt;/code&gt;이 외부 라이브러리의 타입이라면, 이 라이브러리를 사용하는 프로젝트도 해당 타입을 알아야 컴파일할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 &lt;code&gt;api&lt;/code&gt;를 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 외부 라이브러리를 내부 구현에서만 사용한다면 &lt;code&gt;implementation&lt;/code&gt;이 적절합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재처럼 하나의 Spring Boot 애플리케이션을 만드는 단계에서는 &lt;code&gt;api&lt;/code&gt;보다 다음 설정을 먼저 이해하는 것이 좋습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;implementation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;runtimeOnly&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testImplementation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;compileOnly&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;10. configuration 선택 순서&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 의존성을 추가할 때는 다음 순서로 판단하면 됩니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1. main 코드가 라이브러리 타입을 직접 사용하는가?

   ├─ 실행에도 필요하다
   │   └─ implementation

   └─ 실행 환경이 제공한다
       └─ compileOnly


2. main 코드에서 직접 사용하지 않지만
   실행 중 프레임워크가 찾는가?

   └─ runtimeOnly


3. src/test에서만 사용하는가?

   ├─ 테스트 코드가 타입을 직접 사용한다
   │   └─ testImplementation

   └─ 테스트 실행 순간에만 필요하다
       └─ testRuntimeOnly&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 쉽게 요약하면 다음과 같습니다.&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;질문&lt;/th&gt;
&lt;th&gt;선택&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;애플리케이션 코드가 직접 사용하고 실행에도 필요한가?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;implementation&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;컴파일에는 필요하지만 실행 환경이 제공하는가?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;compileOnly&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;코드에서 직접 사용하지 않지만 실행 중 필요한가?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;runtimeOnly&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;테스트 코드에서 직접 사용하는가?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;testImplementation&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;테스트 실행 순간에만 필요한가?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;testRuntimeOnly&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애매할 때는 &lt;code&gt;implementation&lt;/code&gt;을 기본값으로 선택하고, 실제 사용 범위가 명확해졌을 때 configuration을 좁히면 됩니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;11. Gradle classpath 직접 확인하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gradle이 실제로 어떤 의존성을 넣었는지 확인할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;컴파일 classpath&lt;/h3&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;./gradlew dependencies --configuration compileClasspath&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;애플리케이션 실행 classpath&lt;/h3&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;./gradlew dependencies --configuration runtimeClasspath&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;테스트 실행 classpath&lt;/h3&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;./gradlew dependencies --configuration testRuntimeClasspath&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 의존성이 왜 포함됐는지 확인하려면 &lt;code&gt;dependencyInsight&lt;/code&gt;를 사용합니다.&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;./gradlew dependencyInsight \
  --dependency mysql-connector-j \
  --configuration runtimeClasspath&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확인할 때는 다음 질문을 던져보면 됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MySQL 드라이버가 &lt;code&gt;compileClasspath&lt;/code&gt;에는 없는가?&lt;/li&gt;
&lt;li&gt;MySQL 드라이버가 &lt;code&gt;runtimeClasspath&lt;/code&gt;에는 있는가?&lt;/li&gt;
&lt;li&gt;Testcontainers가 운영용 &lt;code&gt;runtimeClasspath&lt;/code&gt;에는 없는가?&lt;/li&gt;
&lt;li&gt;테스트 의존성이 &lt;code&gt;testRuntimeClasspath&lt;/code&gt;에는 포함되어 있는가?&lt;/li&gt;
&lt;li&gt;예상하지 못한 전이 의존성이 추가되지는 않았는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gradle configuration은 의존성을 아무 곳에나 넣는 문법이 아닙니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;누가, 언제, 어디까지 이 라이브러리를 볼 수 있어야 하는지를 선언하는 규칙입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 의존성을 추가할 때는 다음 순서로 생각하면 됩니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1. main 코드가 타입을 직접 사용하는가?
2. 실행에도 필요한가?
3. 실행 환경이 대신 제공하는가?
4. 테스트에서만 사용하는가?
5. 테스트 코드가 직접 타입을 사용하는가?&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종적으로 다음처럼 기억하면 됩니다.&lt;/p&gt;
&lt;pre class=&quot;clean&quot;&gt;&lt;code&gt;직접 사용 + 실행에도 필요
    &amp;rarr; implementation

컴파일에는 필요하지만 실행 환경이 제공
    &amp;rarr; compileOnly

직접 사용하지 않지만 실행 중 필요
    &amp;rarr; runtimeOnly

테스트 코드에서 직접 사용
    &amp;rarr; testImplementation

테스트 실행 순간에만 필요
    &amp;rarr; testRuntimeOnly&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고 자료&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/java_library_plugin.html&quot;&gt;Gradle Java Library Plugin 공식 문서&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/dependency_configurations.html&quot;&gt;Gradle Dependency Configurations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/declaring_configurations.html&quot;&gt;Gradle Configuration 선언 및 해결&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/dependency_management_basics.html&quot;&gt;Gradle Dependency Management Basics&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발/Spring &amp;amp; Spring Boot</category>
      <category>boot</category>
      <category>compileOnly</category>
      <category>configuration</category>
      <category>gradle</category>
      <category>implementation</category>
      <category>runtimeOnly</category>
      <category>spring</category>
      <author>copcat</author>
      <guid isPermaLink="true">https://try-it.tistory.com/76</guid>
      <comments>https://try-it.tistory.com/76#entry76comment</comments>
      <pubDate>Tue, 21 Jul 2026 16:31:38 +0900</pubDate>
    </item>
    <item>
      <title>AWS Network Firewall 쓰면 NAT Gateway가 공짜라고? 근데 비용을 곁들인..</title>
      <link>https://try-it.tistory.com/75</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;AWS에서 Private Subnet의 인스턴스가 인터넷에 나가려면 NAT가 필요하고, 트래픽을 검사하려면 방화벽이 필요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;보통은 NAT Gateway와 방화벽을 각각 구성하고 각각 비용을 지불합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그런데 AWS 문서를 보다 보면 이런 문구가 하나 보입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&quot;Network Firewall과 NAT Gateway를 같은 service chain에 두면 NAT Gateway 비용이 면제된다.&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&quot;진짜로 NAT Gateway가 공짜?&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그래서 실제 구조와 비용을 조금 더 자세히 파봤습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이번 글에서는 &lt;b&gt;AWS Network Firewall과 NAT Gateway를 함께 사용했을 때 NAT Gateway 비용이 면제되는 구조&lt;/b&gt;와 함께, &lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;각 서비스가 어떤 역할을 하는지, 그리고 대체 가능한 옵션은 무엇인지 정리해보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;  잠깐, NAT Gateway와 NAT Instance는 다릅니다&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;본론에 들어가기 전에 헷갈리기 쉬운 부분부터 정리하고 가겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 107.442%; height: 299px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;구분&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NAT Gateway&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NAT Instance&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;관리&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;AWS 완전관리형&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;직접 EC2 관리 (패치, 모니터링)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;고가용성&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;AZ 내 자동 이중화&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;직접 구성 필요 (ASG 등)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;대역폭&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;최대 100 Gbps 자동 확장&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;인스턴스 타입에 따라 제한&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;비용&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;$0.059/시간 + $0.059/GB (서울)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;EC2 인스턴스 비용 (예: t3.micro $0.0104/시간)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Network Firewall 할인&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;✅ 적용됨&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;❌ 적용 안 됨&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NAT Instance는 비용이 저렴하다는 장점이 있어 작은 서비스나 테스트 환경에서는 많이 사용됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;하지만 이번 글에서 이야기하는 &lt;b&gt;NAT Gateway 비용 면제 혜택은 NAT Gateway에만 적용&lt;/b&gt;됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;즉, 이미 Network Firewall을 사용하는 환경이라면 NAT Instance 대신 &lt;b&gt;NAT Gateway를 쓰는 것이 오히려 더 유리할 수도 있습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;  각 서비스는 왜 쓸까?&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;AWS Network Firewall&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;AWS Network Firewall&lt;/b&gt;은 VPC 레벨에서 동작하는 관리형 방화벽 서비스입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;대표적인 기능은 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;L3~L4&amp;nbsp;중심&amp;nbsp;+&amp;nbsp;제한적인&amp;nbsp;L7&amp;nbsp;검사&amp;nbsp;(IP, 포트, 도메인, 콘텐츠 기반 필터링)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Suricata 기반 IPS / IDS 룰 지원&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;TLS 복호화 검사 (Advanced Inspection)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;악성 도메인 및 IP 차단&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;한마디로 정리하면,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&quot;이 VPC에서 나가는 트래픽 중 위험한 건 막겠다.&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;라는 목적의 서비스입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NAT Gateway&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;NAT Gateway&lt;/b&gt;는 Private Subnet의 리소스가 인터넷과 통신할 수 있도록 해주는 서비스입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;대표적인 사용 사례는 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;EC2에서 외부 API 호출&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;패키지 다운로드 (&lt;code&gt;apt&lt;/code&gt;, &lt;code&gt;yum&lt;/code&gt;, &lt;code&gt;npm&lt;/code&gt; 등)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;외부 서비스와 통신&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;하지만 외부에서 내부로 직접 접근하는 것은 막습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;즉,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&quot;인터넷은 나가게 하되, 들어오는 건 막겠다.&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;라는 역할을 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;  둘 다 쓰면 뭐가 좋은데? &amp;mdash; NAT Gateway 비용 면제&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;여기가 이 글의 핵심입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;AWS 공식 문서에는 다음과 같이 명시되어 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&quot;If you create a NAT gateway and place it next to your AWS Network Firewall in a service chain within your AWS account, standard NAT gateway per-hour and data processing usage charges are waived.&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;mdash; AWS Network Firewall Pricing&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;즉, &lt;b&gt;Network Firewall과 NAT Gateway를 같은 네트워크 경로에 배치하면 NAT Gateway 비용이 자동 면제됩니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 107.907%; height: 204px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;항목&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;원래 비용 (서울 리전)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Network Firewall과 함께 사용 시&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NAT Gateway 시간당&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;$0.059/시간&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;$0 (면제)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NAT Gateway 데이터 처리&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;$0.059/GB&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;$0 (면제)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;면제 조건&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;다음 조건을 충족해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NAT Gateway와 Network Firewall이 &lt;b&gt;같은 리전&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NAT Gateway가 Network Firewall endpoint와 &lt;b&gt;같은 네트워크 경로&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1:1 기준 적용&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;즉,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Firewall Endpoint 시간 = NAT Gateway 시간&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Firewall 처리량 = NAT Gateway 처리량 &lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이어야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://aws.amazon.com/about-aws/whats-new/2026/02/aws-network-firewall-new-price-reduction/https://aws.amazon.com/network-firewall/pricing/&quot;&gt;AWS Network Firewall 가격 인하 공지 (2026.02)&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;  실제로 얼마나 아끼는 건데? &amp;mdash; 서울 리전 기준 계산&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;시나리오&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2개 AZ 배포&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;월 5TB 아웃바운드 트래픽&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Network Firewall + NAT Gateway (할인 미적용)&lt;/span&gt;&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;항목&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;계산&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;월 비용&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Network Firewall 엔드포인트&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;$0.395 &amp;times; 2 AZ &amp;times; 720시간&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;$568.80&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Network Firewall 데이터 처리&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;$0.065 &amp;times; 5,000 GB&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;$325.00&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NAT Gateway 시간당&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;$0.059 &amp;times; 2 AZ &amp;times; 720시간&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;$84.96&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NAT Gateway 데이터 처리&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;$0.059 &amp;times; 5,000 GB&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;$295.00&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;합계&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;$1,273.76&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Network Firewall + NAT Gateway (할인 적용)&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;height: 115px;&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;th style=&quot;height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;항목&lt;/span&gt;&lt;/th&gt;
&lt;th style=&quot;height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;계산&lt;/span&gt;&lt;/th&gt;
&lt;th style=&quot;height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;월 비용&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Network Firewall 엔드포인트&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;$0.395 &amp;times; 2 AZ &amp;times; 720시간&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;$568.80&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Network Firewall 데이터 처리&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;$0.065 &amp;times; 5,000 GB&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;$325.00&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NAT Gateway 시간당&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;del&gt;$84.96&lt;/del&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;$0 (면제)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NAT Gateway 데이터 처리&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;del&gt;$295.00&lt;/del&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;$0 (면제)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;합계&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;$893.80&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;즉, &lt;b&gt;월 $379.96 절감 (약 30% 비용 감소)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;트래픽이 많을수록 절감 효과는 더 커집니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;  그럼 NAT Instance는 언제 쓰는 게 맞아?&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NAT Gateway가 무료가 되는 것은 &lt;b&gt;이미 Network Firewall을 사용하고 있을 때&lt;/b&gt; 이야기입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Network Firewall을 사용하지 않는 환경에서는 NAT Gateway 비용이 그대로 발생합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그래서 상황에 따라 NAT Instance를 선택하기도 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100.231%; height: 294px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;상황&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.814%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;추천&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Network Firewall 사용 중&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.814%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;NAT Gateway&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Network Firewall 미사용 + 트래픽 적음&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.814%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;NAT Instance&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Network Firewall 미사용 + 트래픽 많음&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.814%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;NAT Gateway&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;개발 / 테스트 환경&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.814%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;NAT Instance&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;특히 작은 프로젝트에서는 NAT Gateway 비용이 생각보다 부담이 될 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;  Network Firewall 안 쓰면 뭘로 대체해?&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Network Firewall은 강력한 서비스지만 모든 환경에서 반드시 필요한 것은 아닙니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 101.977%; height: 302px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;대안&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;보호 수준&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;비용&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;특징&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Security Group + NACL&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;L3/L4&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;무료&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;기본 방화벽&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;AWS WAF&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;L7&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;요청 기반 과금&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;웹 트래픽 보호&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;VPC Endpoint&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;-&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;무료&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NAT 우회 가능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;3rd Party Firewall&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;L3~L7&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;라이선스 + EC2&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Fortinet / Palo Alto&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;실전 팁&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;S3, DynamoDB 같은 AWS 서비스 접근은 &lt;b&gt;Gateway VPC Endpoint&lt;/b&gt;를 사용하면 NAT Gateway를 아예 거치지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NAT 비용 없음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Network Firewall 여부와 무관&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이라서 항상 추천하는 구성입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;  NAT Gateway 안 쓰면 뭘로 대체해?&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 101.512%; height: 232px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;대안&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;비용&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;장단점&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NAT Instance&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;약 $7.49/월&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;약 $7.49/월&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;VPC Endpoint (Gateway)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;무료&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;S3, DynamoDB 전용&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;VPC Endpoint (Interface)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;시간 + GB 과금&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;특정 AWS 서비스 전용&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;  결론&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;정리하면 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Network Firewall + NAT Gateway&lt;/b&gt; 사용 시 NAT Gateway 비용 &lt;b&gt;전액 면제&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 혜택은 &lt;b&gt;NAT Gateway만 해당&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Network Firewall을 이미 사용한다면 &lt;b&gt;NAT Gateway가 사실상 무료&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Network Firewall이 없다면 &lt;b&gt;NAT Instance도 여전히 유효한 선택&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Network Firewall을 쓰고 있다면 NAT Gateway는 고민할 필요가 없다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;관리형 서비스이기 때문에 운영 부담도 줄어들고, &lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;고가용성 구성도 따로 고민할 필요가 없습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;감사합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;참고 링크&lt;/span&gt;&lt;br /&gt;AWS Network Firewall Pricing&lt;br /&gt;&lt;a href=&quot;https://aws.amazon.com/network-firewall/pricing/&quot;&gt;https://aws.amazon.com/network-firewall/pricing/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;NAT Gateway vs NAT Instance 비교 - AWS 공식문서&lt;br /&gt;&lt;a href=&quot;https://aws.amazon.com/vpc/pricing/&quot;&gt;https://aws.amazon.com/vpc/pricing/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Network Firewall 아키텍처 가이드 (IGW + NAT GW)&lt;br /&gt;&lt;a href=&quot;https://repost.aws/knowledge-center/network-firewall-set-up-with-nat-gateway&quot;&gt;https://repost.aws/knowledge-center/network-firewall-set-up-with-nat-gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;AWS 공식 블로그 - Network Firewall 배포 모델&lt;br /&gt;&lt;a href=&quot;https://aws.amazon.com/blogs/networking-and-content-delivery/deployment-models-for-aws-network-firewall/&quot;&gt;https://aws.amazon.com/blogs/networking-and-content-delivery/deployment-models-for-aws-network-firewall/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;AWS re:Post - Network Firewall + NAT Gateway 설정 가이드&lt;br /&gt;&lt;a href=&quot;https://docs.aws.amazon.com/network-firewall/latest/developerguide/arch-igw-ngw.html&quot;&gt;https://docs.aws.amazon.com/network-firewall/latest/developerguide/arch-igw-ngw.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Amazon VPC Pricing (NAT Gateway)&lt;br /&gt;&lt;a href=&quot;https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-comparison.html&quot;&gt;https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-comparison.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;AWS Network Firewall 가격 인하 공지 (2026.02)&lt;br /&gt;&lt;a href=&quot;https://aws.amazon.com/about-aws/whats-new/2026/02/aws-network-firewall-new-price-reduction/&quot;&gt;https://aws.amazon.com/about-aws/whats-new/2026/02/aws-network-firewall-new-price-reduction/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>aws</category>
      <category>cost</category>
      <category>FREE</category>
      <category>NATgateway</category>
      <category>NetworkFirewall</category>
      <category>비용</category>
      <category>요금</category>
      <author>copcat</author>
      <guid isPermaLink="true">https://try-it.tistory.com/75</guid>
      <comments>https://try-it.tistory.com/75#entry75comment</comments>
      <pubDate>Wed, 11 Mar 2026 18:11:31 +0900</pubDate>
    </item>
    <item>
      <title>초기 세팅시 스프링부트 메인을 실행했는데 꺼지는 이유</title>
      <link>https://try-it.tistory.com/74</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk Image Sept 25.png&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rMlAl/btsNfQpolPh/9qbl1k58l7lim0oVjNJy4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rMlAl/btsNfQpolPh/9qbl1k58l7lim0oVjNJy4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rMlAl/btsNfQpolPh/9qbl1k58l7lim0oVjNJy4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrMlAl%2FbtsNfQpolPh%2F9qbl1k58l7lim0oVjNJy4K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;250&quot; height=&quot;250&quot; data-filename=&quot;KakaoTalk Image Sept 25.png&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;250&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링부트(Spring Boot) 프로젝트를 새로 세팅하고, &lt;span&gt;Application&lt;/span&gt; 클래스를 실행해보면 8080 포트에서 서버가 실행되기를 기대하게 됩니다. &lt;span&gt;&lt;b&gt;별다른 에러 없이 애플리케이션이 곧바로 종료되는 경험&lt;/b&gt;&lt;/span&gt;을 한 적이 있으신가요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번 글에서는 &lt;/span&gt;&lt;b&gt;Spring Boot가 자동으로 종료되는 이유&lt;/b&gt;&lt;span&gt;와 &lt;/span&gt;&lt;b&gt;톰캣(Tomcat) 서버가 JVM을 유지시키는 메커니즘&lt;/b&gt;&lt;span&gt;, 그리고 &lt;/span&gt;&lt;b&gt;Non-Daemon Thread의 역할&lt;/b&gt;&lt;span&gt;에 대해 간단하게 정리해보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. Spring Boot 애플리케이션이 곧바로 종료되는 이유는?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring Boot는 실행 시 프로젝트에 포함된 의존성 등을 바탕으로 애플리케이션이 &lt;span&gt;&lt;b&gt;Web 환경인지, Non-Web 환경인지 자동으로 판단&lt;/b&gt;&lt;/span&gt;합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 다음과 같은 경우에는 &lt;/span&gt;&lt;b&gt;Spring Boot는 Web 환경이 아니라고 판단&lt;/b&gt;&lt;span&gt;합니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;spring-boot-starter-web&lt;span&gt; 또는 &lt;/span&gt;spring-boot-starter-webflux&lt;span&gt;가 포함되어 있지 않음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;유지되어야 할 백그라운드 서비스가 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 중요한 포인트는 이것입니다&lt;/p&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;Spring Boot 애플리케이션이 종료되는 직접적인 원인은 Web 환경이 아님이 아니라, JVM 내에 Non-Daemon Thread가 존재하지 않기 때문입니다.&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;즉, Web 여부가 아닌 &lt;/span&gt;&lt;b&gt;Thread의 상태가 애플리케이션 생존을 결정&lt;/b&gt;&lt;span&gt;합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. JVM과 Non-Daemon Thread란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM(Java Virtual Machine)은 내부에 실행 중인 모든 &lt;span&gt;&lt;b&gt;Non-Daemon Thread가 종료되었을 때, 전체 애플리케이션을 종료&lt;/b&gt;&lt;/span&gt;시킵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;Daemon Thread&lt;/b&gt;&lt;/span&gt;: 백그라운드에서 동작, JVM이 자동 종료되어도 함께 종료됨 (예: GC, Timer)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Non-Daemon Thread&lt;/b&gt;&lt;span&gt;: 주요 작업을 수행, &lt;/span&gt;&lt;b&gt;하나라도 살아있으면 JVM은 종료되지 않음&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 스프링부트 애플리케이션이 자동 종료되었다는 것은 &lt;span&gt;&lt;b&gt;Non-Daemon Thread가 존재하지 않았다는 의미&lt;/b&gt;&lt;/span&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 톰캣이 JVM을 종료되지 않게 막는 방식은?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring Boot는 &lt;span&gt;spring-boot-starter-web&lt;/span&gt; 의존성을 통해 톰캣(Tomcat) 웹서버를 내장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;톰캣은 내부적으로&lt;/span&gt;&lt;b&gt; Non-Daemon Thread&lt;/b&gt;&lt;span&gt;, 특히 &lt;/span&gt;&lt;b&gt;main thread 역할을 하는 &amp;lsquo;Acceptor&amp;rsquo;, &amp;lsquo;Poller&amp;rsquo;, &amp;lsquo;Executor&amp;rsquo;&lt;/b&gt;&lt;span&gt; 등을 통해 HTTP 요청을 수신하고 처리합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 쓰레드가 동작함으로써 JVM이 종료되지 않으며, &lt;span&gt;&lt;b&gt;SpringApplication.run(&amp;hellip;)&lt;/b&gt;&lt;/span&gt; 이후에도 애플리케이션이 계속 살아있는 이유가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 예제로 보는 Non-Daemon Thread&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;톰캣을 포함하지 않은 순수 Spring Boot 프로젝트에서는 다음과 같이 Non-Daemon Thread를 명시적으로 생성하면 JVM을 종료시키지 않을 수 있습니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1744270786861&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class NonDaemonThreadTest {
    public static void main(String[] args) {
        Thread thread = new Thread(() -&amp;gt; {
            try {
                Thread.sleep(100000); // 100초 동안 대기
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        thread.setDaemon(false); // 명시적으로 Non-Daemon 설정
        thread.start();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 메인 메서드가 종료된 이후에도 Non-Daemon Thread가 살아 있으므로, JVM은 종료되지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. 결론 및 요약&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;Spring Boot 애플리케이션이 자동 종료되는 이유&lt;/b&gt;&lt;/span&gt;는 Non-Daemon Thread가 없기 때문입니다.&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;톰캣&lt;/b&gt;&lt;/span&gt;은 Non-Daemon Thread를 실행하여 JVM이 종료되지 않도록 합니다.&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;Web 서버가 포함되지 않은 프로젝트&lt;/b&gt;&lt;/span&gt;에서는 JVM이 실행과 동시에 종료될 수 있습니다.&lt;/li&gt;
&lt;li&gt;JVM의 종료 조건을 이해하면, 백그라운드 작업 처리나 커스텀 런타임 애플리케이션 설계에 도움이 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Spring &amp;amp; Spring Boot</category>
      <category>non-daemon</category>
      <category>spring</category>
      <category>SpringBoot</category>
      <category>thread</category>
      <category>스프링</category>
      <category>쓰레드</category>
      <author>copcat</author>
      <guid isPermaLink="true">https://try-it.tistory.com/74</guid>
      <comments>https://try-it.tistory.com/74#entry74comment</comments>
      <pubDate>Thu, 10 Apr 2025 16:47:31 +0900</pubDate>
    </item>
    <item>
      <title>[AI] Ollama 찍먹해보기</title>
      <link>https://try-it.tistory.com/73</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctcO6j/btsJcWzHpNO/k6VjGeqrxBKG2stDNjQ1Z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctcO6j/btsJcWzHpNO/k6VjGeqrxBKG2stDNjQ1Z0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctcO6j/btsJcWzHpNO/k6VjGeqrxBKG2stDNjQ1Z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctcO6j%2FbtsJcWzHpNO%2Fk6VjGeqrxBKG2stDNjQ1Z0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;225&quot; height=&quot;225&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Ollama가 무엇인가요?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즈음 ChatGPT, Calude 등 대형 LLM이 주목받고 있습니다. 하지만 비용이 만만치 않습니다. 내 PC에서 이런 LLM을 사용하려면 클라우드를 사용하거나 앞서 설명한 대형 LLM을 구독하여 사용해야 합니다. 이러한 문제를 해결해주는 오픈소스 프로젝트가 바로 Ollama 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Ollama는 오픈소스 LLM을 로컬 PC에서 쉽게 실행할 수 있게 해주는 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mistral, Llama 3 등 다양한 오픈소스 LLM을 지원하죠. 모델 가중치, 설정, 데이터셋을 하나의 패키지로 묶어서 Modelfile로 관리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ollama.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ollama.com/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1724338183454&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Ollama&quot; data-og-description=&quot;Get up and running with large language models.&quot; data-og-host=&quot;ollama.com&quot; data-og-source-url=&quot;https://ollama.com/&quot; data-og-url=&quot;https://ollama.com&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/XLOCG/hyWSibC8ke/WtkzHz5oRkxw0c5S745O7k/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://ollama.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ollama.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/XLOCG/hyWSibC8ke/WtkzHz5oRkxw0c5S745O7k/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Ollama&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Get up and running with large language models.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ollama.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;macOS&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://ollama.com/download/Ollama-darwin.zip&quot;&gt;다운로드 페이지(Ollama)&lt;/a&gt;에서 macOS용 파일을 다운로드 합니다.&lt;/li&gt;
&lt;li&gt;다운로드한 zip 파일의 압축을 풉니다.&lt;/li&gt;
&lt;li&gt;터미널을 열고 압축 해제한 폴더로 이동합니다.&lt;/li&gt;
&lt;li&gt;./ollama&amp;nbsp;명령어로 실행합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹은 brew를 사용합니다!&lt;/p&gt;
&lt;pre id=&quot;code_1724337041521&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;brew install ollama&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://formulae.brew.sh/formula/ollama&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://formulae.brew.sh/formula/ollama&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1724337069313&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;ollama&quot; data-og-description=&quot;Homebrew&amp;rsquo;s package index&quot; data-og-host=&quot;formulae.brew.sh&quot; data-og-source-url=&quot;https://formulae.brew.sh/formula/ollama&quot; data-og-url=&quot;https://formulae.brew.sh/formula/ollama&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bKUMvj/hyWSduDDa5/xemkaSulQOA7kKkhgo1NI0/img.png?width=256&amp;amp;height=256&amp;amp;face=0_0_256_256&quot;&gt;&lt;a href=&quot;https://formulae.brew.sh/formula/ollama&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://formulae.brew.sh/formula/ollama&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bKUMvj/hyWSduDDa5/xemkaSulQOA7kKkhgo1NI0/img.png?width=256&amp;amp;height=256&amp;amp;face=0_0_256_256');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;ollama&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Homebrew&amp;rsquo;s package index&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;formulae.brew.sh&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;모델 선택하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ollama 에서 지원하는 모델을 그냥 사용할 수 있지만 저는 한국어 모델이 필요했습니다. 이유는 재미용!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한국어 모델은 &quot;야놀자&quot; 에서 만든 모델이 있습니다. 기본 모델인 &lt;b&gt;EEVE-Korean-10.8B&lt;/b&gt;의 파인 튜닝된 버전입니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 모델에 대해서 간단히 소개해드리겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 모델은 upstage/SOLAR-10.7B 모델을 기반으로 한국어 처리에 최적화된 확장된 어휘를 사용하여 개선되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, EEVE-Korean 모델은 108억 개의 파라미터를 가지고 있으며, 이는 GPT-3(1,750억 개)보다 적기 때문에 감안하여 사용하시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬 AI 만들어서 사용해보는 것이 목적이기 때문에 이 모델을 활용해봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://huggingface.co/yanolja/EEVE-Korean-Instruct-10.8B-v1.0#about-the-model&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://huggingface.co/yanolja/EEVE-Korean-Instruct-10.8B-v1.0#about-the-model&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1724337118253&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;yanolja/EEVE-Korean-Instruct-10.8B-v1.0 &amp;middot; Hugging Face&quot; data-og-description=&quot;EEVE-Korean-Instruct-10.8B-v1.0 Join Our Community on Discord! If you're passionate about the field of Large Language Models and wish to exchange knowledge and insights, we warmly invite you to join our Discord server. It's worth noting that Korean is the &quot; data-og-host=&quot;huggingface.co&quot; data-og-source-url=&quot;https://huggingface.co/yanolja/EEVE-Korean-Instruct-10.8B-v1.0#about-the-model&quot; data-og-url=&quot;https://huggingface.co/yanolja/EEVE-Korean-Instruct-10.8B-v1.0&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/jhAwT/hyWScJeDdX/fjbeG7cPUWPuUxkdtUY3ik/img.png?width=1200&amp;amp;height=648&amp;amp;face=0_0_1200_648,https://scrap.kakaocdn.net/dn/dnSMsS/hyWR9yY2Xo/KxyFkWJvnvFHAnJG4jSQO0/img.png?width=1200&amp;amp;height=648&amp;amp;face=0_0_1200_648&quot;&gt;&lt;a href=&quot;https://huggingface.co/yanolja/EEVE-Korean-Instruct-10.8B-v1.0#about-the-model&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://huggingface.co/yanolja/EEVE-Korean-Instruct-10.8B-v1.0#about-the-model&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/jhAwT/hyWScJeDdX/fjbeG7cPUWPuUxkdtUY3ik/img.png?width=1200&amp;amp;height=648&amp;amp;face=0_0_1200_648,https://scrap.kakaocdn.net/dn/dnSMsS/hyWR9yY2Xo/KxyFkWJvnvFHAnJG4jSQO0/img.png?width=1200&amp;amp;height=648&amp;amp;face=0_0_1200_648');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;yanolja/EEVE-Korean-Instruct-10.8B-v1.0 &amp;middot; Hugging Face&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;EEVE-Korean-Instruct-10.8B-v1.0 Join Our Community on Discord! If you're passionate about the field of Large Language Models and wish to exchange knowledge and insights, we warmly invite you to join our Discord server. It's worth noting that Korean is the&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;huggingface.co&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt; &lt;/span&gt;Hugging Face CLI를 통해 Hugging Face Hub에 있는 모델을 쉽게 다운로드하고 관리할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1724337142989&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;brew install huggingface-cli&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;모델 다운로드받기&lt;/h3&gt;
&lt;pre id=&quot;code_1724337154786&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;huggingface-cli download heegyu/EEVE-Korean-Instruct-10.8B-v1.0-GGUF ggml-model-Q5_K_M.gguf --local-dir /Users/jiwoo/Downloads/ai --local-dir-use-symlinks False&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 명령어는 다음과 같은 의미를 가집니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;huggingface-cli&lt;/b&gt;: Hugging Face의 명령줄 인터페이스(CLI)를 사용합니다. Hugging Face는 주로 자연어 처리 모델을 제공하는 플랫폼입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;download heegyu/EEVE-Korean-Instruct-10.8B-v1.0-GGUF&lt;/b&gt;: &amp;lsquo;heegyu&amp;rsquo; 사용자가 제공하는 &amp;lsquo;EEVE-Korean-Instruct-10.8B-v1.0-GGUF&amp;rsquo;라는 모델을 다운로드합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ggml-model-Q5_K_M.gguf&lt;/b&gt;: 다운로드한 모델을 &amp;lsquo;ggml-model-Q5_K_M.gguf&amp;rsquo;라는 파일 이름으로 저장합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&amp;ndash;local-dir /Users/jiwoo/Downloads/ai&lt;/b&gt;: 모델 파일을 로컬 디렉토리 &amp;lsquo;/Users/jiwoo/Downloads/ai&amp;rsquo;에 저장합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&amp;ndash;local-dir-use-symlinks False&lt;/b&gt;: 심볼릭 링크를 사용하지 않고 실제 파일을 사용하여 저장합니다. 심볼릭 링크는 파일 시스템 내에서 다른 파일이나 디렉토리에 대한 참조를 만드는 것입니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;프롬프트 템플릿 작성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한국어 모델 설치가 완료되었다면 다음 순서로는 모델파일을 만들어서 Ollama에게 적용시켜보는 단계입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1724337367549&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 파일이름 Modelfile

FROM ggml-model-Q5_K_M.gguf

TEMPLATE &quot;&quot;&quot;{{- if .System }}
&amp;lt;s&amp;gt;{{ .System }}&amp;lt;/s&amp;gt;
{{- end }}
&amp;lt;s&amp;gt;Human:
{{ .Prompt }}&amp;lt;/s&amp;gt;
&amp;lt;s&amp;gt;Assistant:
&quot;&quot;&quot;

SYSTEM &quot;&quot;&quot;A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions.&quot;&quot;&quot;

PARAMETER stop &amp;lt;s&amp;gt;
PARAMETER stop &amp;lt;/s&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드에서 SYSTEM은 원하는 프롬프트(글쓴이의 배경이라든지 원하는 조건)를 넣으면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1724337485804&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ollama create EEVE-Korean-10.8B -f Modelfile

# 모델 확인하기
ollama list

# ollama 실행하기
ollama run EEVE-Korean-10.8B:latest&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 명령어는 &amp;ldquo;Ollama&amp;rdquo;라는 툴을 사용하여 &amp;ldquo;EEVE-Korean-10.8B&amp;rdquo;라는 이름의 한국어 모델을 &amp;ldquo;Modelfile&amp;rdquo;이라는 파일을 기반으로 생성하는 작업을 실행하라는 의미입니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;작업 과정&amp;nbsp;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;408&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sTDAg/btsJcVOlstl/q8SAdTV9iRCjiGBE02nAk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sTDAg/btsJcVOlstl/q8SAdTV9iRCjiGBE02nAk1/img.png&quot; data-alt=&quot;모델파일 적용시키는 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sTDAg/btsJcVOlstl/q8SAdTV9iRCjiGBE02nAk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsTDAg%2FbtsJcVOlstl%2Fq8SAdTV9iRCjiGBE02nAk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1800&quot; height=&quot;408&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;408&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;모델파일 적용시키는 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;381&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSg6vc/btsJb4ZDIoG/8O8O7OO7VkrLnmITHJjTQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSg6vc/btsJb4ZDIoG/8O8O7OO7VkrLnmITHJjTQk/img.png&quot; data-alt=&quot;이미지 확인 및 실행&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSg6vc/btsJb4ZDIoG/8O8O7OO7VkrLnmITHJjTQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSg6vc%2FbtsJb4ZDIoG%2F8O8O7OO7VkrLnmITHJjTQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1800&quot; height=&quot;381&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;381&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이미지 확인 및 실행&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;561&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bX5q7q/btsJbqPvmud/EfyM6dk4517Vm2eTziOKWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bX5q7q/btsJbqPvmud/EfyM6dk4517Vm2eTziOKWk/img.png&quot; data-alt=&quot;프롬프트 작업 진행&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bX5q7q/btsJbqPvmud/EfyM6dk4517Vm2eTziOKWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbX5q7q%2FbtsJbqPvmud%2FEfyM6dk4517Vm2eTziOKWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1800&quot; height=&quot;561&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;561&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프롬프트 작업 진행&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1272&quot; data-origin-height=&quot;76&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k5cBX/btsJcRyxmUz/MbwnYn5u5WiLbasKkFx7T0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k5cBX/btsJcRyxmUz/MbwnYn5u5WiLbasKkFx7T0/img.png&quot; data-alt=&quot;메모리&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k5cBX/btsJcRyxmUz/MbwnYn5u5WiLbasKkFx7T0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk5cBX%2FbtsJcRyxmUz%2FMbwnYn5u5WiLbasKkFx7T0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1272&quot; height=&quot;76&quot; data-origin-width=&quot;1272&quot; data-origin-height=&quot;76&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;메모리&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리는 최대 약 2GB 정도 잡히는 것을 확인해볼 수 있습니다.&lt;/p&gt;</description>
      <category>MAC</category>
      <category>Ai</category>
      <category>GPT</category>
      <category>llm</category>
      <category>ollama</category>
      <category>sLLM</category>
      <category>소형llm</category>
      <author>copcat</author>
      <guid isPermaLink="true">https://try-it.tistory.com/73</guid>
      <comments>https://try-it.tistory.com/73#entry73comment</comments>
      <pubDate>Thu, 22 Aug 2024 23:50:20 +0900</pubDate>
    </item>
    <item>
      <title>메소드 파라미터마다 Final 하는 이유</title>
      <link>https://try-it.tistory.com/72</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;개발하면서 깃허브 코드를 참고하다보니 가끔씩 함수의 파라미터에 final 키워드가 들어가는 것을 확인했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 사용하는지? 사용하면 어떤 이점이 있는지 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Final&lt;/b&gt;은 변경불가능하다는 키워드 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 메소드 파라미터에 사용하는 것은 해당 파라미터가 변경불가능하다는 뜻인데, 어떤 이점이 있을까요?&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;장점&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;재할당되서 발생할 수 있는 문제는 컴파일 타임에 바로 잡아 줄 수 있습니다.&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변수의 상태 변화를 추적할 필요가 없으므로 코드가 더 쉽게 읽힙니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;불변성 강조&lt;/b&gt;: &lt;b&gt;final&lt;/b&gt; 키워드가 붙은 파라미터는 메소드 내에서 수정할 수 없습니다. 이는 코드를 읽는 사람에게 해당 변수가 변경되지 않을 것임을 명확하게 알려줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;1110&quot; data-origin-height=&quot;286&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwM7EF/btsyTuAEAkB/tVe1NIwr536Zq4s7MLLR1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwM7EF/btsyTuAEAkB/tVe1NIwr536Zq4s7MLLR1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwM7EF/btsyTuAEAkB/tVe1NIwr536Zq4s7MLLR1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwM7EF%2FbtsyTuAEAkB%2FtVe1NIwr536Zq4s7MLLR1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1110&quot; height=&quot;286&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;1110&quot; data-origin-height=&quot;286&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 Final이 불변성을 의미하는 것일까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt;아닙니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;찾아보니, Final 키워드가 변수에 적용될 때, 그 변수는 재할당을 할 수 없는건 맞지만, 해당 객체의 불변성을 의미하는 것이 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 재할당 금지&lt;/p&gt;
&lt;pre class=&quot;processing&quot;&gt;&lt;code&gt;final String str = &quot;hello&quot;;
str = &quot;world&quot;;  // 컴파일 에러
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp; 객체 상태 변경 가능&lt;/p&gt;
&lt;pre class=&quot;lasso&quot;&gt;&lt;code&gt;final List&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
list.add(&quot;hello&quot;);  // 가능
list.add(&quot;world&quot;);  // 가능
&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;final&lt;/b&gt;: 변수가 한 번 초기화된 후에는 다른 값으로 재할당할 수 없습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;불변성&lt;/b&gt;: 객체의 상태가 생성 후에 변경되지 않습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &lt;b&gt;final&lt;/b&gt;은 변수 재할당을 금지할 뿐, 객체의 불변성을 보장하지는 않습니다.&lt;/p&gt;</description>
      <category>개발/Spring &amp;amp; Spring Boot</category>
      <category>final</category>
      <category>java</category>
      <category>메소드</category>
      <category>불변성</category>
      <category>재할당</category>
      <category>파라미터</category>
      <author>copcat</author>
      <guid isPermaLink="true">https://try-it.tistory.com/72</guid>
      <comments>https://try-it.tistory.com/72#entry72comment</comments>
      <pubDate>Sat, 21 Oct 2023 21:37:53 +0900</pubDate>
    </item>
    <item>
      <title>EC2 AMI 와 Snapshot 의 차이,, 근데 비용을 곁들인..</title>
      <link>https://try-it.tistory.com/71</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;AWS EC2를 사용하다보면 백업을 하기위해서 이미지(AMI)를 생성하거나, Snapshot을 사용하기도 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 포스팅에서는 EC2 AMI 와 Snapshot 의 차이와 비용발생에 대해 간단하게 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  AMI 이미지 생성방식과 EBS 생성방식의 차이&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: start;&quot;&gt;&lt;b&gt;AMI 이미지 생성방식&lt;/b&gt;은 EC2 인스턴스의 전체 백업(인스턴스와 + 저장소) 을 생성하는 것이고,&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: start;&quot;&gt;이미지를 복원할 때는 새로운 인스턴스와 EBS 볼륨이 생성되어 복원됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: start;&quot;&gt;&lt;b&gt;EBS&amp;nbsp;스냅샷&amp;nbsp;생성방식&lt;/b&gt;은&amp;nbsp;EBS볼륨을&amp;nbsp;백업하는&amp;nbsp;방식입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: start;&quot;&gt;스냅샷은 &lt;span style=&quot;background-color: #ffffff; color: #232f3e; text-align: start;&quot;&gt;생성하는 시점 그대로 저장이 됩니다. &lt;/span&gt;EBS만 백업하는 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: start;&quot;&gt;그래서 복원할 때는 새로운 인스턴스가 생성되지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  서울리전(ap-northeast-2)기준으로 비용에서는 어떤 차이가 있을까요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AMI과 EBS 스냅샷 비용에 대해서 각각 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;AMI 비용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EC2&amp;nbsp;인스턴스를&amp;nbsp;기반으로&amp;nbsp;AMI를&amp;nbsp;생성하는&amp;nbsp;데는&amp;nbsp;비용이&amp;nbsp;들지&amp;nbsp;않습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉,&amp;nbsp;AMI&amp;nbsp;생성&amp;nbsp;자체에는&amp;nbsp;비용이&amp;nbsp;청구되지&amp;nbsp;않습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, AMI 생성 중에 소비한 리소스 비용(예: EC2 인스턴스 사용 시간, EBS 스토리지 비용)과 EBS 스냅샷 비용은 고려해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;EBS 스냅샷 비용&lt;/h3&gt;
&lt;table style=&quot;color: #333333; text-align: start; border-collapse: collapse; width: 100%; height: 131px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style4&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;text-align: left; height: 19px;&quot;&gt;&lt;b&gt;EBS Snapshots 스토리지 요금&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;background-color: #f7f7f7; text-align: left; height: 19px;&quot;&gt;스탠더드&lt;/td&gt;
&lt;td style=&quot;background-color: #f7f7f7; text-align: center; height: 19px;&quot;&gt;&lt;span data-metered-unit=&quot;ec2/ebs.[Storage Snapshot Amazon S3 GB Mo]&quot; data-rate-code=&quot;JC4HQPKR4ATMSY93.JRTCKXETXF.6YS6EN2CT7&quot;&gt;0.05 USD&lt;/span&gt;/월별 GB당&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;text-align: left; height: 19px;&quot;&gt;아카이브&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 19px;&quot;&gt;&lt;span data-metered-unit=&quot;ec2/ebs.[Storage Snapshot Amazon S3 SnapshotArchiveStorage GB Mo]&quot; data-rate-code=&quot;6PPBCUMMPPJ9DG94.JRTCKXETXF.6YS6EN2CT7&quot;&gt;0.0125 USD&lt;/span&gt;/월별 GB당&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;background-color: #f7f7f7; text-align: left; height: 19px;&quot;&gt;&lt;b&gt;EBS Snapshots 복원 요금&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #f7f7f7; text-align: center; height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;text-align: left; height: 19px;&quot;&gt;스탠더드&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 19px;&quot;&gt;무료&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;background-color: #f7f7f7; text-align: left; height: 19px;&quot;&gt;아카이브&lt;/td&gt;
&lt;td style=&quot;background-color: #f7f7f7; text-align: center; height: 19px;&quot;&gt;검색된 데이터 GB당&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span data-metered-unit=&quot;ec2/ebs.[Storage Snapshot Amazon S3 SnapshotArchiveRetrieval GB]&quot; data-rate-code=&quot;9QD358WZYTV48TZ5.JRTCKXETXF.6YS6EN2CT7&quot;&gt;0.03 USD&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;background-color: #f7f7f7; text-align: left; height: 17px;&quot;&gt;&lt;b&gt;빠른&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Snapshots&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;복원 요금&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #f7f7f7; text-align: center; height: 17px;&quot;&gt;&lt;span style=&quot;background-color: #f7f7f7; color: #333333; text-align: center;&quot;&gt;해당 기능이 활성화된 각 스냅샷 및 각 AZ에서 1 DSU 시간당&amp;nbsp;0.86 USD&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232f3e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232f3e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;요금은 스토리지 티어에 따라 다릅니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232f3e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232f3e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;스탠다드 티어의 경우 저장된 후 변경된 블록에 대해서만 요금이 청구됩니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232f3e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232f3e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아카이브 티어의 경우 저장된 모든 스냅샷 블록에 대해 요금이 청구됩니다. 아카이브 티어에서 스냅샷을 검색하는 비용도 청구됩니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232f3e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232f3e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음은 각 스토리지 티어에 대한 예제 시나리오입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #232f3e; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;스탠다드 티어&lt;/b&gt;: 100GB의 데이터를 저장하는 볼륨이 있습니다. 첫 번째 스냅샷(스냅 A)의 경우, 전체 데이터 100GB에 대한 요금이 청구됩니다. 다음 스냅샷(스냅 B)에서는 105GB의 데이터가 있습니다. 그러면 증분 스냅 B에 대한 추가 5GB 스토리지에 대해서만 요금이 청구됩니다. &lt;span style=&quot;background-color: #ffffff; color: #2f3941; text-align: start;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;a style=&quot;background-color: #ffffff; color: #1f73b7; text-align: start;&quot; href=&quot;https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/EBSSnapshots.html#how_snapshots_work&quot;&gt;AWS EBS 증분 스냅샷 작동 방식&amp;gt;&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #2f3941; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #2f3941; text-align: start;&quot;&gt;EBS Snapshots 스토리지 요금 계산&lt;/span&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #2f3941; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: initial;&quot;&gt;주요 스냅샷 요금 : $0.05 /월별 GB 당, 100GB x 0.05 = $5&lt;/li&gt;
&lt;li style=&quot;list-style-type: initial;&quot;&gt;추가 스냅샷 요금 : 5 GB x $0.05 = $0.25&lt;/li&gt;
&lt;li style=&quot;list-style-type: initial;&quot;&gt;합계 : $5 + $0.25 = $5.25&lt;/li&gt;
&lt;/ul&gt;
&lt;span style=&quot;background-color: #ffffff; color: #2f3941; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;아카이브 티어&lt;/b&gt;: 스냅 B를 아카이빙합니다. 그런 다음 스냅샷이 아카이브 티어로 이동되고 전체 105GB 스냅샷 블록에 대한 요금이 청구됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 링크&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/backup-recovery/ec2-backup.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/backup-recovery/ec2-backup.html&lt;/a&gt;&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>ami</category>
      <category>aws</category>
      <category>ec2</category>
      <category>Snapshot</category>
      <category>백업</category>
      <category>볼륨</category>
      <category>비용</category>
      <category>요금</category>
      <category>인스턴스</category>
      <category>클라우드</category>
      <author>copcat</author>
      <guid isPermaLink="true">https://try-it.tistory.com/71</guid>
      <comments>https://try-it.tistory.com/71#entry71comment</comments>
      <pubDate>Sat, 5 Aug 2023 11:30:18 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] 프록시 객체를 이용하는 이유</title>
      <link>https://try-it.tistory.com/70</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;161&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wPuWF/btshHNCU5sk/u7ESDSRZN4DIYKZjFPReCK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wPuWF/btshHNCU5sk/u7ESDSRZN4DIYKZjFPReCK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wPuWF/btshHNCU5sk/u7ESDSRZN4DIYKZjFPReCK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwPuWF%2FbtshHNCU5sk%2Fu7ESDSRZN4DIYKZjFPReCK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;621&quot; height=&quot;161&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;161&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;프록시 객체는 실제 객체를 대신하여 요청을 처리하는 객체입니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;실제 객체와 같은 인터페이스를 구현하여 실제 객체를 대신하여 요청을 처리할 수 있습니다. 프록시 객체는 실제 객체를 보호하거나, 실제 객체의 기능을 확장하거나, 실제 객체의 로직을 변경하는 데 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;프록시 객체를 사용하는 이유&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;프록시 객체를 사용하는 이유는 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실제 객체 보호
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프록시 객체는 실제 객체를 대신하여 요청을 처리할 수 있습니다. 따라서 실제 객체가 직접 요청을 받지 않으므로 실제 객체를 보호할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;실제 객체의 기능 확장
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프록시 객체는 실제 객체의 기능을 확장할 수 있습니다.&lt;/li&gt;
&lt;li&gt;예를 들어, 프록시 객체는 실제 객체의 요청을 기록하거나, 실제 객체의 요청을 캐싱할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;실제 객체의 로직 변경
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프록시 객체는 실제 객체의 로직을 변경할 수 있습니다.&lt;/li&gt;
&lt;li&gt;예를 들어, 프록시 객체는 실제 객체의 요청을 필터링하거나, 실제 객체의 요청을 변환할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;CGLIB 프록시&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;VS JDK 프록시&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt; Spring 프록시는 CGLIB 프록시와 JDK 프록시 두 가지 유형의 프록시 객체를 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;간단하게 알아보자면,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JDK Dynamic Proxy는 인터페이스를 기반으로 프록시를 생성합니다. 따라서 프록시를 생성하려면 타겟 객체가 인터페이스를 구현해야 합니다. JDK Dynamic Proxy는 타겟 객체가 인터페이스를 구현하지 않은 경우에는 사용할 수 없습니다.&lt;/li&gt;
&lt;li&gt;CGLIB Proxy는 타겟 객체의 바이트 코드를 조작하여 프록시를 생성합니다. 따라서 타겟 객체가 인터페이스를 구현하지 않아도 사용할 수 있습니다. CGLIB Proxy는 JDK Dynamic Proxy보다 성능이 좋습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;Spring Boot 2.3 버전부터는 CGLIB 라이브러리가 Spring Core 패키지에&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #1f1f1f;&quot;&gt;기본적으로 포함되어있기 때문에 따로 의존성을 추가하지 않아도 됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>개발/Spring &amp;amp; Spring Boot</category>
      <category>Proxy</category>
      <category>spring</category>
      <category>Spring Boot</category>
      <category>프록시</category>
      <author>copcat</author>
      <guid isPermaLink="true">https://try-it.tistory.com/70</guid>
      <comments>https://try-it.tistory.com/70#entry70comment</comments>
      <pubDate>Mon, 29 May 2023 19:52:56 +0900</pubDate>
    </item>
    <item>
      <title>도커</title>
      <link>https://try-it.tistory.com/69</link>
      <description>&lt;h2&gt;Docker란?&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;도커는 컨테이너 기술을 기반하여 만든 오픈소스 가상화 플랫폼입니다. (도커 ≠ 컨테이너)&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h2&gt;컨테이너?&lt;/h2&gt;
&lt;p&gt;사전적 의미&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;화물을 담아 나르기 위해 주로 쓰는, 쇠로 만들어진 큰 상자.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;기술적 의미&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이미지 목적에 따라 생성되는 프로세스 단위의 독립 환경입니다.&lt;/li&gt;
&lt;li&gt;환경을 제공하며 프로세스의 생명주기를 관리합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;왜 컨테이너를 사용할까요?&lt;/h2&gt;
&lt;p&gt;HOST와 격리를 통하여 &lt;strong&gt;독립된 개발환경&lt;/strong&gt;을 보장하기 위해 사용합니다.&lt;/p&gt;
&lt;h2&gt;컨테이너의 역사&lt;/h2&gt;
&lt;h3&gt;FreeBSD Jail&lt;/h3&gt;
&lt;p&gt;오픈소스 Unix인 FreeBSD의 기술입니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;특징&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;프로세스의 구획화&lt;/li&gt;
&lt;li&gt;네트워크의 구힉화 &lt;/li&gt;
&lt;li&gt;파일 시스템의 구획화 &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;(구획이란? 경계를 갈라 정하는 것 또는 그 구역)&lt;/p&gt;
&lt;h3&gt;Solaris Containers&lt;/h3&gt;
&lt;p&gt;Oracle의 상용 Unix인 Solaris 의 기술입니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;특징&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Solaris 존 기능&lt;/li&gt;
&lt;li&gt;Solaris 리소스 매니저 기능&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Linux Containers (LXC)&lt;br&gt;Linux 커널의 컨테이너 기능을 이용하기 위한 툴이나 API를 제공합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;가상화??&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;하나의 물리적 서버 호스트에서 여러개의 서버 호스트를 게스트로 실행할 수 있게 해주는 소프트웨어 아키텍쳐&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;이런 서버 가상화를 구현해주는 기술이 바로 &lt;code&gt;Hypervisor&lt;/code&gt; 이라고 합니다.&lt;/p&gt;
&lt;p&gt;하이퍼바이저는 하나의 호스트 OS 위에 여러 개의 게스트 OS를 사용할 수 있게 도와주고 또한 이렇게 생성된 게스트OS는 각각 &lt;code&gt;가상머신&lt;/code&gt;이라는 단위로 구별됩니다.&lt;/p&gt;
&lt;p&gt;하이퍼바이저는 게스트 운영체제를 실행하고 관리할 수 있게끔 돕는 역할과 호스트 머신들이 자원들을 VM들에게 분배할 수 있도록 도와주는 역할을 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOPyai/btsd9MUfIHp/6evbKkheEEjJkD84lYkpCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOPyai/btsd9MUfIHp/6evbKkheEEjJkD84lYkpCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOPyai/btsd9MUfIHp/6evbKkheEEjJkD84lYkpCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOPyai%2Fbtsd9MUfIHp%2F6evbKkheEEjJkD84lYkpCK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위 그림을 보면 하이퍼바이저와 컨테이너의 방식은 유사해보이지만 큰 차이는 아래와 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;VM&lt;/code&gt; 은 호스트 os 위에 게스트 os 가 구동되기 때문에 이미지로 만들 때 무겁고 가상화 작업에서는 무조건 하이퍼바이저를 거쳐야합니다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;컨테이너&lt;/code&gt;는 애플리케이션을 구동하는 데 필요한 라이브러리 및 실행 파일만 존재하기 때문에 가볍고 이식성이 좋습니다.&lt;/p&gt;
&lt;p&gt;다시 강조하지만 컨테이너 ≠ 도커는 아닙니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;도커의 기능&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;이미지를 만듬 (Build)&lt;/li&gt;
&lt;li&gt;이미지를 공유 (Ship)&lt;/li&gt;
&lt;li&gt;컨테이너를 작동 (Run)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;이미지를 만드는 기능 - Build&lt;/h3&gt;
&lt;p&gt;애플리케이션의 실행에 필요한 프로그램 본체, 라이브러리, 미들웨어 , OS나 네트워크 설정 등을 하나로 모아서 이미지로 만듭니다.&lt;/p&gt;
&lt;p&gt;즉, 실행환경에서 움직이는 컨테이너의 바탕이 됩니다.&lt;/p&gt;
&lt;p&gt;도커에서는 &lt;code&gt;하나의 이미지 - 하나의 애플리케이션&lt;/code&gt; 만 넣어두는 것을 권장합니다.&lt;/p&gt;
&lt;p&gt;이미지는 겹쳐서 사용할 수 있기 때문에 OS 용 이미지에 웹 애플리케이션용 이미지를 겹쳐 다른 새로운 이미지 또한 만들 수 있습니다. ( 변경한 부분(이미지 레이어) 차분으로 관리합니다)&lt;/p&gt;
&lt;h3&gt;이미지를 공유하는 기능 - Ship&lt;/h3&gt;
&lt;p&gt;이미지는 Docker 레지스트리(ex. docker hub) 에서 공유할 수 있습니다.&lt;/p&gt;
&lt;p&gt;깃허브와 연계하여 dockerfile을 관리하고 자동으로 docker 이미지를 생성하여 hub 에 공개하는 것도 가능합니다.&lt;/p&gt;
&lt;h3&gt;컨테이너를 작동시키는 기능 - Run&lt;/h3&gt;
&lt;p&gt;Linux 상세어 컨테이너 단위로 서버 기능을 작동시킵니다.&lt;/p&gt;
&lt;p&gt;vm 같은 경우 서버 기능을 실행시키려면 os 의 실행 부터 해야하기 때문에 오래 걸리지만&lt;/p&gt;
&lt;p&gt; 도커는 이미 동작되는 os 상에서 프로세스를 실행시키는 것과 같은 속도로 빨리 실행 시킬 수 있습니다.&lt;/p&gt;
&lt;p&gt;하나의 Linux 커널을 여러 개의 컨테이너에서 공유하고 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.notion.so/b5723e8ae6bd4b49b06dd80084b5f843&quot;&gt;Linux 커널 기능 기술 (namespace, cgroups 등)&lt;/a&gt; 을 사용하여 컨테이너를 독립된 공간으로서 관리할 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Docker 컴포넌트&lt;/h2&gt;
&lt;h3&gt;Docker Engine&lt;/h3&gt;
&lt;p&gt;도커의 이미지를 생성하고 컨테이너를 가동시키기 위한 핵심 기능입니다.&lt;/p&gt;
&lt;h3&gt;Dokcer Registry&lt;/h3&gt;
&lt;p&gt;도커 이미지를 공개 및 공유하기 위한 레지스트리 기능입니다.&lt;/p&gt;
&lt;p&gt;실제 도커 공식 레지스트리 서비스인 도커 허브도 이 도커 레지스트리를 사용하고 있습니다.&lt;/p&gt;
&lt;h3&gt;Docker Compose&lt;/h3&gt;
&lt;p&gt;여러 개의 컨테이너로부터 이루어진 서비스를 구축, 실행하는 순서를 자동으로 하여, 관리를 간단히하는 기능입니다.&lt;/p&gt;
&lt;h3&gt;Docker Machine&lt;/h3&gt;
&lt;p&gt;더이상 지원되지 않습니다. &lt;a href=&quot;https://docs.docker.com/machine/&quot;&gt;https://docs.docker.com/machine/&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Docker Swarm&lt;/h3&gt;
&lt;p&gt;여러 도커 호스트를 클러스터화 하기 위한 툴입니다. → 쿠버네티스와 비슷&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dZrfoG/btsdZjfP22s/EiGB0106b4N2pbTekFkKV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dZrfoG/btsdZjfP22s/EiGB0106b4N2pbTekFkKV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dZrfoG/btsdZjfP22s/EiGB0106b4N2pbTekFkKV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdZrfoG%2FbtsdZjfP22s%2FEiGB0106b4N2pbTekFkKV1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;도커의 작동 구조&lt;/h2&gt;
&lt;p&gt;도커는 Linux  커널의 기술이 베이스로 되어 있습니다.&lt;/p&gt;
&lt;h3&gt;컨테이너를 구획화하는 장치 (namespace)&lt;/h3&gt;
&lt;p&gt;도커가 컨테이너라는 독립된 환경을 만들고 그 컨테이너를 구획화하여 어플리케이션의 실행 환경을 만들 수 있도록 하게끔 해준 기술입니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;개념&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;한 덩어리의 데이터를 이름을 붙여 분할함으로써 충돌 가능성을 줄이고, 쉽게 참조할 수 있게 함&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;독립된 환경&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PID&lt;/li&gt;
&lt;li&gt;Network&lt;/li&gt;
&lt;li&gt;UID&lt;/li&gt;
&lt;li&gt;MOUNT&lt;/li&gt;
&lt;li&gt;UTS&lt;/li&gt;
&lt;li&gt;IPC&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;릴리스 관리 장치 (cgroups)&lt;/h3&gt;
&lt;p&gt;도커가 물리 머신의 자원을 여러 컨테이너가 공유하여 작동할 수 있게 하게끔 해준 기술입니다.&lt;/p&gt;
&lt;p&gt;→ 예를 들면, 어떤 컨테이너가 호스트 os 의 자원을 모두 사용해 다른 컨테이너의 영향을 주는 일을 막아줌.&lt;/p&gt;
&lt;p&gt;cgroups의 부모자식 관계에서는 자식이 부모의 제한을 물려받습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;네트워크 구성&lt;/h2&gt;
&lt;p&gt;서버의 물리 NIC가 docker0 이라는 가상 브리지 네트워크로 연결됩니다. (docker0 은 기본 값입니다)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JeB1q/btsd3dZrdK4/RjtKXtiKNb3iD8diIqZkkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JeB1q/btsd3dZrdK4/RjtKXtiKNb3iD8diIqZkkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JeB1q/btsd3dZrdK4/RjtKXtiKNb3iD8diIqZkkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJeB1q%2Fbtsd3dZrdK4%2FRjtKXtiKNb3iD8diIqZkkk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;도커 컨테이너와 외부 네트워크가 통신을 할 때는 가상 브리지 docker0 과 호스트 os 의 물리적 NIC에서 패킷을 전송하는 장치가 필요합니다. → NAPT 기능 사용&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;도커 이미지의 데이터 관리 장치&lt;/h2&gt;
&lt;p&gt;데이터를 복사하고 변경이 없다면 그 복사는 쓸데 없이 점점 공간 낭비가 발생하는 문제가 있습니다.&lt;/p&gt;
&lt;p&gt;하지만 도커는 복사를 요구받아도 바로 복사하지 않고 원래 데이터를 그대로 참조시켜, 원본 또는 복사 어느 쪽에 수정이 가해진 시점에 비로소 새로운 빈 영역을 확보하고 데이터를 확보합니다.&lt;/p&gt;
&lt;p&gt;→ &lt;code&gt;Copy on Write&lt;/code&gt; 라고 부릅니다.&lt;/p&gt;
&lt;p&gt;위 방식으로 도커는 컨테이너의 이미지를 관리합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;이미지를 관리하는 스토리지 디바이스&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AUFS&lt;/li&gt;
&lt;li&gt;Btrfs → 롤백, 스냅샷 기능&lt;/li&gt;
&lt;li&gt;Device Mapper&lt;/li&gt;
&lt;li&gt;OverlayFS&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;  궁금했던 것들&lt;/h3&gt;
&lt;h2&gt;왜 하필 도커?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;주관적인 생각&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;편리성&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;클라우드와 친화적&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;거대한 커뮤니티 &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;이식성&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;등등.. &lt;/p&gt;
&lt;p&gt;많은 장점들로 하여금 사용하지 않았을까요?&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Linux 커널 기능 - namespace, cgroups ?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;구글링&lt;/p&gt;
&lt;p&gt;  커널 →&lt;strong&gt;&lt;em&gt;컴퓨터 자원을 관리&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;   namespace ?&lt;/p&gt;
&lt;p&gt;  → 프로세스를 실행할 때 시스템의 리소스를 분리해서 실행할 수 있도록 도와주는 기능&lt;/p&gt;
&lt;p&gt;  쉽게 말해 한 덩어리 데이터를 네이밍하여 서로 충돌을 방지하고 쉽게 참조할 수 있게 해주는 기능입니다.&lt;/p&gt;
&lt;p&gt;  cgroups ?&lt;/p&gt;
&lt;p&gt;  → 프로세스들이 사용할 수 있는 컴퓨터 자원을 제한하고 격리시켜주는 기능&lt;/p&gt;
&lt;p&gt;  제한 가능한 자원리스트&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;메모리&lt;/li&gt;
&lt;li&gt;CPU&lt;/li&gt;
&lt;li&gt;네트워크&lt;/li&gt;
&lt;li&gt;장치&lt;/li&gt;
&lt;li&gt;I/O&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>인프라/Docker</category>
      <category>Docker</category>
      <category>도커</category>
      <author>copcat</author>
      <guid isPermaLink="true">https://try-it.tistory.com/69</guid>
      <comments>https://try-it.tistory.com/69#entry69comment</comments>
      <pubDate>Sat, 6 May 2023 17:36:59 +0900</pubDate>
    </item>
    <item>
      <title>AWS S3 URL 다운로드 제한을 IP로 할 수 있을까?</title>
      <link>https://try-it.tistory.com/68</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;문득 S3 미리 정의된 URL로 다운로드하거나 액세스하는 것을 퍼블릭하게 노출시키지 않는 방법이 뭐가 있을까?&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;고민하다가 &lt;b&gt;IP기반으로 액세스를 허용하고 제한할 수 있을까&lt;/b&gt; 하고 간단하게 테스트해본 내용입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트를 위해 버킷과 객체를 준비해줍니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 버킷 생성&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;2158&quot; data-origin-height=&quot;1160&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czd1ue/btr5O9ep7PC/J1DRK6OdPuX9X2G2M0ZJok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czd1ue/btr5O9ep7PC/J1DRK6OdPuX9X2G2M0ZJok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czd1ue/btr5O9ep7PC/J1DRK6OdPuX9X2G2M0ZJok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fczd1ue%2Fbtr5O9ep7PC%2FJ1DRK6OdPuX9X2G2M0ZJok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2158&quot; height=&quot;1160&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;2158&quot; data-origin-height=&quot;1160&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 객체를 선택하고 미리 서명된 URL 과 공유를 선택합니다.&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2.png&quot; data-origin-width=&quot;2632&quot; data-origin-height=&quot;944&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/efjRkW/btr5RSQf3VI/gGFuWUU8VKdIVoptz1mM7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/efjRkW/btr5RSQf3VI/gGFuWUU8VKdIVoptz1mM7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/efjRkW/btr5RSQf3VI/gGFuWUU8VKdIVoptz1mM7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FefjRkW%2Fbtr5RSQf3VI%2FgGFuWUU8VKdIVoptz1mM7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2632&quot; height=&quot;944&quot; data-filename=&quot;2.png&quot; data-origin-width=&quot;2632&quot; data-origin-height=&quot;944&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;S3 버킷 정책에 내 IP 만 접근할 수 있도록 버킷정책을 꾸려보자&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;테스트는 내 현재 IP와 VPN 사용해서 다른 IP를 획득하여 액세스가 가능한지 여부에 대해 확인해볼 예정이다.&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.&amp;nbsp; S3 버킷 정책 설정 - IP&amp;nbsp;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;3.png&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;126&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SlZPx/btr5Q3Ew7yC/LVKwlgTEHisRXB5UcPVs20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SlZPx/btr5Q3Ew7yC/LVKwlgTEHisRXB5UcPVs20/img.png&quot; data-alt=&quot;내 IP 주소&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SlZPx/btr5Q3Ew7yC/LVKwlgTEHisRXB5UcPVs20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSlZPx%2Fbtr5Q3Ew7yC%2FLVKwlgTEHisRXB5UcPVs20%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;29&quot; data-filename=&quot;3.png&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;126&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;내 IP 주소&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;S3 버킷 정책&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1679836967598&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
    &quot;Version&quot;: &quot;2012-10-17&quot;,
    &quot;Statement&quot;: [
        {
            &quot;Sid&quot;: &quot;AllowIPs&quot;,
            &quot;Effect&quot;: &quot;Allow&quot;,
            &quot;Principal&quot;: &quot;*&quot;,
            &quot;Action&quot;: &quot;s3:GetObject&quot;,
            &quot;Resource&quot;: &quot;arn:aws:s3:::testforjiwoo/*&quot;,    # &amp;lt;&amp;lt;&amp;lt; your S3 Bucket
            &quot;Condition&quot;: {
                &quot;IpAddress&quot;: {
                    &quot;aws:SourceIp&quot;: [
                        &quot;210.95.62.154&quot;   # &amp;lt;&amp;lt;&amp;lt; your IP
                    ]
                }
            }
        }
    ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 버킷 정책을 저장하고 미리 정의된 URL로 접근해보자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. TEST&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1044&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqATIa/btr5QAinn4m/7sBJosYA4uuzFZhzTrdeR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqATIa/btr5QAinn4m/7sBJosYA4uuzFZhzTrdeR1/img.png&quot; data-alt=&quot;버킷정책에 설정한 IP 로 URL 접근 시 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqATIa/btr5QAinn4m/7sBJosYA4uuzFZhzTrdeR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdqATIa%2Fbtr5QAinn4m%2F7sBJosYA4uuzFZhzTrdeR1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;1044&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1044&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;버킷정책에 설정한 IP 로 URL 접근 시 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 접근되는 모습&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;써드파티의 툴 VPN을 사용해서 IP를 변환시켜 접근시도해본다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;146&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tuKQf/btr5Ulrelb1/7pIDawFZMwBgdmfacQbyi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tuKQf/btr5Ulrelb1/7pIDawFZMwBgdmfacQbyi1/img.png&quot; data-alt=&quot;변환된 내 IP&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tuKQf/btr5Ulrelb1/7pIDawFZMwBgdmfacQbyi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtuKQf%2Fbtr5Ulrelb1%2F7pIDawFZMwBgdmfacQbyi1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;22&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;146&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;변환된 내 IP&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ritYa/btr53EwPWBu/6Ku7QkgVA24MIpMrG3uit1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ritYa/btr53EwPWBu/6Ku7QkgVA24MIpMrG3uit1/img.png&quot; data-alt=&quot;변환된 IP로 URL 접근 시 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ritYa/btr53EwPWBu/6Ku7QkgVA24MIpMrG3uit1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FritYa%2Fbtr53EwPWBu%2F6Ku7QkgVA24MIpMrG3uit1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;460&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;460&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;변환된 IP로 URL 접근 시 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;접근 실패되는 모습&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 외 다른 방법으로 안전하게 S3 액세스하는 방법들이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/userguide/example-bucket-policies.html#example-bucket-policies-use-case-3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/userguide/example-bucket-policies.html#example-bucket-policies-use-case-3&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://repost.aws/ko/knowledge-center/block-s3-traffic-vpc-ip&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://repost.aws/ko/knowledge-center/block-s3-traffic-vpc-ip&lt;/a&gt;&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>aws</category>
      <category>s3</category>
      <author>copcat</author>
      <guid isPermaLink="true">https://try-it.tistory.com/68</guid>
      <comments>https://try-it.tistory.com/68#entry68comment</comments>
      <pubDate>Sun, 26 Mar 2023 22:35:11 +0900</pubDate>
    </item>
    <item>
      <title>AWS Lambda로 RDS 와 외부 인터넷 접근하기</title>
      <link>https://try-it.tistory.com/67</link>
      <description>&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/AJuakfo.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;API를 통해 데이터를 가져와 AWS RDS 적재하는 역할의 Lambda를 사용하면서 겪은 삽질기(경험 부족)입니다.&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;354&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDWQer/btr0DUUfA6V/Ek4Ot9z0eJbvFhaAOnJppK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDWQer/btr0DUUfA6V/Ek4Ot9z0eJbvFhaAOnJppK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDWQer/btr0DUUfA6V/Ek4Ot9z0eJbvFhaAOnJppK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDWQer%2Fbtr0DUUfA6V%2FEk4Ot9z0eJbvFhaAOnJppK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;354&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;354&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 만든 Lambda 는 위의 캡쳐 사진처럼 간단합니다. 또한 다음과 같은 역할을 수행하고자 합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;외부 인터넷을 통해 API를 호출하여 데이터를 가져온다.&lt;/li&gt;
&lt;li&gt;AWS RDS에 접근하여 데이터를 적재한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 Lambda 에는 1) 외부 인터넷을 접속할 수 있는 인터넷 게이트웨이가 필요하며, 2) RDS과 같은 AWS 리소스를 사용하기 위해선 해당 VPC 망에 존재해야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lambda 의 VPC 활성화 옵션을 통해 RDS 와 같은 VPC 로 지정하였고, 서브넷 또한 퍼블릭 서브넷으로 지정하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;람다는 기본적으로 인터넷과 통신이 되기 때문에 당연히 될거라 배제하고 진행했었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 API 를 호출하는 데 있어 NetworkConnection Error 가 반복되면서 인터넷 접속이 불가능하다고 오류를 마구 뱉습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2420&quot; data-origin-height=&quot;1212&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xJ2da/btr0HzB1Nos/23bHXthST7NujpUQUJRjy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xJ2da/btr0HzB1Nos/23bHXthST7NujpUQUJRjy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xJ2da/btr0HzB1Nos/23bHXthST7NujpUQUJRjy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxJ2da%2Fbtr0HzB1Nos%2F23bHXthST7NujpUQUJRjy1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2420&quot; height=&quot;1212&quot; data-origin-width=&quot;2420&quot; data-origin-height=&quot;1212&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/configuration-vpc.html#vpc-setup-guidelines&quot;&gt;공식문서&lt;/a&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;에서는 인터넷의 사용이 필요한 경우 &lt;/span&gt;&lt;span&gt;해당 Lambda가 이용하는 VPC의 서브넷에 NAT 나 NAT 인스턴스를 할당해야한다고 합니다. &lt;/span&gt;따라서 저는 NAT Gateway와 람다의 고가용성을 위해서 가용영역이 다른 서브넷 2개를 만들었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;NAT Gateway의 경우는 인터넷 게이트웨이가 있는 퍼블릭 서브넷에 위치시켰고, 앞서 만든 서브넷 2개는 라우팅 테이블을 만들어 연결하고 그 라우팅 테이블 규칙에는 NAT Gateway 를 추가하여 &lt;b&gt;외부 인터넷을 액세스할 수 없었던 문제&lt;/b&gt;를 해결하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;NAT Gateway 의 경우 서울리전 기준-시간당 0.059 USD입니다.&lt;/i&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 Lambda 함수는 AWS 서비스를 포함하여 인터넷에 액세스할 수 있지만 VPC의 프라이빗 리소스에는 액세스할 수 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lambda를 VPC의 프라이빗 서브넷에 연결하면 VPC의 프라이빗 리소스에 액세스할 수 있지만 인터넷이나 AWS 서비스에는 액세스할 수 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모두 원한다면 VPC의 프라이빗 서브넷에 함수를 연결하고 퍼블릭 서브넷에 NAT 게이트웨이를 생성한 다음 트래픽을 GW로 라우팅해야 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Internet Gateway&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인터넷 게이트웨이는 AWS VPC와 인터넷을 연결해주는 논리적인 커넥션&lt;/li&gt;
&lt;li&gt;1 VPC에 1 IGW 만 할당할 수 있고 통신 대역폭의 제한은 없음&lt;/li&gt;
&lt;li&gt;VPC에 인터넷 게이트웨이가 연결되어 있지 않으면, 외부에서 VPC 내부로 접근 할 수 없음&lt;/li&gt;
&lt;li&gt;적어도 1개의 퍼블릭 서브넷이 IGW로 접근하는 것을 라우팅 테이블에서 허용해 줘야 함&lt;/li&gt;
&lt;li&gt;라우팅 테이블에서 트래픽이 인터넷 게이트웨이를 향하게 된다면, 퍼블릭 서브넷으로 간주함.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;NAT Gateway&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프라이빗 서브넷안에 있는 리소스들이 인터넷에 접속할 수 있도록 해줌&lt;/li&gt;
&lt;li&gt;명시적으로 허용하지 않는 이상 &lt;b&gt;일방통행&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;외부 트래픽은 NAT Gateway를 통해 들어올 수 없음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Private Subnet 에서 생성된 Lambda 도 NAT Gateway를 지나 외부 인터넷과 통신할 수 있음&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;참고자료&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;- &lt;a href=&quot;https://aws.amazon.com/ko/premiumsupport/knowledge-center/internet-access-lambda-function/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://aws.amazon.com/ko/premiumsupport/knowledge-center/internet-access-lambda-function/&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1677340397926&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;company&quot; data-og-title=&quot;VPC에서 Lambda 함수에 인터넷 액세스 권한 부여&quot; data-og-description=&quot;Amazon VPC에 연결된 Lambda 함수에 인터넷 액세스 권한을 부여하려면 어떻게 해야 합니까? 최종 업데이트 날짜: 2023년 2월 16일 Amazon Virtual Private Cloud(VPC)에 연결된 AWS Lambda 함수에 인터넷 액세스 권한&quot; data-og-host=&quot;aws.amazon.com&quot; data-og-source-url=&quot;https://aws.amazon.com/ko/premiumsupport/knowledge-center/internet-access-lambda-function/&quot; data-og-url=&quot;https://aws.amazon.com/ko/premiumsupport/knowledge-center/internet-access-lambda-function/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/rbGUu/hyRJHn3v8Q/FTeYkU6SfDwud8PufBkk50/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/gZ5b5/hyRKLWHNjd/jYzVLLMeplkjXDXHBHDKdk/img.png?width=179&amp;amp;height=109&amp;amp;face=0_0_179_109&quot;&gt;&lt;a href=&quot;https://aws.amazon.com/ko/premiumsupport/knowledge-center/internet-access-lambda-function/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://aws.amazon.com/ko/premiumsupport/knowledge-center/internet-access-lambda-function/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/rbGUu/hyRJHn3v8Q/FTeYkU6SfDwud8PufBkk50/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/gZ5b5/hyRKLWHNjd/jYzVLLMeplkjXDXHBHDKdk/img.png?width=179&amp;amp;height=109&amp;amp;face=0_0_179_109');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;VPC에서 Lambda 함수에 인터넷 액세스 권한 부여&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Amazon VPC에 연결된 Lambda 함수에 인터넷 액세스 권한을 부여하려면 어떻게 해야 합니까? 최종 업데이트 날짜: 2023년 2월 16일 Amazon Virtual Private Cloud(VPC)에 연결된 AWS Lambda 함수에 인터넷 액세스 권한&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/services-rds-tutorial.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/services-rds-tutorial.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1677340399965&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;자습서: Amazon VPC에서 Amazon RDS에 액세스하도록 Lambda 함수 구성 - AWS Lambda&quot; data-og-description=&quot;이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.&quot; data-og-host=&quot;docs.aws.amazon.com&quot; data-og-source-url=&quot;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/services-rds-tutorial.html&quot; data-og-url=&quot;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/services-rds-tutorial.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/services-rds-tutorial.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/services-rds-tutorial.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;자습서: Amazon VPC에서 Amazon RDS에 액세스하도록 Lambda 함수 구성 - AWS Lambda&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>인프라/AWS</category>
      <category>aws</category>
      <category>lambda</category>
      <category>rds</category>
      <category>vpc</category>
      <author>copcat</author>
      <guid isPermaLink="true">https://try-it.tistory.com/67</guid>
      <comments>https://try-it.tistory.com/67#entry67comment</comments>
      <pubDate>Fri, 24 Feb 2023 23:17:53 +0900</pubDate>
    </item>
  </channel>
</rss>