<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>덕규의 아즈카반</title>
    <link>https://frontheadlock.tistory.com/</link>
    <description>도비가 되고 싶은 유치원생입니다.</description>
    <language>ko</language>
    <pubDate>Sat, 5 Sep 2026 23:41:06 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>frontheadlock</managingEditor>
    <image>
      <title>덕규의 아즈카반</title>
      <url>https://tistory1.daumcdn.net/tistory/8418019/attach/fd535b05c5aa4fd3bc8ec4439a2ac43d</url>
      <link>https://frontheadlock.tistory.com</link>
    </image>
    <item>
      <title>KCD x Ceph x OpenInfra Korea Day 2026</title>
      <link>https://frontheadlock.tistory.com/23</link>
      <description>&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;KakaoTalk_Photo_2026-09-01-18-00-37.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCC2sf/dJMcadXCPiX/NJcS8Xv7NAq8udJRgchY31/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCC2sf/dJMcadXCPiX/NJcS8Xv7NAq8udJRgchY31/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCC2sf/dJMcadXCPiX/NJcS8Xv7NAq8udJRgchY31/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCC2sf%2FdJMcadXCPiX%2FNJcS8Xv7NAq8udJRgchY31%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;3024&quot; height=&quot;4032&quot; data-filename=&quot;KakaoTalk_Photo_2026-09-01-18-00-37.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&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: #000000; text-align: start;&quot;&gt;KCD x Ceph x OpenInfra Korea Day 2026에 다녀왔습니다.&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: #000000; text-align: start;&quot;&gt;AI는 더 이상 특별한 기술이 아닌, 인프라 생태계의 기저에 깔리는 전제 조건이 되었습니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;어플리케이션 레이어 뿐만 아니라 kubernetes, storage , GPU 스케줄링 등 모든 주제에 AI가 들어가 있었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;분산 스토리지/CPU/GPU 등 하드웨어를 운영하면서도 AI가 도입되고, &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;거의 모든 회사가 AIOps를 통한 운영 자동화를 도입하고 있었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;앞으로는 AI 도입 여부보다 이걸 어떻게 더 잘 활용하는 지에 대한 고민이 필요한 시대인 것 같습니다.&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;행사에서는 다양한 연사자 분들이 나오셔서,&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-09-01 오후 6.29.48.png&quot; data-origin-width=&quot;1576&quot; data-origin-height=&quot;820&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4jw5M/dJMcagz0KrA/IDAGGG6VkBuIxe7crNVGcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4jw5M/dJMcagz0KrA/IDAGGG6VkBuIxe7crNVGcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4jw5M/dJMcagz0KrA/IDAGGG6VkBuIxe7crNVGcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4jw5M%2FdJMcagz0KrA%2FIDAGGG6VkBuIxe7crNVGcK%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;1576&quot; height=&quot;820&quot; data-filename=&quot;스크린샷 2026-09-01 오후 6.29.48.png&quot; data-origin-width=&quot;1576&quot; data-origin-height=&quot;820&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;특히 인상 깊었던 부분은 Naver 하현님의 세션이었습니다.&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;위 세션에서는 Multi-Cluster 환경에서 발생 가능한 자원 파편화를 해결 과정을 공유해주셨습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 HW 자원의 가격이 기하급수적으로 오르며,&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;/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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유휴 클러스터의 노드를 떼내어 busy resource에 붙이면 replica가 깨지는 문제가 발생할 수 있습니다.&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;또한 그렇게 구성을 하며 자체적으로 ceph 스토리지에 오케스트레이터 패턴을 구축했다는 점이 인상깊었습니다.&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;/p&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;이번 행사에서 한가지 충격적이었던 것은 AI의 중요성으로 오히려 오픈소스의 중요성이 더 커진다는 점이었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;오프닝에서 ASIA CNCF의 Director인 Horace Li 가 얘기한 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;AI 인프라의 성장이 폐쇄적으로 흘러갈 경우,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; 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: #000000; text-align: start;&quot;&gt;CNCF에서 키워내는 다양한 오픈소스들이 성장하고, 사람들이 관심을 가지는 것이 얼마나 중요한 지 알 수 있었습니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;기계처럼 AI를 소비만 하는 것이 아니라, &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;AI가 돌아가는 판에 대해 더 이해하고 더 미래를 바라볼 수 있는 눈을 키울 필요성을 깨달을 수 있었습니다..&lt;/span&gt;&lt;/p&gt;</description>
      <category>생각</category>
      <author>frontheadlock</author>
      <guid isPermaLink="true">https://frontheadlock.tistory.com/23</guid>
      <comments>https://frontheadlock.tistory.com/23#entry23comment</comments>
      <pubDate>Tue, 1 Sep 2026 22:18:06 +0900</pubDate>
    </item>
    <item>
      <title>HW 기본 원리</title>
      <link>https://frontheadlock.tistory.com/22</link>
      <description>&lt;h2 data-heading=&quot;0. 컴퓨터 구성도&quot; data-ke-size=&quot;size26&quot;&gt;컴퓨터 구성도&lt;/h2&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;폰 노이만 구조(Von Neumann Architecture)&lt;/b&gt; 를 따라 구성됩니다.&lt;br /&gt;프로그램(명령어)과 데이터를 메모리에 저장하고,&lt;br /&gt;CPU가 이를 순서대로 읽어 실행하는 구조를 가집니다.&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-08-25 오후 7.12.38.png&quot; data-origin-width=&quot;2908&quot; data-origin-height=&quot;1560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Umo4J/dJMcabFljZH/EauDOT7TjMnoeufoEOEElK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Umo4J/dJMcabFljZH/EauDOT7TjMnoeufoEOEElK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Umo4J/dJMcabFljZH/EauDOT7TjMnoeufoEOEElK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUmo4J%2FdJMcabFljZH%2FEauDOT7TjMnoeufoEOEElK%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;726&quot; height=&quot;389&quot; data-filename=&quot;스크린샷 2026-08-25 오후 7.12.38.png&quot; data-origin-width=&quot;2908&quot; data-origin-height=&quot;1560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;운영체제에 대해 얘기를 할 때, 가장 많이 나오는 예시인 주방에 비유하면 쉽습니다.&lt;br /&gt;요리를 할 때는 창고에 있는 재료들로 바로 요리를 시작할 수는 없습니다.&lt;br /&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;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CPU&lt;/td&gt;
&lt;td&gt;명령어 실행&amp;middot;연산&lt;/td&gt;
&lt;td&gt;요리사&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;레지스터&lt;/td&gt;
&lt;td&gt;연산 직전/직후 값 보관&lt;/td&gt;
&lt;td&gt;요리사의 양손&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;캐시 (L1~L3)&lt;/td&gt;
&lt;td&gt;곧 쓸 데이터를 미리 근처에&lt;/td&gt;
&lt;td&gt;조리대 위 선반&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAM (1차)&lt;/td&gt;
&lt;td&gt;실행 중인 프로그램&amp;middot;데이터&lt;/td&gt;
&lt;td&gt;주방 조리대&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSD/HDD (2차)&lt;/td&gt;
&lt;td&gt;영구 보관&lt;/td&gt;
&lt;td&gt;창고/냉장고&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2차 메모리(창고) &amp;rarr; 1차 메모리(조리대) &amp;rarr; 캐시(선반) &amp;rarr; 레지스터(손) &amp;rarr; ALU(계산)&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-heading=&quot;1. CPU&quot; data-ke-size=&quot;size26&quot;&gt;1. CPU&lt;/h2&gt;
&lt;h4 data-heading=&quot;실행과 연산&quot; data-ke-size=&quot;size20&quot;&gt;실행과 연산&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU는 다른 말로 Machine (명령을 내릴 대상)이라고도 부릅니다.&lt;br /&gt;CPU에 내려가는 명령들은 전기 신호로 입력되고,&lt;br /&gt;CPU는 그러한 신호를 굉장히 빠른 속도로 처리하며 컴퓨터를 동작시킵니다.&lt;/p&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;b&gt;연산(operation)&lt;/b&gt;: ALU가 수행하는 개별 계산 하나로, 덧셈, 비교 등이 각각 연산&lt;/li&gt;
&lt;li&gt;&lt;b&gt;실행(execution)&lt;/b&gt;: 명령어들이 연속적&amp;middot;순차적으로 이어진 &lt;b&gt;하나의 흐름&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 구분이 중요한 이유는, 실행이라는 &lt;b&gt;흐름이 맥락을 만들기 때문입니다&lt;/b&gt;.&lt;br /&gt;지금 어떤 명령을 실행 중이고, 레지스터에 어떤 값이 들어있는 지 등이 모여 맥락이 되고,&lt;br /&gt;맥락들이 결국에는 실행의 단위가 됩니다.&lt;/p&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;b&gt;프로세스(Process)&lt;/b&gt;: 실행 중인 프로그램. 독립된 메모리 공간(가상 주소 공간)을 가진다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;쓰레드(Thread)&lt;/b&gt;: 프로세스 안의 실행 흐름. 메모리는 공유하되 실행 맥락(레지스터&amp;middot;스택)은 별도
&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;쓰레드가 죽으면 OS에서 알아서 거둬들임&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-heading=&quot;CPU SPEC 조회&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-heading=&quot;CPU SPEC 조회&quot; data-ke-size=&quot;size20&quot;&gt;CPU SPEC 조회&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 CPU에는 어떤 기능 들이 중요할까요?&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;1302&quot; data-origin-height=&quot;1800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6DpOr/dJMcahMljaA/1jQ8WaQl61IkYirYrD3g81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6DpOr/dJMcahMljaA/1jQ8WaQl61IkYirYrD3g81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6DpOr/dJMcahMljaA/1jQ8WaQl61IkYirYrD3g81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6DpOr%2FdJMcahMljaA%2F1jQ8WaQl61IkYirYrD3g81%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;534&quot; height=&quot;738&quot; data-origin-width=&quot;1302&quot; data-origin-height=&quot;1800&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;예를 들어, CPU를 사고자 할 때 눈여겨 보는 사례에 대해서 알아 보겠습니다.&lt;br /&gt;쇼핑몰에서 흔히 보는 AMD Ryzen / 8코어,16스레드 / 기본 3.8GHz / L2 8MB, L3 32MB&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%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;코어(Core)&lt;/td&gt;
&lt;td&gt;물리 연산 장치 개수. 8코어 = 8개 실행 흐름을 물리적으로 동시 처리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;스레드(Thread)&lt;/td&gt;
&lt;td&gt;논리 프로세서 수. SMT(하이퍼스레딩)로 코어당 2개 &amp;rarr; 8C/16T&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;기본/부스트 클럭&lt;/td&gt;
&lt;td&gt;초당 동작 사이클 수. 3.8GHz = 초당 38억 사이클&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L2 / L3 캐시&lt;/td&gt;
&lt;td&gt;코어 전용(L2) / 코어 공유(L3) 캐시 용량&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;메모리 규격&lt;/td&gt;
&lt;td&gt;지원 RAM 종류&amp;middot;속도 (DDR5-5600, 듀얼 채널 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div data-callout-metadata=&quot;&quot; data-callout-fold=&quot;&quot; data-callout=&quot;tip&quot;&gt;
&lt;div&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;클럭(Hz)의 의미&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;1Hz = 1초에 1번. 1kHz = 1,000번, 1GHz = 10억 번.&lt;br /&gt;사이클마다 트랜지스터 스위치들이 on/off 상태를 바꾸며 연산이 한 단계씩 진행된다.&lt;br /&gt;단,&amp;nbsp; 클럭이 높다 &amp;ne; 무조건 빠르다.&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-heading=&quot;비트(bit)&quot; data-ke-size=&quot;size20&quot;&gt;비트(bit)&lt;/h4&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;br /&gt;&lt;b&gt;1비트는 두 가지 상태를 표시하는 전기 스위치 1개&lt;/b&gt;로, 전류가 흐르면 1, 흐르지 않으면 0입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;32bit 신호란 이런 스위치 32개를 전자적 속도로 on/off 하는 것이고,&lt;br /&gt;이 조작이 1초에 1000번 일어나면 1kHz입니다.&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%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;bit&lt;/td&gt;
&lt;td&gt;0 또는 1&lt;/td&gt;
&lt;td&gt;최소 단위&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Byte&lt;/td&gt;
&lt;td&gt;8 bit&lt;/td&gt;
&lt;td&gt;&lt;b&gt;메모리 주소 부여의 기본 단위&lt;/b&gt;, ASCII 문자 1개&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KB / KiB&lt;/td&gt;
&lt;td&gt;10&amp;sup3; / 2&amp;sup1;⁰ Byte&lt;/td&gt;
&lt;td&gt;마케팅은 10진, OS는 2진 단위 혼용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Word&lt;/td&gt;
&lt;td&gt;CPU가 한 번에 처리하는 크기&lt;/td&gt;
&lt;td&gt;64bit CPU = 8 Byte&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 data-heading=&quot;BitStream &amp;rarr; Format &amp;rarr; Protocol&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-heading=&quot;BitStream &amp;rarr; Format &amp;rarr; Protocol&quot; data-ke-size=&quot;size20&quot;&gt;BitStream &amp;rarr; Format &amp;rarr; Protocol&lt;/h4&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;BitStream&lt;/b&gt;이라 부릅니다.&lt;br /&gt;그런데, 비트 자체에는 아무 의미가 없습니다.&lt;br /&gt;01001000이라는 비트열은 숫자 72일 수도, 문자 'H'일 수도, 기계어 명령의 일부일 수도 있습니다.&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;스크린샷 2026-08-25 오후 7.11.17.png&quot; data-origin-width=&quot;2872&quot; data-origin-height=&quot;986&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bi1JNd/dJMcacEoY8r/KHHYj30wGsm27jgsGsFEF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bi1JNd/dJMcacEoY8r/KHHYj30wGsm27jgsGsFEF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bi1JNd/dJMcacEoY8r/KHHYj30wGsm27jgsGsFEF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbi1JNd%2FdJMcacEoY8r%2FKHHYj30wGsm27jgsGsFEF1%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;682&quot; height=&quot;234&quot; data-filename=&quot;스크린샷 2026-08-25 오후 7.11.17.png&quot; data-origin-width=&quot;2872&quot; data-origin-height=&quot;986&quot;/&gt;&lt;/span&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;&lt;b&gt;Format&lt;/b&gt;: 한 곳에 &lt;b&gt;저장된&lt;/b&gt; 비트열에 해석 규칙(구조)을 부여한 것. 파일 / 파일 시스템 포맷.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Protocol&lt;/b&gt;: 두 주체 사이를 &lt;b&gt;오가는&lt;/b&gt; 비트열의 규약. 네트워크로 가면 프로토콜&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 실제로 2진수를 활용하기에는 표기가 너무 길어지기에 16진수(hex)로 축약해 씁니다.&lt;br /&gt;16진수 한 자리를 4비트에 대응시켜 변환을 빠르게 가져갈 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;2진수  1111 1111  =  16진수 FF  =  10진수 255
2진수  0100 1000  =  16진수 48  =  10진수 72  ('H'의 ASCII)
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU가 실제로 읽고 실행하는 것은 &lt;b&gt;기계어(machine code)&lt;/b&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;h2 data-heading=&quot;2. CPU의 연산 흐름&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-heading=&quot;2. CPU의 연산 흐름&quot; data-ke-size=&quot;size26&quot;&gt;2. CPU의 연산 흐름&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU 내부에서 연산은 아래와 같이 흘러갑니다.&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;스크린샷 2026-08-25 오후 7.09.25.png&quot; data-origin-width=&quot;2766&quot; data-origin-height=&quot;1604&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qi0zk/dJMcahMli2K/koWJHOW95MvNHhkt4HiEDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qi0zk/dJMcahMli2K/koWJHOW95MvNHhkt4HiEDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qi0zk/dJMcahMli2K/koWJHOW95MvNHhkt4HiEDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqi0zk%2FdJMcahMli2K%2FkoWJHOW95MvNHhkt4HiEDK%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;2766&quot; height=&quot;1604&quot; data-filename=&quot;스크린샷 2026-08-25 오후 7.09.25.png&quot; data-origin-width=&quot;2766&quot; data-origin-height=&quot;1604&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;h4 data-heading=&quot;구성 요소&quot; data-ke-size=&quot;size20&quot;&gt;구성 요소&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;ALU (Arithmetic Logic Unit)&lt;/b&gt;: 산술&amp;middot;논리 연산을 실제 수행하는 핵심 회로.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;레지스터(Register)&lt;/b&gt;: CPU 내부의 초고속 저장 공간.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 레지스터가 값을 하나씩 담고, 레지스터의 값들을 ALU가 연산합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;제어 장치(CU)&lt;/b&gt;: 명령어를 해석(decode)하고 각 장치에 제어 신호를 보냅니다.&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;스크린샷 2026-08-25 오후 7.09.53.png&quot; data-origin-width=&quot;2832&quot; data-origin-height=&quot;1146&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QHjqd/dJMcahMli3D/7MNqtA5dnS1YSlVZxP8QOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QHjqd/dJMcahMli3D/7MNqtA5dnS1YSlVZxP8QOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QHjqd/dJMcahMli3D/7MNqtA5dnS1YSlVZxP8QOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQHjqd%2FdJMcahMli3D%2F7MNqtA5dnS1YSlVZxP8QOk%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;2832&quot; height=&quot;1146&quot; data-filename=&quot;스크린샷 2026-08-25 오후 7.09.53.png&quot; data-origin-width=&quot;2832&quot; data-origin-height=&quot;1146&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-heading=&quot;실행 절차&quot; data-ke-size=&quot;size20&quot;&gt;실행 절차&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;2차 메모리&lt;/b&gt;(SSD)에 저장된 실행 코드를 &lt;b&gt;1차 메모리&lt;/b&gt;(RAM)에 Load&lt;/li&gt;
&lt;li&gt;RAM에 로드된 실행 코드를 CPU가 Fetch.&lt;/li&gt;
&lt;li&gt;이때 L1~L3 캐시에 &lt;b&gt;다음에 쓰일 명령과 데이터가 미리 로드&lt;/b&gt;(pre-fetch).&lt;/li&gt;
&lt;li&gt;가져온 데이터를 CPU &lt;b&gt;레지스터&lt;/b&gt;에 저장&lt;/li&gt;
&lt;li&gt;레지스터 값에 대해 ALU가 &lt;b&gt;연산&lt;/b&gt;, 결과를 레지스터에(필요 시 메모리에) 기록&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 컴퓨터가 동작할 때, 실행되는 스레드는 수백개지만 실행 가능한 Core는 n개입니다.&lt;br /&gt;그래서 운영체제는 코어 위에서 실행 흐름을 빠르게 변경하며 실행합니다.&lt;br /&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;h4 data-heading=&quot;하드웨어&quot; data-ke-size=&quot;size20&quot;&gt;하드웨어&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메인보드에 CPU는 어떻게 올라가게 될까요?&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;스크린샷 2026-08-25 오후 7.10.19.png&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;1792&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NRyrQ/dJMb99Of5aC/JtBwGh8Z1S3uxWu6O2IwXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NRyrQ/dJMb99Of5aC/JtBwGh8Z1S3uxWu6O2IwXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NRyrQ/dJMb99Of5aC/JtBwGh8Z1S3uxWu6O2IwXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNRyrQ%2FdJMb99Of5aC%2FJtBwGh8Z1S3uxWu6O2IwXK%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;602&quot; height=&quot;609&quot; data-filename=&quot;스크린샷 2026-08-25 오후 7.10.19.png&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;1792&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;CPU는 메인보드에 있는 소켓이란 칸 위에 올라가 그 안에서 동작합니다.&lt;br /&gt;이러한 소켓에는 PGA, LGA, BGA 등의 종류가 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;PGA : CPU에 핀 부착&lt;/li&gt;
&lt;li&gt;LGA : 소켓에 핀 부착&lt;/li&gt;
&lt;li&gt;BGA : 납땜되어 출고&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1개의 Socket 내에는 1개의 CPU를 꽂을 수도,&lt;br /&gt;여러 개의 CPU를 꽂아 넣을 수도 있습니다.&lt;br /&gt;서버의 성능이 높아질 수록 CPU 코어 수가 계속 늘어나게 되고,&lt;br /&gt;여러 CPU를 꽂기 위해 패키지 안에 들어가는 소켓의 수도 늘어나게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서, 패키지를 통해 분리된 CPU 간의 원활한 통신을 위해서 NUMA 아키텍처를 사용합니다.&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;스크린샷 2026-08-25 오후 7.10.46.png&quot; data-origin-width=&quot;1388&quot; data-origin-height=&quot;528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOLfIS/dJMcaixNLUu/3ycylqeZ5fu113SyAGneC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOLfIS/dJMcaixNLUu/3ycylqeZ5fu113SyAGneC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOLfIS/dJMcaixNLUu/3ycylqeZ5fu113SyAGneC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOLfIS%2FdJMcaixNLUu%2F3ycylqeZ5fu113SyAGneC1%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;631&quot; height=&quot;240&quot; data-filename=&quot;스크린샷 2026-08-25 오후 7.10.46.png&quot; data-origin-width=&quot;1388&quot; data-origin-height=&quot;528&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;CPU는 기본적으로 RAM으로부터 데이터를 읽어와 작업을 진행합니다.&lt;br /&gt;여러 개의 CPU가 존재하는 상황에서,&lt;br /&gt;몇몇 CPU가 메모리를 선점유 시 남은 CPU가 유휴 상태에 빠지게 될 수 있습니다.&lt;br /&gt;이러한 병목을 방지하고자 나온 아키텍처 구조로,&lt;br /&gt;소켓 옆에 DIMM을 분리해 꽂아 메모리를 고루 할당합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NUMA의 경우는, 말하면 이야기가 길어져 추후에 별도로 작성해보겠습니다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 메모리 계층&lt;/h2&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;스크린샷 2026-08-25 오후 6.51.49.png&quot; data-origin-width=&quot;2778&quot; data-origin-height=&quot;1574&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btOI1K/dJMcafHSiTj/bzNr1lKPqOkrEmJvlF9XU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btOI1K/dJMcafHSiTj/bzNr1lKPqOkrEmJvlF9XU1/img.png&quot; data-alt=&quot;기억장치 계층&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btOI1K/dJMcafHSiTj/bzNr1lKPqOkrEmJvlF9XU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtOI1K%2FdJMcafHSiTj%2FbzNr1lKPqOkrEmJvlF9XU1%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;2778&quot; height=&quot;1574&quot; data-filename=&quot;스크린샷 2026-08-25 오후 6.51.49.png&quot; data-origin-width=&quot;2778&quot; data-origin-height=&quot;1574&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 data-ke-size=&quot;size16&quot;&gt;기억장치들은 위로 갈수록 &lt;b&gt;빠르고, 작고, 비싸고, CPU에 가깝습니다.&lt;/b&gt;&lt;br /&gt;반면 , 아래로 갈수록 &lt;b&gt;느리고, 크고, 싸고, 비휘발성&lt;/b&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;레지스터 ~ Cache Memory : CPU 내부&lt;/li&gt;
&lt;li&gt;RAM : 메모리 (컴퓨터 내부)&lt;/li&gt;
&lt;li&gt;HDD , SSD : 외부 저장소 (External Storage)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작업 지연시간을 근사치로 표현하면 다음과 같이 확인할 수 있습니다.&lt;/p&gt;
&lt;table style=&quot;color: #333333; text-align: start; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;레지스터 접근&lt;/td&gt;
&lt;td&gt;~0.3 ns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L1 캐시 히트&lt;/td&gt;
&lt;td&gt;~1 ns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L2 캐시 히트&lt;/td&gt;
&lt;td&gt;~4 ns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L3 캐시 히트&lt;/td&gt;
&lt;td&gt;~15 ns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAM 접근&lt;/td&gt;
&lt;td&gt;~100 ns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HDD 탐색&lt;/td&gt;
&lt;td&gt;~5&amp;ndash;10 ms&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차 메모리 &amp;rarr; 1차 메모리 &amp;rarr; 캐시 &amp;rarr; 레지스터 순으로 올라와 작업이 실행됩니다.&lt;/p&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;디스크 &amp;harr; RAM: &lt;b&gt;블록/페이지 (4KB)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;RAM &amp;harr; 캐시: &lt;b&gt;캐시 라인 (64B)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;캐시 &amp;harr; 레지스터: &lt;b&gt;워드 (8B)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Cache Memory&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저장장치의 계층적 구조를 통해 CPU가 연산을 하기 위해서는,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSD에서 정보를 가져와 RAM에 올리고, 그 정보를 CPU가 참조해서 연산함을 확인할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데, CPU가 매 작업에 대해 RAM을 거쳐오기에는 RAM과 CPU의 작업 속도차이가 300배 이상 납니다.&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;이를 극복하고자 나온 것이 Cache Memory 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RAM보다 훨씬 빠른 SRAM을 CPU 안에 넣고, &lt;b&gt;사용할 명령어와 데이터를 미리 가져다 두는 것&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 명령어 혹은 데이터를 prefetch 하여 RAM과 CPU 간의 속도 간극을 메우게 됩니다.&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-08-25 오후 7.08.11.png&quot; data-origin-width=&quot;2536&quot; data-origin-height=&quot;1624&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AYEkg/dJMcagfChQq/OVoeHI5us9xNSDZYfKaCTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AYEkg/dJMcagfChQq/OVoeHI5us9xNSDZYfKaCTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AYEkg/dJMcagfChQq/OVoeHI5us9xNSDZYfKaCTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAYEkg%2FdJMcagfChQq%2FOVoeHI5us9xNSDZYfKaCTk%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;748&quot; height=&quot;479&quot; data-filename=&quot;스크린샷 2026-08-25 오후 7.08.11.png&quot; data-origin-width=&quot;2536&quot; data-origin-height=&quot;1624&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;RAM에서 올라온 데이터와 명령어는 &lt;b&gt;모두 L3로&lt;/b&gt; 들어오고, 각 코어가 필요로 하는 것이 L2 &amp;rarr; L1로 분배된다.&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;b&gt;L3 (전체 코어 공유, LLC)&lt;/b&gt;: 가장 큰 캐시로 코어들 사이에 데이터가 오가는 접점&lt;/li&gt;
&lt;li&gt;&lt;b&gt;L2 (코어당, 통합형)&lt;/b&gt;: 각 코어별로 해당되는 명령과 데이터를 구분 없이 함께 저장&lt;/li&gt;
&lt;li&gt;&lt;b&gt;L1 (코어당, 분리형)&lt;/b&gt;: &lt;b&gt;L1d(데이터)와 L1i(명령어)가 별도로 존재&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;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2차 메모리&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차 메모리란 1차 메모리와 정확히 반대입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;저속이지만 비휘발성&lt;/b&gt;이라 전원이 꺼져도 데이터가 유지됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU는 2차 메모리를 직접 연산 대상이 아닌, 데이터의 저장 장치로 사용을 합ㄴ다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-heading=&quot;7.1 HDD &amp;mdash; 기계식 저장 장치&quot; data-ke-size=&quot;size20&quot;&gt;HDD&amp;nbsp; (기계식 저장 장치)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HDD는 자성 물질을 입힌 원판(&lt;b&gt;플래터&lt;/b&gt;)을 회전시키고, 그 위를 &lt;b&gt;헤드&lt;/b&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;HDD는 기계식이기 때문에 전기로 동작하는 다른 장치들에 비해 느립니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;탐색(seek)&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;순차 접근은 나쁘지 않게(~150MB/s)&lt;/b&gt; 해내지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;헤드가 계속 이동해야 하는 &lt;b&gt;랜덤 접근은 많이 느립니다.(~1MB/s 수준)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;옛날 윈도우 컴퓨터에서 &quot;조각 모음&quot;을 돌리던 이유가 여기 있습니다.&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;h4 data-heading=&quot;7.2 SSD &amp;mdash; 전자식 저장 장치의 속사정&quot; data-ke-size=&quot;size20&quot;&gt;SSD (전자식 저장 장치)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSD는 &lt;b&gt;NAND 플래시&lt;/b&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;다만, SSD 내부는 생각보다 까다로운 제약 위에서 돌아갑니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;페이지(4~16KB)&lt;/b&gt; 단위로 읽고 쓰지만, 삭제는 페이지 수백 개를 묶은 &lt;b&gt;블록(수 MB)&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;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;FTL&lt;/b&gt; (Flash Translation Layer)&lt;/td&gt;
&lt;td&gt;OS가 보는 논리 주소 &amp;harr; 실제 물리 페이지 매핑 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Garbage Collection&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;무효 페이지가 쌓인 블록의 유효 데이터를 옮기고 블록을 지워 재활용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Wear Leveling&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;셀당 쓰기 수명(수천~수만 회)이 있어 마모를 고르게 분산&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;TRIM&lt;/b&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;삭제된 파일임을 알려 GC 보조&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;뿐만 아니라, SSD는 HDD와 다르게 중복 제거를 지원합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엔터프라이즈 급의 SSD 스토리지 서버를 사용할 경우,&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;/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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SATA : HDD 시절에 설계된 프로토콜로 직렬 전송 방식 지원&lt;/li&gt;
&lt;li&gt;NVMe : 플래시를 위해 새로 설계, PCIe 인터페이스를 통해 SSD의 성능 극대화&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;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;479&quot; data-origin-height=&quot;275&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cK1TDc/dJMcafVomK4/RCspOb9VdPpuAYxUZ0B3c0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cK1TDc/dJMcafVomK4/RCspOb9VdPpuAYxUZ0B3c0/img.png&quot; data-alt=&quot;충격&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cK1TDc/dJMcafVomK4/RCspOb9VdPpuAYxUZ0B3c0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcK1TDc%2FdJMcafVomK4%2FRCspOb9VdPpuAYxUZ0B3c0%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;507&quot; height=&quot;291&quot; data-origin-width=&quot;479&quot; data-origin-height=&quot;275&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 data-ke-size=&quot;size16&quot;&gt;사실 여태껏 DevOps 라는 직무에 대해 개발자들의 빌드/배포만 지원하면 된다고 생각했습니다.&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;/p&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 'DevOps/SE 개발자를 위한 리눅스 커널 이야기'라는 책을 읽으며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;buff/cache가 차 있는지 , iowait이 튀는 지 안튀는 지 확인하는 것을 넘어서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제가 생기는 환경에 따라서는 커널 수준에 대해서까지 확인하는 것도 DevOps 개발자의 영역임을 알았습니다.&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;더 나은 개발자가 되기 위해서 CS 기초 , 특히나 하드웨어의 영역에 대해서 미리 이해를 하고,&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; &amp;nbsp; &amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps</category>
      <author>frontheadlock</author>
      <guid isPermaLink="true">https://frontheadlock.tistory.com/22</guid>
      <comments>https://frontheadlock.tistory.com/22#entry22comment</comments>
      <pubDate>Tue, 25 Aug 2026 22:37:43 +0900</pubDate>
    </item>
    <item>
      <title>GenAI on EKS/K8s 인퍼런스 최적화(4)</title>
      <link>https://frontheadlock.tistory.com/21</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작업을 진행해오며 모델, 게이트웨이, 관측성을 갖춘 Agentic AI 플랫폼을 구축했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 이 플랫폼 위에,&lt;br /&gt;&lt;b&gt;&quot;Loan Buddy&quot;&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;이 과정에서 AI 에이전트가 복잡한 워크플로우를 어떻게 자동화하는지,&lt;br /&gt;배포하고 추적하며 확인하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-heading=&quot;어플리케이션 목표&quot; data-ke-size=&quot;size26&quot;&gt;어플리케이션 목표&lt;/h2&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;b&gt;AI 어플리케이션 구축&lt;/b&gt;: 앞서 구축한 플랫폼 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;지능형 에이전트 배포&lt;/b&gt;: 비즈니스 의사결정을 자동으로 수행&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Model Context Protocol(MCP) 사용&lt;/b&gt;: 에이전트에 외부 도구와의 기능 제공&lt;/li&gt;
&lt;li&gt;&lt;b&gt;에이전트 워크플로우 추적&lt;/b&gt;: Langfuse를 활용한 관측성 확보&lt;/li&gt;
&lt;li&gt;&lt;b&gt;아키텍처&lt;/b&gt;: Kubernetes 위의 AI 에이전트 구조&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;아키텍처&quot; data-ke-size=&quot;size23&quot;&gt;아키텍처&lt;/h3&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;1774&quot; data-origin-height=&quot;887&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZRNgU/dJMcabrIudG/2tFdx2TKUQRqzmleh2dhQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZRNgU/dJMcabrIudG/2tFdx2TKUQRqzmleh2dhQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZRNgU/dJMcabrIudG/2tFdx2TKUQRqzmleh2dhQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZRNgU%2FdJMcabrIudG%2F2tFdx2TKUQRqzmleh2dhQk%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;770&quot; height=&quot;385&quot; data-origin-width=&quot;1774&quot; data-origin-height=&quot;887&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;이전에 만들어 놓은 플랫폼에 에이전트와 MCP 서버를 추가해 구축할 예정입니다.&lt;br /&gt;플랫폼을 통해 모델 서빙과 라우팅, 추적을 진행하고,&lt;br /&gt;에이전트와 MCP를 이용해 해야할 업무들을 자동화할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 AI 요청은 &lt;b&gt;LiteLLM Gateway&lt;/b&gt;를 통해 처리&lt;/li&gt;
&lt;li&gt;모든 에이전트 활동을 &lt;b&gt;Langfuse&lt;/b&gt;로 추적&lt;/li&gt;
&lt;li&gt;어플리케이션은 지금까지 학습한 패턴 그대로 &lt;b&gt;EKS에 배포&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;/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;b&gt;AI Frameworks&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;LangGraph&lt;/b&gt;: AI 에이전트를 위한 워크플로우 오케스트레이션&lt;/li&gt;
&lt;li&gt;&lt;b&gt;LangChain&lt;/b&gt;: AI 애플리케이션 구축 기반&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Model Context Protocol&lt;/b&gt;: 도구 통합 표준&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Pydantic&lt;/b&gt;: 데이터 검증 및 직렬화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Platform Integration&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;LiteLLM Gateway&lt;/b&gt;: 모든 AI 요청 라우팅&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Langfuse&lt;/b&gt;: 모든 에이전트 활동 추적&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Claude 4.5 Sonnet&lt;/b&gt;: AI 모델&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Application Components&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Loan Processing Agent&lt;/b&gt;: 메인 워크플로우 오케스트레이터&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Address Validator&lt;/b&gt;: 주소 검증 MCP 서버&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Employment Checker&lt;/b&gt;: 고용 검증 MCP 서버&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Image Processor&lt;/b&gt;: 문서 분석 MCP 서버&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;h2 data-heading=&quot;John의 대출 신청&quot; data-ke-size=&quot;size26&quot;&gt;John의 대출 신청&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Loan Buddy는 다음과 같은 대출 신청서 이미지들을 처리할 예정입니다.&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;529&quot; data-origin-height=&quot;1200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfIEnU/dJMcabk1h4U/qKGSbCKanfNCOz2x2L7u5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfIEnU/dJMcabk1h4U/qKGSbCKanfNCOz2x2L7u5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfIEnU/dJMcabk1h4U/qKGSbCKanfNCOz2x2L7u5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfIEnU%2FdJMcabk1h4U%2FqKGSbCKanfNCOz2x2L7u5K%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;485&quot; height=&quot;1100&quot; data-origin-width=&quot;529&quot; data-origin-height=&quot;1200&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;서류는 John Michael Doe 씨의 것으로,&lt;br /&gt;개인정보와 고용 정보(Tech Solutions Inc, Software Engineer, 연봉 $75,000),&lt;br /&gt;주소 정보(123 Main Street, 자가 4년 거주),&lt;br /&gt;대출 조건($8,500, 36개월, 월 $275)을 가지고 있습니다.&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;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;데이터 추출&lt;/b&gt;: 이름, 생년월일, SSN 등 신청서 항목 옮겨 적기&lt;/li&gt;
&lt;li&gt;&lt;b&gt;고용 확인&lt;/b&gt;: Tech Solutions Inc에 연락해 재직 여부 확인&lt;/li&gt;
&lt;li&gt;&lt;b&gt;소득 검증&lt;/b&gt;: 연봉 $75,000 (월 $6,250) 확인&lt;/li&gt;
&lt;li&gt;&lt;b&gt;주소 검증&lt;/b&gt;: 123 Main Street가 실재하는 주거용 주소인지 확인&lt;/li&gt;
&lt;li&gt;&lt;b&gt;안정성 평가&lt;/b&gt;: 거주 기간, 주택 소유, 근속 연수 기록&lt;/li&gt;
&lt;li&gt;&lt;b&gt;비율 계산&lt;/b&gt;: 대출액 대비 소득, 월 상환액 산출&lt;/li&gt;
&lt;li&gt;&lt;b&gt;결정&lt;/b&gt;: 모든 요소를 종합해 승인 또는 거부&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 모든 과정은 통상 2~3시간을 소모합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Loan Buddy는 이 전체 프로세스를 자동화합니다.&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;b&gt;신청서 읽기&lt;/b&gt;: 비전 LLM을 활용해 이미지에서 데이터 추출&lt;/li&gt;
&lt;li&gt;&lt;b&gt;정보 검증&lt;/b&gt;: 외부 서비스를 통해 주소&amp;middot;고용 확인&lt;/li&gt;
&lt;li&gt;&lt;b&gt;비즈니스 규칙 적용&lt;/b&gt;: 대출 한도, 소득 비율, 위험 평가&lt;/li&gt;
&lt;li&gt;&lt;b&gt;결정과 기록&lt;/b&gt;: 판단 근거를 Langfuse에 감사 추적으로 보존&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 자동화 도구를 도입하여 기존 대비 처리 시간을 2~3시간에서 분 단위로 줄이고,&lt;br /&gt;동일한 기준을 도입 및 모든 결정에 대한 근거를 남길 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;처리 구조&quot; data-ke-size=&quot;size23&quot;&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;그렇다면 Loan Buddy는 이를 어떻게 처리할까요?&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;2118&quot; data-origin-height=&quot;974&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFiQGr/dJMb991LO1I/RenSsdTjkh6FrA2PXJ05vK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFiQGr/dJMb991LO1I/RenSsdTjkh6FrA2PXJ05vK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFiQGr/dJMb991LO1I/RenSsdTjkh6FrA2PXJ05vK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFiQGr%2FdJMb991LO1I%2FRenSsdTjkh6FrA2PXJ05vK%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;747&quot; height=&quot;344&quot; data-origin-width=&quot;2118&quot; data-origin-height=&quot;974&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;John의 신청서가 업로드되면 &lt;b&gt;Loan Processing Agent(LangGraph)&lt;/b&gt; 가 이를 처음 맡습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangGraph를 활용해 Workflow를 Orchestrate 하여 LiteLLM으로 넘깁니다.&lt;br /&gt;에이전트에 대한 모든 요청은 LiteLLM을 거쳐 Claude가 추론과 판단을 맡고,&lt;br /&gt;주소 검증, 고용 확인, 이미지 처리를 각 MCP 서버가 담당합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이 모든 과정을 Langfuse로 추적합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-heading=&quot;구성요소&quot; data-ke-size=&quot;size26&quot;&gt;구성요소&lt;/h2&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;h3 data-heading=&quot;LangGraph와 LangChain&quot; data-ke-size=&quot;size23&quot;&gt;LangGraph와 LangChain&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;LangGraph란?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;LLM 기반 에이전트의 워크플로우를 그래프로 정의하고 실행하는 오케스트레이션 프레임워크.&lt;br /&gt;상태 관리, 분기, 오류 처리, 도구 호출 루프를 담당합니다.&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;출처: LangChain Docs&lt;/span&gt;&lt;/p&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;AI 시스템의 프로젝트 관리자에 해당하는 역할입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;vala&quot;&gt;&lt;code&gt;# 에이전트에서 LangGraph는 워크플로우를 생성합니다
from langgraph.prebuilt import create_react_agent

# 다음을 수행할 수 있는 에이전트를 생성:
# 1. 입력에 반응
# 2. 도구 사용 (MCP 서버)
# 3. 단계 간 상태 유지
# 4. 결정 내리기
graph = create_react_agent(model, tools, debug=True)
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;LangChain이란?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;LLM 애플리케이션을 구성하는 빌딩 블록 프레임워크.&lt;br /&gt;모델 연결, 도구 추상화, 메모리 관리, 프롬프트 템플릿을 제공합니다.&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;출처: LangChain Docs&lt;/span&gt;&lt;/p&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;LangChain이 구성요소를 제공하면, LangGraph가 이를 워크플로우로 엮는 관계입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# LangChain이 플랫폼에 연결
from langchain_openai import ChatOpenAI

model = ChatOpenAI(
    model=&quot;bedrock/claude-4.5-sonnet&quot;,
    api_key=model_key,
    # 게이트웨이
    base_url=&quot;http://litellm.litellm.svc.cluster.local:4000&quot;
)
&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;여기서 base_url은 Bedrock이나 Anthropic의 엔드포인트가 아니라,&lt;br /&gt;&lt;b&gt;클러스터 내부의 LiteLLM 서비스 주소&lt;/b&gt;를 바라봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에이전트 입장에서는 OpenAI 호환 API 하나를 쓰고,&lt;br /&gt;모델 라우팅과 비용 추적은 전부 게이트웨이가 처리하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;MCP 서버 3종&quot; data-ke-size=&quot;size23&quot;&gt;MCP 서버 3종&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;MCP(Model Context Protocol)란?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;AI 모델이 외부 도구와 데이터 소스에 접근하는 방식을 표준화한 오픈 프로토콜.&lt;br /&gt;도구를 MCP 서버로 만들어두면, 어떤 에이전트든 같은 방식으로 연결해 사용할 수 있습니다.&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;출처: modelcontextprotocol.io&lt;/span&gt;&lt;/p&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;각 MCP 서버는 한 가지 작업에만 전문성을 가지며, Loan Buddy는 3개의 MCP 서버를 사용합니다.&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;1. Image Processor MCP&lt;/b&gt; (신청서 이미지에서 구조화된 데이터 추출)&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;신청서 이미지 ID &lt;b&gt;수신&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;S3 스토리지에서 이미지 &lt;b&gt;검색&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Claude의 비전 기능으로 문서 &lt;b&gt;읽기&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;구조화된 JSON 데이터 &lt;b&gt;추출&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지는 S3에 한 번 저장된 후 ID로만 참조됩니다.&lt;br /&gt;모든 LLM 호출에 이미지를 다시 실어 보내지 않기에, 토큰 비용을 절약할 수 있습니다.&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;2. Address Validator MCP&lt;/b&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;검증&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;주거용 여부 &lt;b&gt;확인&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;사기 위험 지표 &lt;b&gt;평가&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;소유 상태 &lt;b&gt;검증&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;거주 기간 기반 안정성 점수 &lt;b&gt;계산&lt;/b&gt;&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;&lt;b&gt;3. Employment Validator MCP&lt;/b&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;/li&gt;
&lt;li&gt;소득 정확성 검증 (연봉/월급 일치)&lt;/li&gt;
&lt;li&gt;고용 기간 확인&lt;/li&gt;
&lt;li&gt;고용 이력 기반 안정성 평가&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;오케스트레이터&quot; data-ke-size=&quot;size23&quot;&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;이 모든 과정을 Loan Processing Agent가 지휘하며, 전체 워크플로우는 다음과 같습니다.&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;1024&quot; data-origin-height=&quot;1536&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yPRJJ/dJMcafnpRAf/d853hriRhtNXgkfatvDjnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yPRJJ/dJMcafnpRAf/d853hriRhtNXgkfatvDjnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yPRJJ/dJMcafnpRAf/d853hriRhtNXgkfatvDjnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyPRJJ%2FdJMcafnpRAf%2Fd853hriRhtNXgkfatvDjnk%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;623&quot; height=&quot;935&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1536&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;br /&gt;&lt;b&gt;순차적으로 이루어지고&lt;/b&gt;, 모든 단계를 Langfuse로 기록합니다.&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;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&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;각 MCP 서버는 한 가지 작업만 잘 수행&lt;/li&gt;
&lt;li&gt;에이전트는 오케스트레이션만 하고 비즈니스 로직을 직접 구현하지 않음&lt;/li&gt;
&lt;li&gt;인프라(라우팅, 추적)는 플랫폼 컴포넌트가 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&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;MCP 서버는 독립적으로 확장 가능&lt;/li&gt;
&lt;li&gt;여러 에이전트가 동일한 MCP 서버를 공유 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&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;에이전트를 건드리지 않고 MCP 서버의 비즈니스 규칙 업데이트&lt;/li&gt;
&lt;li&gt;기존 코드 변경 없이 새로운 검증 도구 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&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;li&gt;효율적인 토큰 사용 (모든 호출에 이미지를 싣지 않음)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-heading=&quot;어플리케이션 배포&quot; data-ke-size=&quot;size26&quot;&gt;어플리케이션 배포&lt;/h2&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;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# 플랫폼 구성요소 확인
kubectl get pods -n litellm
kubectl get pods -n langfuse

# LiteLLM 게이트웨이 접근 확인
echo &quot;LiteLLM URL: http://$(kubectl get ingress -n litellm litellm -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')&quot;

# Langfuse 접근 확인
echo &quot;Langfuse URL: http://$(kubectl get ingress -n langfuse langfuse -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;배포에 필요한 구성&quot; data-ke-size=&quot;size23&quot;&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;Loan Buddy가 동작하려면 다음 요소들이 연결되어야 합니다.&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;b&gt;S3 Bucket&lt;/b&gt;: 업로드된 대출 문서 저장. Langfuse 배포 시 Terraform이 만든 버킷을 재사용
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;terraform output langfuse_bucket_name&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;AWS Region&lt;/b&gt;: .env 파일의 REGION 값. S3 및 AWS 서비스 호출에 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;LiteLLM API Key&lt;/b&gt;: Virtual Key(agent-key). 에이전트가 모델을 호출할 수 있게 함&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Langfuse Credentials&lt;/b&gt;: 관측성을 위한 공개/비밀 키 쌍&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Service Account + Pod Identity&lt;/b&gt;: Langfuse 서비스 계정을 workshop 네임스페이스로 복사
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Pod Identity Association 생성&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;p data-ke-size=&quot;size16&quot;&gt;Pod Identity Association을 사용하게 된다면,&lt;br /&gt;Pod는 &lt;b&gt;하드코딩된 자격 증명 없이&lt;/b&gt; IAM 역할을 통해 S3에 접근합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;# 서비스 계정 복사
kubectl get serviceaccount langfuse -n langfuse -o yaml | \
  sed 's/namespace: langfuse/namespace: workshop/' | \
  kubectl apply -f -

# Pod Identity Association 생성
aws eks create-pod-identity-association \
  --cluster-name genai-on-eks \
  --namespace workshop \
  --service-account langfuse \
  --role-arn &amp;lt;IAM_ROLE_ARN&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;자동 배포&quot; data-ke-size=&quot;size23&quot;&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;이 모든 절차를 배포 스크립트 하나로 자동화했다면, 딸깍으로 끝납니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;# credit validation 디렉토리로 이동
cd /workshop/workshops/eks-genai-workshop/static/code/module3/credit-validation

# 배포 스크립트 실행
chmod +x deploy-workshop-app.sh
./deploy-workshop-app.sh
&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;p data-ke-size=&quot;size16&quot;&gt;Terraform 출력에서 S3 버킷을 조회,&lt;br /&gt;LiteLLM/Langfuse 키를 매니페스트에 주입,&lt;br /&gt;네임스페이스와 서비스 계정, Pod Identity를 만들어,&lt;br /&gt;어플리케이션을 배포합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# 배포 예시
Loan Buddy Workshop Deployment

Step 1: Checking prerequisites...            ✅
Step 2: Retrieving S3 bucket name...         ✅ genai-on-eks-bucket-langfuse-xxxxx
Step 3: Getting AWS region...                ✅ us-west-2
Step 4: Getting LiteLLM API key...           ✅ sk-xxxxx...
Step 5: Getting Langfuse credentials...      ✅ lf_pk_xxxxx... / lf_sk_xxxxx...
Step 6: Creating workshop namespace...       ✅
Step 7: Setting up service account...        ✅ (+ Pod Identity Association)
Step 8: Configuring deployment file...       ✅
Step 9: Deploying Loan Buddy application...  ✅
Step 10: Waiting for deployments...          ✅

NAME                                     READY   STATUS    RESTARTS   AGE
loan-buddy-agent-xxx                     1/1     Running   0          1m
mcp-address-validator-xxx                1/1     Running   0          1m
mcp-employment-validator-xxx             1/1     Running   0          1m
mcp-image-processor-xxx                  1/1     Running   0          1m
&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;에이전트 1개와 MCP 서버 3개, 총 4개의 Deployment가 올라갑니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-heading=&quot;동작 확인&quot; data-ke-size=&quot;size26&quot;&gt;동작 확인&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배포한 어플리케이션을 이용해서 John의 신청서를 실제로 처리해보겠습니다.&lt;br /&gt;example1.png 를 사용해 테스트를 진행해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;# 새 터미널에서 에이전트 로그 관찰
kubectl logs -f deployment/loan-buddy-agent -n workshop

# Loan Buddy 배포
kubectl port-forward service/loan-buddy-agent 8888:8080 -n workshop &amp;amp;

# 테스트 데이터 디렉토리로 이동
cd /workshop/workshops/eks-genai-workshop/static/code/module3/credit-validation/

# John Michael Doe의 대출 신청서 처리
curl -X POST -F &quot;image_file=@./example1.png&quot; \
  http://localhost:8888/api/process_credit_application_with_upload | jq
&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;  Starting credit application processing...
  Processing uploaded loan application image...
✅ Image stored in S3 with ID: a7b9c2d4e5f6...
  Loading MCP tools...
  Processing with agent...

[Agent]: I'll help you process this credit application.

[Image Processor MCP]: Extracting data from loan application...
Found: John Michael Doe, DOB: 03/15/1985, SSN: ***-**-7890
Income: $75,000, Employer: Tech Solutions Inc
Address: 123 Main Street, Anytown, CA 90210

[Address Validator MCP]: Checking 123 Main Street, Anytown, CA 90210
✅ Valid residential address - Owner occupied - 4 years
✅ Risk score: 15 (Low risk)

[Employment Validator MCP]: Verifying Tech Solutions Inc
✅ Employment confirmed - Software Engineer, $75,000, 3.5 years
✅ Stability score: 85 (High stability)

[Agent]: Calculating loan metrics...
- Loan amount: $8,500 / Monthly payment: $275
- Debt-to-income ratio: 4.4% (Excellent)

FINAL DECISION: ✅ APPROVED
&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;br /&gt;이미지 추출 &amp;rarr; 주소 검증 &amp;rarr; 고용 확인 &amp;rarr; 비율 계산 &amp;rarr; 승인 결정이 차례로 실행됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 사람이 했다면 2~3시간 걸릴 검토가, 업로드 한 번으로 몇 분 안에 끝납니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;Langfuse에서 에이전트 추적&quot; data-ke-size=&quot;size23&quot;&gt;Langfuse에서 에이전트 추적&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;이 실행은 Langfuse에도 그대로 기록되는데,&lt;br /&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;4408&quot; data-origin-height=&quot;1520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mXbYF/dJMcabSKuOH/rWuJkEFDLJwi7b02iWKBkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mXbYF/dJMcabSKuOH/rWuJkEFDLJwi7b02iWKBkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mXbYF/dJMcabSKuOH/rWuJkEFDLJwi7b02iWKBkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmXbYF%2FdJMcabSKuOH%2FrWuJkEFDLJwi7b02iWKBkk%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;4408&quot; height=&quot;1520&quot; data-origin-width=&quot;4408&quot; data-origin-height=&quot;1520&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;단일 span이 아니라, &lt;b&gt;에이전트 실행 전체가 중첩된 트리&lt;/b&gt;형태로 기록됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최상위 트레이스 하위에 agent &amp;rarr; call_model &amp;rarr; 도구 호출이 계층으로 쌓이고&lt;/li&gt;
&lt;li&gt;agent와 tools span이 번갈아 반복되며 &lt;b&gt;ReAct 루프&lt;/b&gt;(추론 &amp;rarr; 행동 &amp;rarr; 관찰)가 시각화돼&lt;/li&gt;
&lt;li&gt;각 단계의 지연시간과 LLM 호출별 토큰 사용량을 개별적으로 확인할 수 있습니다&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;b&gt;애플리케이션 레이어(Langfuse SDK) 추적&lt;/b&gt;이 바로 이것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게이트웨이 레이어가 &quot;LLM을 몇 번, 얼마에 불렀는가&quot;를 보여준다면,&lt;br /&gt;SDK 레이어는 &quot;에이전트가 &lt;b&gt;왜&lt;/b&gt; 호출을 했고, 어떤 도구를 거쳐 도달했는가&quot;를 보여줍니다.&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;br /&gt;이 추적 기록이 규정 준수에 대한 중요한 감사 자료가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;마무리&quot; data-ke-size=&quot;size23&quot;&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;Loan Buddy를 끝으로, 전체 워크샵을 진행할 수 있었습니다.&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;b&gt;Phase 1 : 모델과 상호작용&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;EKS Auto Mode 클러스터 위에 Open WebUI 배포&lt;/li&gt;
&lt;li&gt;AWS Neuron 칩에서 vLLM으로 Qwen 3 8B, DeepSeek R1 서빙&lt;/li&gt;
&lt;li&gt;Bedrock을 통한 Claude 4.5 Sonnet 통합, 자체 호스팅 vs 관리형 비교&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Phase 2 : 플랫폼 컴포넌트&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LiteLLM 통합 게이트웨이 구성과 무중단 모델 추가&lt;/li&gt;
&lt;li&gt;Langfuse 관측성 스택과 게이트웨이/SDK 이중 추적&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Phase 3 : 어플리케이션 구축&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangGraph 에이전트와 MCP 서버 3종으로 Loan Buddy 구현&lt;/li&gt;
&lt;li&gt;Pod Identity 기반의 자격 증명 없는 S3 접근&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;이번 모듈을 만들면서 가장 크게 느낀 것은,&lt;br /&gt;&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;br /&gt;생각보다 코드가 그렇게 무겁지 않다는 것을 배울 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;문서 처리, 고객 서비스 자동화, 모니터링 등 Loan Buddy와 같은 패턴을 적용할 수 있는 곳은 많습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;참고로, 워크샵과 동일한 플랫폼을 직접 배포해볼 수 있는&lt;br /&gt;&lt;a href=&quot;https://github.com/aws-samples/sample-genai-on-eks-starter-kit&quot; data-tooltip-position=&quot;top&quot;&gt;AWS GenAI on EKS Starter Kit&lt;/a&gt;이 GitHub에 오픈소스로 공개되어 있습니다.&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;llm-d&lt;/b&gt;라는 K8s 기반 분리형 LLM 서빙 프레임워크도 포함되어 있습니다.&lt;br /&gt;제가 진행한 과정을 따라 진행해보고자 한다면, 깃허브에서 참고하시면 좋을 것 같습니다..&lt;/p&gt;</description>
      <category>DevOps</category>
      <author>frontheadlock</author>
      <guid isPermaLink="true">https://frontheadlock.tistory.com/21</guid>
      <comments>https://frontheadlock.tistory.com/21#entry21comment</comments>
      <pubDate>Wed, 12 Aug 2026 22:13:09 +0900</pubDate>
    </item>
    <item>
      <title>Gen AI on K8s/EKS 인퍼런스 최적화 (3)</title>
      <link>https://frontheadlock.tistory.com/20</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LiteLLM 게이트웨이를 구성하며,&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;이번 글에서는 게이트웨이를 지나간 모든 대화를 추적하는 관측성 플랫폼에 대해 살펴보겠습니다.&lt;/p&gt;
&lt;h2 data-heading=&quot;Langfuse&quot; data-ke-size=&quot;size26&quot;&gt;Langfuse&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Langfuse란?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;Langfuse는 다음을 제공하는 오픈소스 LLM 관측성 플랫폼&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;포괄적인 추적: 전체 컨텍스트와 함께 캡처되는 모든 LLM 상호작용&lt;/li&gt;
&lt;li&gt;비용 추적: 모든 모델에 걸친 토큰 사용량 및 비용&lt;/li&gt;
&lt;li&gt;성능 분석: 지연시간, 처리량, 품질 지표&lt;/li&gt;
&lt;li&gt;디버깅 도구: 상세한 요청/응답 검사&lt;/li&gt;
&lt;li&gt;다중 데이터베이스 아키텍처: 확장을 위한 PostgreSQL + ClickHouse + Redis&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #9d9d9d; text-align: left;&quot;&gt;출처: AWS Workshop&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-heading=&quot;관측성 스택 탐색&quot; data-ke-size=&quot;size23&quot;&gt;관측성 스택 탐색&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 Langfuse가 어떤 컴포넌트로 구성되어 있는지 확인합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# 완전한 관측성 스택 확인
kubectl get all -n langfuse
&lt;/code&gt;&lt;/pre&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;b&gt;langfuse-web&lt;/b&gt;: 대시보드 UI와 API를 담당하는 메인 어플리케이션&lt;/li&gt;
&lt;li&gt;&lt;b&gt;langfuse-worker&lt;/b&gt;: 수집된 이벤트를 비동기로 처리해 ClickHouse에 적재&lt;/li&gt;
&lt;li&gt;&lt;b&gt;langfuse-postgresql-0&lt;/b&gt;: 추적 메타데이터, 프로젝트, 사용자 정보 저장&lt;/li&gt;
&lt;li&gt;&lt;b&gt;langfuse-clickhouse-shard0-0&lt;/b&gt;: 대량의 트레이스 분석을 위한 컬럼형 데이터베이스&lt;/li&gt;
&lt;li&gt;&lt;b&gt;langfuse-zookeeper-0&lt;/b&gt;: ClickHouse 복제 코디네이터&lt;/li&gt;
&lt;li&gt;&lt;b&gt;langfuse-redis-primary-0&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;요청을 받아 대시보드 역할을 하는 역할(web)과,&lt;br /&gt;트레이스를 소화해 분석 DB에 쌓는 역할(worker)이 나눠져 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;구성과 배포&quot; data-ke-size=&quot;size23&quot;&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;실제 구성은 IDE에서 확인할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;# Langfuse Helm values 확인
cat /workshop/components/o11y/langfuse/values.template.yaml

# 스택 구성 확인
grep -A 5 &quot;postgresql:\|clickhouse:\|redis:&quot; /workshop/components/o11y/langfuse/values.template.yaml
&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;a href=&quot;https://langfuse.com/self-hosting/deployment/kubernetes-helm&quot; data-tooltip-position=&quot;top&quot;&gt;공식 Langfuse Helm Chart&lt;/a&gt;를 사용합니다.&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;# Langfuse Helm 레포지토리 추가
helm repo add langfuse https://langfuse.github.io/langfuse-k8s
helm repo update

# 커스텀 values로 Langfuse 배포
helm upgrade --install langfuse langfuse/langfuse \
  --namespace langfuse \
  --create-namespace \
  -f values.rendered.yaml

# 배포 상태 확인
kubectl rollout status deployment/langfuse-web -n langfuse
&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;템플릿 렌더링&lt;/b&gt;: values.template.yaml &amp;rarr; values.rendered.yaml&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Helm 설치&lt;/b&gt;: 렌더링된 values로 차트 배포&lt;/li&gt;
&lt;li&gt;&lt;b&gt;데이터베이스 초기화&lt;/b&gt;: PostgreSQL, ClickHouse, Redis 설정&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프로젝트 설정&lt;/b&gt;: 조직 및 프로젝트 자동 생성, 워크샵 자격 증명으로 사용자 계정 생성&lt;/li&gt;
&lt;li&gt;&lt;b&gt;통합 준비&lt;/b&gt;: LiteLLM 연결을 위한 API 키 구성&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4~5번을 거쳐, 접속하면 LiteLLM의 트레이스가 쌓이는 상태로 시작할 수 있습니다.&lt;/p&gt;
&lt;h2 data-heading=&quot;Langfuse 사용해보기&quot; data-ke-size=&quot;size26&quot;&gt;Langfuse 사용해보기&lt;/h2&gt;
&lt;h3 data-heading=&quot;첫 접속&quot; data-ke-size=&quot;size23&quot;&gt;첫 접속&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;echo &quot;Langfuse URL: http://$(kubectl get ingress -n langfuse langfuse -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')&quot;
&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;로그인하면 Organizations 화면이 먼저 나타납니다.&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;3838&quot; data-origin-height=&quot;1984&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l2mZ9/dJMcaazzIHl/fURZopwSqk1ize8I7Tknt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l2mZ9/dJMcaazzIHl/fURZopwSqk1ize8I7Tknt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l2mZ9/dJMcaazzIHl/fURZopwSqk1ize8I7Tknt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl2mZ9%2FdJMcaazzIHl%2FfURZopwSqk1ize8I7Tknt1%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;713&quot; height=&quot;369&quot; data-origin-width=&quot;3838&quot; data-origin-height=&quot;1984&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;b&gt;Provisioned Org&lt;/b&gt;와 &lt;b&gt;Provisioned Project&lt;/b&gt;가 이미 만들어져 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Go to project&lt;/b&gt;를 눌러 프로젝트로 들어갑니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;홈 대시보드&quot; data-ke-size=&quot;size23&quot;&gt;홈 대시보드&lt;/h3&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;3838&quot; data-origin-height=&quot;1980&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPYFck/dJMcacxmdvK/mIsGws7M9kpIRgsOEFeW5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPYFck/dJMcacxmdvK/mIsGws7M9kpIRgsOEFeW5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPYFck/dJMcacxmdvK/mIsGws7M9kpIRgsOEFeW5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPYFck%2FdJMcacxmdvK%2FmIsGws7M9kpIRgsOEFeW5K%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;643&quot; height=&quot;332&quot; data-origin-width=&quot;3838&quot; data-origin-height=&quot;1980&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;Past 1 day 기준으로 다음이 집계되어 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Traces&lt;/b&gt;: 4건 (중간에 DB 초기화 해서 일부 날아갔습니다..)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Model costs&lt;/b&gt;: $0.002727 &amp;mdash; bedrock/openai.gpt-oss-20b-1:0, 20.17K 토큰&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Scores&lt;/b&gt;: 0건 (아직 평가를 붙이지 않았으므로)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지난 글에서 LiteLLM Usage 탭으로 봤던 것과 같은 데이터가,&lt;br /&gt;이번에는 모델별 비용과 시간대별 차트로 훨씬 자세하게 펼쳐집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;트레이스 목록&quot; data-ke-size=&quot;size23&quot;&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;&lt;b&gt;Tracing&lt;/b&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;3830&quot; data-origin-height=&quot;632&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mZnvv/dJMcahrXkpH/kymkxf2Rl7rKgZZsB9kaE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mZnvv/dJMcahrXkpH/kymkxf2Rl7rKgZZsB9kaE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mZnvv/dJMcahrXkpH/kymkxf2Rl7rKgZZsB9kaE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmZnvv%2FdJMcahrXkpH%2Fkymkxf2Rl7rKgZZsB9kaE1%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;3830&quot; height=&quot;632&quot; data-origin-width=&quot;3830&quot; data-origin-height=&quot;632&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;각 행에 타임스탬프, 입력/출력 미리보기, Latency, 토큰 수, 비용이 정리되어 있습니다.&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;트레이스 4건 중 실제로 질문을 한 것은, &quot;Langfuse에 대해 설명해줘&quot;, &quot;트레이스 분석하게 도와줘&quot; &lt;b&gt;2건&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나머지 2건은 Suggest 3-5 relevant follow-up questions...로 시작하는,&lt;br /&gt;&lt;b&gt;Open WebUI가 후속 질문 추천을 위해 자동으로 보내는 요청&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;채팅 한 번에 실제로는 LLM 호출이 두 번 나가고 있었던 것입니다.&lt;br /&gt;관측성을 켜보면, UI가 뒤에서 조용히 보내던 요청까지 확인할 수 있던것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;개별 트레이스 검사&quot; data-ke-size=&quot;size23&quot;&gt;개별 트레이스 검사&lt;/h3&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1918&quot; data-origin-height=&quot;1982&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bb8b7e/dJMb99UT0Hz/bI6nRzg6uMUox8zYc090YK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bb8b7e/dJMb99UT0Hz/bI6nRzg6uMUox8zYc090YK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bb8b7e/dJMb99UT0Hz/bI6nRzg6uMUox8zYc090YK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbb8b7e%2FdJMb99UT0Hz%2FbI6nRzg6uMUox8zYc090YK%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;666&quot; height=&quot;688&quot; data-origin-width=&quot;1918&quot; data-origin-height=&quot;1982&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Latency&lt;/b&gt;: 5.29초 (Time to first token 5.29초)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Total Cost&lt;/b&gt;: $0.0005&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Token Usage&lt;/b&gt;: 5,575 프롬프트 &amp;rarr; 367 완성 (총 5,942)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모델&lt;/b&gt;: bedrock/openai.gpt-oss-20b-1:0&lt;/li&gt;
&lt;li&gt;&lt;b&gt;파라미터&lt;/b&gt;: stream: false, max_retries: 0, aws_region_name: us-west-2&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Preview 탭에는 요청 전문이 그대로 담겨 있는데, Chat History에 낯익은 대화가 보입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지난 글에서 gpt-oss-20b를 테스트하며 물었던 &lt;b&gt;&quot;오늘 저녁 메뉴 추천 해줘&quot;&lt;/b&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;프롬프트가 실제로 사용한 5,575 토큰에 대한 근거도 확인해볼 수도 있습니다.&lt;br /&gt;후속 질문을 만들기 위한&amp;nbsp;&lt;b&gt;직전 대화 전체가 컨텍스트로 다시 들어가기 때문&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;응답 몇 줄을 추천받자고 대화 전체를 다시 지불하는 셈이니,&lt;br /&gt;이런 부가 기능의 비용도 관측성이 있어야 보입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;기본 제공 대시보드&quot; data-ke-size=&quot;size23&quot;&gt;기본 제공 대시보드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Dashboards&lt;/b&gt; 메뉴에는 Langfuse가 관리하는 대시보드 4종이 기본 제공됩니다.&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;2048&quot; data-origin-height=&quot;398&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eoeOiZ/dJMcah6zE7z/e5yKA9DakZWMSdExbw4MJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eoeOiZ/dJMcah6zE7z/e5yKA9DakZWMSdExbw4MJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eoeOiZ/dJMcah6zE7z/e5yKA9DakZWMSdExbw4MJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeoeOiZ%2FdJMcah6zE7z%2Fe5yKA9DakZWMSdExbw4MJk%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;752&quot; height=&quot;146&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;398&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Langfuse Home&lt;/b&gt;: 프로젝트 홈에 표시되는 전체 개요&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Langfuse Cost Dashboard&lt;/b&gt;: LLM 비용 리뷰&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Langfuse Latency Dashboard&lt;/b&gt;: 트레이스/생성 단위 지연시간 모니터링&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Langfuse Usage Management&lt;/b&gt;: 리소스 할당을 위한 사용량 추적&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 중 Cost Dashboard를 열어보겠습니다.&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;3542&quot; data-origin-height=&quot;1910&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lLl0u/dJMcah6zE72/dAKkP4hwKuiK0cg1UVJZZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lLl0u/dJMcah6zE72/dAKkP4hwKuiK0cg1UVJZZ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lLl0u/dJMcah6zE72/dAKkP4hwKuiK0cg1UVJZZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlLl0u%2FdJMcah6zE72%2FdAKkP4hwKuiK0cg1UVJZZ0%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;743&quot; height=&quot;401&quot; data-origin-width=&quot;3542&quot; data-origin-height=&quot;1910&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Total Count Traces 7 / Observations 10&lt;/b&gt;: 전체 기간 누적 집계&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Cost by Model Name&lt;/b&gt;: bedrock/openai.gpt-oss-20b-1:0가 비용 대부분을 차지&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Cost by Environment&lt;/b&gt;: default 환경에 전액($0.002727)이 몰린 도넛 차트&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Top 20 Users / Use Cases by Cost&lt;/b&gt;: 사용자와 유스케이스 단위의 비용 분석 틀&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위젯을 직접 추가해 커스텀 대시보드를 만들 수도 있지만,&lt;br /&gt;기본 제공 대시보드만으로도 비용, 지연시간, 사용량 관점이 이미 갖춰져 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;고급 기능: LLM-as-a-Judge&quot; data-ke-size=&quot;size23&quot;&gt;고급 기능: LLM-as-a-Judge&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;Langfuse는 AI 모델을 심사자로 사용해 응답 품질을 자동 평가하는 기능도 지원합니다.&lt;/p&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;/li&gt;
&lt;li&gt;&lt;b&gt;일관성 평가&lt;/b&gt;: 서로 다른 모델의 응답을 객관적으로 비교&lt;/li&gt;
&lt;li&gt;&lt;b&gt;품질 벤치마킹&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;모델 비교, 프롬프트 최적화, 품질 저하 감지, A/B 테스트에 활용되며,&lt;br /&gt;모듈 4에서 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세한 내용은 &lt;a href=&quot;https://langfuse.com/docs/evaluation/evaluation-methods/llm-as-a-judge&quot; data-tooltip-position=&quot;top&quot;&gt;Langfuse LLM-as-a-Judge 문서&lt;/a&gt;를 참고하세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-heading=&quot;Langfuse 동작 원리&quot; data-ke-size=&quot;size26&quot;&gt;Langfuse 동작 원리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 이 트레이스들은 어떻게 Langfuse까지 흘러온 걸까요?&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;2028&quot; data-origin-height=&quot;1042&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SoHMx/dJMcafOs64q/0HJD9LxwG9rH8cv1CkktY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SoHMx/dJMcafOs64q/0HJD9LxwG9rH8cv1CkktY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SoHMx/dJMcafOs64q/0HJD9LxwG9rH8cv1CkktY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSoHMx%2FdJMcafOs64q%2F0HJD9LxwG9rH8cv1CkktY1%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;681&quot; height=&quot;350&quot; data-origin-width=&quot;2028&quot; data-origin-height=&quot;1042&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;b&gt;LiteLLM은 모델 호출과 별개로 트레이스를 전송&lt;/b&gt;합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;사용자가 메시지를 보내면 Open WebUI가 LiteLLM에 API 요청&lt;/li&gt;
&lt;li&gt;LiteLLM이 모델로 라우팅하면서 동시에 Langfuse에 &lt;b&gt;Start trace&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;모델 응답이 돌아오면 &lt;b&gt;Complete trace with metrics&lt;/b&gt; 전송&lt;/li&gt;
&lt;li&gt;Langfuse는 프롬프트, 응답, 토큰, 비용, 지연시간을 저장&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Open WebUI는 Langfuse의 존재를 전혀 모릅니다.&lt;br /&gt;게이트웨이가 추적을 대신 해주기에, 어플리케이션 코드 변경이 없는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Langfuse로 트레이스를 보내는 경로는 이 방법 하나만이 아닙니다.&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;통합 작동 방식&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;LiteLLM Callbacks&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;게이트웨이를 통과하는 모든 LLM 요청을 자동 추적. 어플리케이션 코드 변경 불필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Langfuse SDK&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;어플리케이션 코드에 CallbackHandler를 직접 삽입해, 에이전트 워크플로우와 도구 호출 수준까지 추적&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;OpenTelemetry&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;표준 OTEL 프로토콜로 Langfuse의 OTEL 호환 엔드포인트에 전송. 다국어 환경이나 기존 OTEL 계측에 유용&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;/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;게이트웨이 레이어&lt;/b&gt; (LiteLLM Callbacks): 모든 LLM 호출의 토큰, 비용, 지연시간 캡처&lt;/li&gt;
&lt;li&gt;&lt;b&gt;어플리케이션 레이어&lt;/b&gt; (Langfuse SDK): 에이전트 워크플로우, 도구 호출, 의사결정 체인 캡처&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;낮은 수준의 모델 성능과 높은 수준의 어플리케이션 동작을,&lt;br /&gt;하나의 Langfuse 대시보드에서 모두 볼 수 있게 되는 구조입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;마무리&quot; data-ke-size=&quot;size23&quot;&gt;마무리&lt;/h3&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;br /&gt;UI가 뒤에서 보내는 자동 요청까지 포함해 모든 호출을 기록합니다.&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;관측성 모델을 통해 채팅 한 번이 LLM 호출 두 번이 되고,&lt;br /&gt;그 부가 호출이 대화 전체를 컨텍스트로 다시 소비한다는 사실을 알 수도 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 기능을 추가할 때마다 토큰 비용이 어디서 새는지 알 수도 있었습니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 LiteLLM(게이트웨이)과 Langfuse(관측성)를 모두 갖추며,&lt;br /&gt;EKS 위의 Agentic AI 플랫폼 기반을 완성했습니다.&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;다음 모듈에서는 이 기반 위에서 LangChain과 LangGraph를 사용해,&lt;br /&gt;도구 호출과 메모리를 갖춘 실제 에이전트 어플리케이션을 구축해보겠습니다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <author>frontheadlock</author>
      <guid isPermaLink="true">https://frontheadlock.tistory.com/20</guid>
      <comments>https://frontheadlock.tistory.com/20#entry20comment</comments>
      <pubDate>Sun, 9 Aug 2026 21:58:56 +0900</pubDate>
    </item>
    <item>
      <title>GenAI on K8s/EKS 인퍼런스 최적화 (2)</title>
      <link>https://frontheadlock.tistory.com/19</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;지난 글에서는 EKS 위에 배포된 개별 모델들과 직접 상호작용해보았습니다.&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;이번에는 LiteLLM을 통합 API 게이트웨이로,&lt;br /&gt;Langfuse를 관측성 플랫폼으로 연결해,&lt;br /&gt;Agentic AI 어플리케이션을 지탱하는 인프라를 완성합니다.&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;오늘은 LiteLLM을 중점적으로 다루고, Langfuse는 다음 글에서 이어가겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-heading=&quot;Phase 2 아키텍처&quot; data-ke-size=&quot;size26&quot;&gt;아키텍처&lt;/h2&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;2078&quot; data-origin-height=&quot;1100&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDbB67/dJMcagfnysF/htlZf5NYERHhzJEbtKwY5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDbB67/dJMcagfnysF/htlZf5NYERHhzJEbtKwY5k/img.png&quot; data-alt=&quot;아키텍처&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDbB67/dJMcagfnysF/htlZf5NYERHhzJEbtKwY5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDbB67%2FdJMcagfnysF%2FhtlZf5NYERHhzJEbtKwY5k%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;2078&quot; height=&quot;1100&quot; data-origin-width=&quot;2078&quot; data-origin-height=&quot;1100&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 data-ke-size=&quot;size16&quot;&gt;Open WebUI의 모든 요청은 API Gateway Layer의 LiteLLM을 지나,&lt;br /&gt;vLLM 또는 AWS Bedrock으로 라우팅됩니다.&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;이 과정에서 발생하는 모든 Trace가 Langfuse로 흘러가고,&lt;br /&gt;Langfuse는 이를 PostgreSQL, ClickHouse, Redis에 저장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 아키텍처는 Helm 차트를 사용하여 &lt;b&gt;실제 배포 패턴&lt;/b&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;b&gt;동적 구성&lt;/b&gt;: Helm 템플릿이 유연한 배포를 가능하게 하는 방법&lt;/li&gt;
&lt;li&gt;&lt;b&gt;자동 통합&lt;/b&gt;: 컴포넌트가 서로를 발견하고 연결하는 방법&lt;/li&gt;
&lt;li&gt;&lt;b&gt;확장 가능한 패턴&lt;/b&gt;: 리소스 관리, Ingress 및 보안 이해&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-heading=&quot;LiteLLM&quot; data-ke-size=&quot;size26&quot;&gt;LiteLLM&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;LiteLLM이란?&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;LiteLLM은 다음을 제공하는 오픈소스 프록시&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;통합 API: 모든 모델을 위한 단일 OpenAI 호환 엔드포인트&lt;/li&gt;
&lt;li&gt;스마트 라우팅: 적절한 백엔드로 요청을 자동으로 라우팅&lt;/li&gt;
&lt;li&gt;영구 스토리지: 구성을 위한 PostgreSQL, 캐싱을 위한 Redis&lt;/li&gt;
&lt;li&gt;로드 밸런싱: 여러 모델 레플리카 간에 요청 분산&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;출처: AWS Workshop&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 data-heading=&quot;LiteLLM 스택 구성&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-heading=&quot;LiteLLM 스택 구성&quot; data-ke-size=&quot;size23&quot;&gt;LiteLLM 스택 구성&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;LiteLLM은 단일 Pod가 아니라, 세 개의 컴포넌트로 구성된 스택입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;LiteLLM Pod&lt;/b&gt;: 모든 모델 요청을 라우팅하는 API 게이트웨이 본체&lt;/li&gt;
&lt;li&gt;&lt;b&gt;PostgreSQL&lt;/b&gt;: 모델 구성, 사용 데이터, Virtual Key 등 저장&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Redis&lt;/b&gt;: 응답 캐싱을 통한 응답 시간 개선&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지난 글에서 kubectl get svc로 확인했던 litellm 네임스페이스의&lt;br /&gt;litellm, litellm-postgresql, litellm-redis 서비스가 바로 이 구성입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;모델 구성 확인&quot; data-ke-size=&quot;size23&quot;&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;먼저 실행 중인 vLLM 모델을 확인하고,&lt;br /&gt;LiteLLM이 이 모델들을 어떻게 바라보는지 구성 파일에서 살펴봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;vala&quot;&gt;&lt;code&gt;# 실행 중인 vLLM 모델 확인
kubectl get pods -n vllm -l app

# LiteLLM의 모델 구성 확인
grep -A 16 &quot;model_list:&quot; /workshop/components/ai-gateway/litellm/values.rendered.yaml
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;# LiteLLM
model_list:
  # Bedrock 모델 (AWS 구성에서)
  - model_name: bedrock/claude-4.5-sonnet
    litellm_params:
      model: bedrock/global.anthropic.claude-sonnet-4-5-20250929-v1:0
      aws_region_name: us-west-2

  # vLLM 모델 (실행 중인 Pod에서 자동 발견)
  - model_name: vllm/qwen3-8b-neuron
    litellm_params:
      model: openai/qwen3-8b-neuron
      api_key: fake-key
      api_base: http://qwen3-8b-neuron.vllm:8000/v1
  - model_name: vllm/deepseek-r1-qwen3-8b-neuron
    litellm_params:
      model: openai/deepseek-r1-qwen3-8b-neuron
      api_key: fake-key
      api_base: http://deepseek-r1-qwen3-8b-neuron.vllm:8000/v1
&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;api_base&lt;/b&gt;: vLLM Service의 클러스터 내부 DNS를 그대로 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;api_key: fake-key&lt;/b&gt;: vLLM 엔드포인트에는 별도 인증이 없어 Mock 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;model: openai/...&lt;/b&gt;: vLLM이 OpenAI 호환 API를 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;모델 자동 발견&quot; data-ke-size=&quot;size23&quot;&gt;모델 자동 발견&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 구성 파일은 직접 작성하지 않고,&lt;br /&gt;배포 시점에 실행 중인 모델을 스캔해 자동으로 렌더링됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;# 통합 발견 로직 확인
grep -A 15 &quot;integration.*llm-model&quot; /workshop/components/ai-gateway/litellm/index.mjs
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;gams&quot;&gt;&lt;code&gt;// LiteLLM의 모델 발견 프로세스
for (const model of value.models) {
  if (model.deploy) {
    // 모델 Pod가 실제로 실행 중인지 확인
    const result = await kubectl get pod -n ${namespace} -l app=${model.name}
    if (result.stdout.includes(model.name)) {
      // 모델을 찾아 통합에 추가
      integration[&quot;llm-model&quot;][namespace][model.name] = true;
    }
  }
}
&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;스캔&lt;/b&gt;: 실행 중인 모델 Pod를 Kubernetes에서 탐색&lt;/li&gt;
&lt;li&gt;&lt;b&gt;검증&lt;/b&gt;: 각 모델이 정상적으로 사용 가능한지 확인&lt;/li&gt;
&lt;li&gt;&lt;b&gt;빌드&lt;/b&gt;: 발견된 모델로 통합 객체 생성&lt;/li&gt;
&lt;li&gt;&lt;b&gt;렌더링&lt;/b&gt;: 사용 가능한 모델만으로 Helm 템플릿 렌더링&lt;/li&gt;
&lt;li&gt;&lt;b&gt;배포&lt;/b&gt;: 해당 모델 구성으로 LiteLLM 배포&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 덕분에 LiteLLM은 실제로 실행 중인 모델만 바라보도록 구성되어,&lt;br /&gt;고아 모델이 model_list에 남아 라우팅을 혼잡스러게 하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;LiteLLM 배포&quot; data-ke-size=&quot;size23&quot;&gt;LiteLLM 배포&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;배포에는 커스텀 values 템플릿과 &lt;a href=&quot;https://github.com/BerriAI/litellm/tree/main/deploy/charts/litellm-helm&quot; data-tooltip-position=&quot;top&quot;&gt;공식 LiteLLM Helm Chart&lt;/a&gt;를 사용합니다.&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;# 렌더링된 values로 공식 차트 배포
helm upgrade --install litellm oci://ghcr.io/berriai/litellm-helm \
  --namespace litellm \
  --create-namespace \
  -f /workshop/components/ai-gateway/litellm/values.rendered.yaml
&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;동작 시퀀스&quot; data-ke-size=&quot;size23&quot;&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;배포된 LiteLLM의 요청 처리 흐름은 다음과 같습니다.&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;1982&quot; data-origin-height=&quot;1154&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uaR3F/dJMb99UQL5r/u5cazTCyHVt0xLV1ad3wv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uaR3F/dJMb99UQL5r/u5cazTCyHVt0xLV1ad3wv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uaR3F/dJMb99UQL5r/u5cazTCyHVt0xLV1ad3wv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuaR3F%2FdJMb99UQL5r%2Fu5cazTCyHVt0xLV1ad3wv0%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;1982&quot; height=&quot;1154&quot; data-origin-width=&quot;1982&quot; data-origin-height=&quot;1154&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;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;사용자가 모델을 선택하고 메시지를 전송&lt;/li&gt;
&lt;li&gt;Open WebUI가 LiteLLM에 POST /v1/chat/completions 호출&lt;/li&gt;
&lt;li&gt;선택된 모델에 따라 vLLM 엔드포인트 또는 Bedrock API로 분기&lt;/li&gt;
&lt;li&gt;어느 쪽이든 &lt;b&gt;동일한 응답 형식(Unified response format)&lt;/b&gt; 으로 반환&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백엔드가 무엇이든 응답 형식이 같기에,&lt;br /&gt;클라이언트는 모델이 어디서 서빙되는지 전혀 신경 쓸 필요가 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-heading=&quot;LiteLLM 웹 인터페이스 탐색&quot; data-ke-size=&quot;size26&quot;&gt;LiteLLM 웹 인터페이스 탐색&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 LiteLLM 관리 인터페이스에서 모델과 지표를 확인하고, API를 테스트해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;1. LiteLLM 접속&quot; data-ke-size=&quot;size23&quot;&gt;1. LiteLLM 접속&lt;/h3&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;3840&quot; data-origin-height=&quot;2160&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CXE0m/dJMcadiJn2S/dGBBfsZIwGKcjQAD1lFoPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CXE0m/dJMcadiJn2S/dGBBfsZIwGKcjQAD1lFoPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CXE0m/dJMcadiJn2S/dGBBfsZIwGKcjQAD1lFoPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCXE0m%2FdJMcadiJn2S%2FdGBBfsZIwGKcjQAD1lFoPK%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;3840&quot; height=&quot;2160&quot; data-origin-width=&quot;3840&quot; data-origin-height=&quot;2160&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;pre class=&quot;bash&quot;&gt;&lt;code&gt;echo &quot;LiteLLM URL: http://$(kubectl get ingress -n litellm litellm -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')&quot;
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ALB 주소로 접속하면 먼저 Swagger 기반의 API 문서가 나타납니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Proxy Server to call 100+ LLMs in the OpenAI format&quot;라는 소개 문구처럼,&lt;br /&gt;모델 관리부터 채팅까지 모든 기능이 OpenAI 형식의 REST API로 노출되어 있습니다.&lt;/p&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;b&gt;/ui&lt;/b&gt;: 관리 패널 (Admin Panel)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;LiteLLM Model Cost Map&lt;/b&gt;: 모델별 비용 단가표&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Model Hub&lt;/b&gt;: 사용 가능한 모델 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;2. 모델 대시보드&quot; data-ke-size=&quot;size23&quot;&gt;2. 모델 대시보드&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;관리 패널의 &lt;b&gt;Models + Endpoints&lt;/b&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;1876&quot; data-origin-height=&quot;832&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0jvuA/dJMcadbNNIU/i1VK56UUTgkQX1KkKQC6f1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0jvuA/dJMcadbNNIU/i1VK56UUTgkQX1KkKQC6f1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0jvuA/dJMcadbNNIU/i1VK56UUTgkQX1KkKQC6f1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0jvuA%2FdJMcadbNNIU%2Fi1VK56UUTgkQX1KkKQC6f1%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;709&quot; height=&quot;314&quot; data-origin-width=&quot;1876&quot; data-origin-height=&quot;832&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Show results&lt;/b&gt;: values.rendered.yaml의 model_list와 동일한 3개 모델이 등록&lt;/li&gt;
&lt;li&gt;LiteLLM이 OpenAI 호환 API를 통해 제공하기에 Provier가 openai&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Costs 열은 bedrock/claude-4.5-sonnet에만&lt;/b&gt; 할당&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;3. 사용량 및 비용 모니터링&quot; data-ke-size=&quot;size23&quot;&gt;3. 사용량 및 비용 모니터링&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;&lt;b&gt;Usage&lt;/b&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;3838&quot; data-origin-height=&quot;1988&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxgZh4/dJMcaijZaCm/KOj3vUMQykKkr6S0dkXPZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxgZh4/dJMcaijZaCm/KOj3vUMQykKkr6S0dkXPZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxgZh4/dJMcaijZaCm/KOj3vUMQykKkr6S0dkXPZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxgZh4%2FdJMcaijZaCm%2FKOj3vUMQykKkr6S0dkXPZK%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;711&quot; height=&quot;368&quot; data-origin-width=&quot;3838&quot; data-origin-height=&quot;1988&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Total Requests 18 / Successful 17 / Failed 1&lt;/b&gt;: 실패한 요청까지 그대로 집계&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Total Tokens 19,701&lt;/b&gt;: 워크샵 기간 사용한 토큰 총량&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Total Spend $0.0008&lt;/b&gt;: 단가가 등록된 Bedrock 호출분만 계산된 금액&lt;/li&gt;
&lt;/ul&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;h3 data-heading=&quot;4. Playground에서 모델 테스트&quot; data-ke-size=&quot;size23&quot;&gt;4. Playground에서 모델 테스트&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;&lt;b&gt;Playground&lt;/b&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;3832&quot; data-origin-height=&quot;1862&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bo6dcw/dJMcafnjQyC/HrAZva74zRKGDthoOHEjF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bo6dcw/dJMcafnjQyC/HrAZva74zRKGDthoOHEjF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bo6dcw/dJMcafnjQyC/HrAZva74zRKGDthoOHEjF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbo6dcw%2FdJMcafnjQyC%2FHrAZva74zRKGDthoOHEjF0%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;774&quot; height=&quot;376&quot; data-origin-width=&quot;3832&quot; data-origin-height=&quot;1862&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;b&gt;TTFT 1.86s, Total Latency 10.73s, In 22 / Out 696 토큰&lt;/b&gt;&lt;br /&gt;요청 단위의 성능 지표가 함께 표시되어, 모델별 응답 성능을 비교하기에 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-heading=&quot;Bedrock 모델 추가&quot; data-ke-size=&quot;size26&quot;&gt;Bedrock 모델 추가&lt;/h2&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;br /&gt;어플리케이션 코드 변경 없이, 구성 변경만으로 새 모델을 추가해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;# 액세스 권한이 있는 Bedrock 모델 확인
aws bedrock list-foundation-models \
  --query &quot;modelSummaries[?contains(modelId, 'gpt-oss')].{ModelId:modelId,ModelName:modelName}&quot; \
  --output table
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;# 구성 파일에 모델 추가 (components/ai-gateway/litellm/values.rendered.yaml)
model_list:
  - model_name: bedrock/gpt-oss-20b
    litellm_params:
      model: bedrock/openai.gpt-oss-20b-1:0
      aws_region_name: us-west-2
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;# 업데이트된 구성 적용
helm upgrade litellm oci://ghcr.io/berriai/litellm-helm \
  --namespace litellm \
  -f /workshop/components/ai-gateway/litellm/values.rendered.yaml

# 배포 완료 대기
kubectl rollout status deployment/litellm -n litellm
&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;돌아가면, bedrock/gpt-oss-20b가 드롭다운에 새로 등록되어 있습니다.&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;3118&quot; data-origin-height=&quot;1502&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7NXxt/dJMcagNjwKM/tEOhP7m1SFT2F8StyUqrvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7NXxt/dJMcagNjwKM/tEOhP7m1SFT2F8StyUqrvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7NXxt/dJMcagNjwKM/tEOhP7m1SFT2F8StyUqrvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7NXxt%2FdJMcagNjwKM%2FtEOhP7m1SFT2F8StyUqrvK%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;3118&quot; height=&quot;1502&quot; data-origin-width=&quot;3118&quot; data-origin-height=&quot;1502&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;바로 &quot;오늘 저녁 메뉴 추천 해줘&quot;라고 물어보니,&lt;br /&gt;4초 동안 생각한 뒤 한식 메뉴와 디저트를 표로 정리해줍니다.&lt;br /&gt;&lt;s&gt;(밥 줘)&lt;/s&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;여기서 중요한 점은, Open WebUI를 한 번도 건드리지 않았다는 것입니다.&lt;br /&gt;values 수정과 helm upgrade로, 서비스 중단 없이 스택 전체에 전파되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-heading=&quot;Virtual Key 생성&quot; data-ke-size=&quot;size26&quot;&gt;Virtual Key 생성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 모듈에서 만들 에이전트가 모델들에 접근하려면 전용 API 키가 필요합니다.&lt;br /&gt;LiteLLM은 이를 Virtual Key로 해결합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Virtual Key란?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;LiteLLM 프록시가 발급하고 관리하는 가상 API 키.&lt;br /&gt;AWS 자격 증명 같은 실제 제공자 키를 노출하지 않으면서,&lt;br /&gt;키 단위로 접근 가능한 모델, 예산, 속도 제한, 사용량 추적을 관리할 수 있습니다.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;출처: LiteLLM Docs&lt;/span&gt;&lt;/p&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;b&gt;Virtual Keys&lt;/b&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;3840&quot; data-origin-height=&quot;2160&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brb2x0/dJMcahFka8w/rx3CZkeGmdf8jYV71DRe7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brb2x0/dJMcahFka8w/rx3CZkeGmdf8jYV71DRe7K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brb2x0/dJMcahFka8w/rx3CZkeGmdf8jYV71DRe7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbrb2x0%2FdJMcahFka8w%2Frx3CZkeGmdf8jYV71DRe7K%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;702&quot; height=&quot;395&quot; data-origin-width=&quot;3840&quot; data-origin-height=&quot;2160&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;b&gt;+ Create New Key&lt;/b&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;3066&quot; data-origin-height=&quot;1272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yecOU/dJMcadv5j3o/GTJRfxEjswkiucHM1KcEV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yecOU/dJMcadv5j3o/GTJRfxEjswkiucHM1KcEV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yecOU/dJMcadv5j3o/GTJRfxEjswkiucHM1KcEV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyecOU%2FdJMcadv5j3o%2FGTJRfxEjswkiucHM1KcEV0%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;730&quot; height=&quot;303&quot; data-origin-width=&quot;3066&quot; data-origin-height=&quot;1272&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Owned By&lt;/b&gt;: You (기본값)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Team&lt;/b&gt;: 선택하지 않음 (선택 사항)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Key Name&lt;/b&gt;: agent-key&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Models&lt;/b&gt;: 사용 가능한 모든 모델 선택
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;bedrock/claude-4.5-sonnet&lt;/li&gt;
&lt;li&gt;bedrock/gpt-oss-20b&lt;/li&gt;
&lt;li&gt;vllm/qwen3-8b-neuron&lt;/li&gt;
&lt;li&gt;vllm/deepseek-r1-qwen3-8b-neuron&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Key Type&lt;/b&gt;: Default&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Create Key&lt;/b&gt;를 클릭하면 sk-로 시작하는 키가 발급됩니다.&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;h3 data-heading=&quot;Key 동작 검증&quot; data-ke-size=&quot;size23&quot;&gt;Key 동작 검증&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;발급받은 키가 실제로 동작하는지 Playground에서 검증합니다.&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;3302&quot; data-origin-height=&quot;1444&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cekq8i/dJMcahyB6CB/Am6lDrx0ftQHgJ2Op0cyr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cekq8i/dJMcahyB6CB/Am6lDrx0ftQHgJ2Op0cyr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cekq8i/dJMcahyB6CB/Am6lDrx0ftQHgJ2Op0cyr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcekq8i%2FdJMcahyB6CB%2FAm6lDrx0ftQHgJ2Op0cyr1%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;734&quot; height=&quot;321&quot; data-origin-width=&quot;3302&quot; data-origin-height=&quot;1444&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;b&gt;Virtual Key Source&lt;/b&gt;를 Current UI에서 &lt;b&gt;Virtual Key&lt;/b&gt;로 변경하고,&lt;br /&gt;발급받은 키를 붙여넣은 뒤 테스트 메시지를 보냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후, 모델(claude-4.5-sonnet)이 정상적으로 응답하는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 키는 이후 모듈에서 LangGraph 에이전트가 모델에 접근할 때 그대로 사용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;마무리&quot; data-ke-size=&quot;size23&quot;&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;이번 실습을 통해 통합 AI 게이트웨이가 주는 이점을 직접 확인할 수 있었습니다.&lt;/p&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;/li&gt;
&lt;li&gt;&lt;b&gt;자동 발견&lt;/b&gt;: 실행 중인 모델만 스캔해 구성에 반영&lt;/li&gt;
&lt;li&gt;&lt;b&gt;무중단 모델 추가&lt;/b&gt;: values 수정과 helm upgrade만으로 새 모델 전파&lt;/li&gt;
&lt;li&gt;&lt;b&gt;내장 관측성&lt;/b&gt;: 요청, 토큰, 비용이 게이트웨이 한 곳에 집계&lt;/li&gt;
&lt;li&gt;&lt;b&gt;접근 제어&lt;/b&gt;: Virtual Key로 모델 접근과 사용량을 키 단위로 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델 종류에 상관없이, 클라이언트 입장에서는 전부 같은 OpenAI 호환 API입니다.&lt;br /&gt;덕분에 모델 추가, 비용 집계, 키 관리가 전부 LiteLLM 한 곳에서 해결됩니다.&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;br /&gt;관측성 플랫폼, Langfuse를 살펴보겠습니다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <author>frontheadlock</author>
      <guid isPermaLink="true">https://frontheadlock.tistory.com/19</guid>
      <comments>https://frontheadlock.tistory.com/19#entry19comment</comments>
      <pubDate>Tue, 4 Aug 2026 22:35:16 +0900</pubDate>
    </item>
    <item>
      <title>GenAI on K8s/EKS 인퍼런스 최적화</title>
      <link>https://frontheadlock.tistory.com/18</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 OSSAI 활동을 통해, GenAI On EKS에 대해 교육받을 수 있는 기회가 생겼습니다.&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;교육 기간 중 Amazon EKS 기반의 Agentic AI 플랫폼 설계 및 배포와 관련하여,&lt;br /&gt;AWS로부터 핸즈온 가능한 플랫폼을 제공받아 직접 작업해볼 수 있었습니다.&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;br /&gt;LLM 배포부터 지능형 어플리케이션 구축까지 AI 플랫폼을 구축하는 것이었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;핸즈온 환경&lt;br /&gt;&lt;br /&gt;Agentic AI 플랫폼: EKS Auto Mode&lt;br /&gt;LLM: AQwen 3 8B와 DeepSeek R1 Qwen 3 8B(Neuron Chip), Amazon Bedrock (Claude)&lt;br /&gt;최신 AI 패턴: 관측성, 비용 추적, 확장성&lt;br /&gt;프레임워크: LangChain, LangGraph, Model Context Protocol(MCP)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-heading=&quot;워크샵 구성&quot; data-ke-size=&quot;size26&quot;&gt;워크샵 구성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;워크샵은 총 5개의 모듈로 구성되어 있습니다.&lt;/p&gt;
&lt;h3 data-heading=&quot;모듈 1. 모델과 상호작용&quot; data-ke-size=&quot;size23&quot;&gt;1. 모델과 상호작용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 배포 패턴을 통해 LLM과 상호작용하며 시작합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Open WebUI&lt;/b&gt;: 모델 상호작용을 위한 ChatGPT 유사 인터페이스 배포&lt;/li&gt;
&lt;li&gt;&lt;b&gt;vLLM on AWS Neuron&lt;/b&gt;: Neuron 위에서 Qwen 3 8B와 DeepSeek R1 Qwen 3 8B 호스팅&lt;/li&gt;
&lt;li&gt;&lt;b&gt;AWS Bedrock&lt;/b&gt;: Bedrock을 통해 Claude 4.5 Sonnet 연결&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-heading=&quot;모듈 2. Agentic AI 플랫폼 컴포넌트&quot; data-ke-size=&quot;size23&quot;&gt;2. Agentic AI 플랫폼 컴포넌트&lt;/h3&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;b&gt;LiteLLM Gateway&lt;/b&gt;: 모든 모델을 위한 통합 API 생성&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Langfuse Observability&lt;/b&gt;: 모든 토큰, 비용, 상호작용 추적&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Platform Integration&lt;/b&gt;: 컴포넌트들을 원활하게 연결&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-heading=&quot;모듈 3. Agentic AI 애플리케이션 구축&quot; data-ke-size=&quot;size23&quot;&gt;3. Agentic AI 애플리케이션 구축&lt;/h3&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;b&gt;LangChain &amp;amp; LangGraph&lt;/b&gt;: 체인, 에이전트, 워크플로우 구축&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Model Context Protocol&lt;/b&gt;: MCP 서버로 외부 도구 및 API 통합&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Loan Buddy Agent&lt;/b&gt;: LangGraph 기반의 대출 처리 애플리케이션 구축&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Secure and Observe&lt;/b&gt;: 에이전트 플로우를 플랫폼 컴포넌트와 통합&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-heading=&quot;모듈 4. 플랫폼 확장 및 평가&quot; data-ke-size=&quot;size23&quot;&gt;4. 플랫폼 확장 및 평가&lt;/h3&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;b&gt;LLM-as-a-Judge&lt;/b&gt;: Langfuse로 에이전트 출력 품질 자동 평가&lt;/li&gt;
&lt;li&gt;&lt;b&gt;A/B Model Routing&lt;/b&gt;: LiteLLM의 가중치 기반 트래픽 분할로 모델 비교&lt;/li&gt;
&lt;li&gt;&lt;b&gt;AMP/AMG Monitoring&lt;/b&gt;: Prometheus / Grafana로 대시보드 구축&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Auto-Scaling&lt;/b&gt;: HPA와 Karpenter를 통한 탄력적 추론 용량 확보&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-heading=&quot;모듈 5. 프로덕션 준비&quot; data-ke-size=&quot;size23&quot;&gt;5. 프로덕션 준비&lt;/h3&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;b&gt;RAG with Milvus&lt;/b&gt;: 정책 인식 결정을 위한 벡터 데이터베이스&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ragas Evaluation&lt;/b&gt;: RAG 품질 측정 (충실도, 관련성, 정확도)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Security Hardening&lt;/b&gt;: Pod Identity, External Secrets, Bedrock Guardrails&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Streaming Responses&lt;/b&gt;: 더 나은 UX를 위한 실시간 SSE 출력&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 워크샵 환경 구성과 모듈 1(모델과 상호작용)까지를 정리하고,&lt;br /&gt;이후 모듈은 다음 글에서 이어서 다뤄보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-heading=&quot;아키텍처&quot; data-ke-size=&quot;size26&quot;&gt;아키텍처&lt;/h2&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1851&quot; data-origin-height=&quot;850&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c333Fm/dJMcacRuXti/HBTO5iAsT6YmiSw2Sykm00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c333Fm/dJMcacRuXti/HBTO5iAsT6YmiSw2Sykm00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c333Fm/dJMcacRuXti/HBTO5iAsT6YmiSw2Sykm00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc333Fm%2FdJMcacRuXti%2FHBTO5iAsT6YmiSw2Sykm00%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;1851&quot; height=&quot;850&quot; data-origin-width=&quot;1851&quot; data-origin-height=&quot;850&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;사용자는 Open WebUI로 대화하고,&lt;br /&gt;모든 요청은 LiteLLM 게이트웨이를 거쳐 vLLM 또는 Bedrock으로 라우팅됩니다.&lt;br /&gt;그리고 이 과정 전체가 Langfuse로 추적됩니다.&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;br /&gt;비용 추적과 관측성, 모델 교체가 전부 이 지점에서 해결됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Agentic AI에 EKS가 유용한 이유&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Scalability
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AI 워크로드 수요에 따른 오토스케일링&lt;/li&gt;
&lt;li&gt;특수 하드웨어 지원 (GPU, Neuron)&lt;/li&gt;
&lt;li&gt;분산 추론 및 다중 모델 배포 패턴&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Flexibility
&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;Operations
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Langfuse를 통한 포괄적인 관측성&lt;/li&gt;
&lt;li&gt;Helm을 통한 자동화된 라이프사이클 관리&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;h2 data-heading=&quot;워크샵 환경&quot; data-ke-size=&quot;size26&quot;&gt;워크샵 환경&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;시작하기&quot; data-ke-size=&quot;size23&quot;&gt;시작하기&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2546&quot; data-origin-height=&quot;2160&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oFuv0/dJMcabZuVTa/wnUNkmEy2S8ghU5jjlKJUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oFuv0/dJMcabZuVTa/wnUNkmEy2S8ghU5jjlKJUK/img.png&quot; data-alt=&quot;EKS를 무료로...!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oFuv0/dJMcabZuVTa/wnUNkmEy2S8ghU5jjlKJUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoFuv0%2FdJMcabZuVTa%2FwnUNkmEy2S8ghU5jjlKJUK%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;610&quot; height=&quot;518&quot; data-origin-width=&quot;2546&quot; data-origin-height=&quot;2160&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;EKS를 무료로...!&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 data-ke-size=&quot;size16&quot;&gt;AWS에서 핸즈온용 플랫폼을 제공해주어, 비용 부담 없이 개발 가능한 환경을 제공받았습니다. &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;Workshop Studio에 액세스하면 위와 같이,&lt;br /&gt;브라우저에서 바로 열리는 Visual Studio Code 기반의 IDE가 주어집니다.&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;workshop 폴더에는 components, terraform 등 실습에 사용할 코드가 미리 담겨 있고,&lt;br /&gt;하단 터미널은 participant 계정으로 EKS 클러스터와 AWS CLI에 바로 연결되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사전에 구성된 EKS 클러스터와 임시 자격 증명이 포함되어 있기에,&lt;br /&gt;별도 설정 없이 바로 kubectl을 사용할 수 있었습니다.&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;워크샵의 주제는 어디까지나 Agentic AI인 만큼,&lt;br /&gt;애플리케이션을 구축하고 배포하기 이전의 기반 인프라는 모두 사전 구성되어 제공되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;EKS Auto Mode&quot; data-ke-size=&quot;size23&quot;&gt;EKS Auto Mode&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;워크샵 환경에는 완전히 작동하는 Amazon EKS 클러스터가 포함되어 있고,&lt;br /&gt;이 클러스터는 &lt;b&gt;EKS Auto Mode&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;EKS Auto Mode는 컴퓨팅, 스토리지, 네트워킹 리소스 관리의 운영 오버헤드를 제거하는&lt;br /&gt;완전 관리형 Kubernetes 경험을 제공합니다.&lt;/p&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;: EC2 인스턴스를 수동으로 생성하거나 관리할 필요 없음&lt;/li&gt;
&lt;li&gt;&lt;b&gt;동적 확장&lt;/b&gt;: 워크로드 수요에 따라 용량을 자동으로 조정&lt;/li&gt;
&lt;li&gt;&lt;b&gt;패치 관리&lt;/b&gt;: OS 및 Kubernetes 컴포넌트 자동 업데이트&lt;/li&gt;
&lt;li&gt;&lt;b&gt;비용 최적화&lt;/b&gt;: 지능형 인스턴스 선택 및 Spot 인스턴스 통합&lt;/li&gt;
&lt;/ul&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1676&quot; data-origin-height=&quot;406&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OrgB3/dJMcacYkVyT/Z7ZQWaXeQGpxewPiwbRVZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OrgB3/dJMcacYkVyT/Z7ZQWaXeQGpxewPiwbRVZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OrgB3/dJMcacYkVyT/Z7ZQWaXeQGpxewPiwbRVZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOrgB3%2FdJMcacYkVyT%2FZ7ZQWaXeQGpxewPiwbRVZk%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;1676&quot; height=&quot;406&quot; data-origin-width=&quot;1676&quot; data-origin-height=&quot;406&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;조회된 노드가 모두 Ready 상태인데, COMPUTE-TYPE 레이블이 전부 auto입니다.&lt;br /&gt;제가 직접 만든 노드가 하나도 없이,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Auto Mode로 워크로드에 맞춰 알아서 프로비저닝되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;클러스터 노드 구성&quot; data-ke-size=&quot;size23&quot;&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;노드풀과 스토리지를 조회해보면 클러스터의 구성이 한눈에 들어옵니다.&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;1708&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QPf0j/dJMcaftYqNY/hSO6zlZspMYivDMjRdLaUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QPf0j/dJMcaftYqNY/hSO6zlZspMYivDMjRdLaUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QPf0j/dJMcaftYqNY/hSO6zlZspMYivDMjRdLaUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQPf0j%2FdJMcaftYqNY%2FhSO6zlZspMYivDMjRdLaUk%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;1708&quot; height=&quot;432&quot; data-origin-width=&quot;1708&quot; data-origin-height=&quot;432&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;/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는 gpu 환경 위에서 동작을 하는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;neuron 노드풀에만 노드 2개가 떠있고, &lt;b&gt;gpu 노드풀은 0개&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노드풀 정의는 되어 있지만, GPU 워크로드가 없는 동안에는 비싼 노드를 하나도 유지하지 않습니다.&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;StorageClass로는 ebs(기본)와 efs가 준비되어 있고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;huggingface-cache, neuron-cache라는 100Gi EFS 볼륨 2개가 바인딩되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 두 캐시는 뒤의 vLLM 섹션에서 다시 등장합니다.&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;&lt;b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;General Purpose Nodes (Multi-Architecture)&lt;/span&gt;&lt;/b&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;b&gt;Instance Types&lt;/b&gt;: 최신 세대 컴퓨팅(C), 메모리(M), 범용(R) 최적화 인스턴스
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;AWS Graviton (ARM64)&lt;/b&gt;: 비슷한 x86 대비 최대 40% 향상된 가격 대비 성능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;x86 (AMD/Intel)&lt;/b&gt;: 기존 x86 아키텍처 인스턴스&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Architecture Support&lt;/b&gt;: 워크로드 호환성에 따라 자동 선택되는 멀티 아키텍처 (amd64/arm64)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: 일반 워크로드, 웹 서비스, 컨트롤 플레인 컴포넌트 실행&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Scaling&lt;/b&gt;: Karpenter가 Pod 요구사항에 따라 비용이 효율적인 인스턴스를 자동 선택, 낮은 노드는 통합&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;GPU-Accelerated Nodes&lt;/b&gt;&lt;b&gt;&lt;/b&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;b&gt;Instance Types&lt;/b&gt;: NVIDIA GPU (g5, g6, p4, p5 패밀리)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: GPU 집약적 AI/ML 워크로드 실행&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Features&lt;/b&gt;: CUDA 지원, GPU 오퍼레이터 사전 설치&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;b&gt;AWS Neuron Nodes&lt;/b&gt;&lt;b&gt;&lt;/b&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;b&gt;Instance Types&lt;/b&gt;: inf2, trn1, trn2 인스턴스&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: 대규모 언어 모델을 위한 최적화된 추론&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Benefits&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GPU 대비 추론당 최대 50% 낮은 비용&lt;/li&gt;
&lt;li&gt;최적 성능을 위한 사전 컴파일 모델&lt;/li&gt;
&lt;li&gt;네이티브 int8 양자화 지원&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 data-heading=&quot;스토리지 구성&quot; data-ke-size=&quot;size23&quot;&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;클러스터는 영구 스토리지로 &lt;b&gt;Amazon EFS&lt;/b&gt;(Elastic File System)를 사용합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Shared Storage&lt;/b&gt;: 여러 Pod가 동시에 읽기/쓰기 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Elastic Throughput Mode&lt;/b&gt;: 워크로드에 따라 성능을 자동으로 확장&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Model Caching&lt;/b&gt;: 빠른 배포를 위해 사전 다운로드된 모델을 EFS에 저장&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Cross-AZ Availability&lt;/b&gt;: 여러 가용 영역에 걸친 고가용성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;사전 설치된 Agentic AI 스택&quot; data-ke-size=&quot;size23&quot;&gt;사전 설치된 Agentic AI 스택&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;Agentic AI 애플리케이션을 바로 구축할 수 있도록, 주요 컴포넌트들이 미리 배포되어 있습니다.&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1726&quot; data-origin-height=&quot;1052&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVW2FX/dJMcagzEex2/oR82vmYD5Kli5assc62E91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVW2FX/dJMcagzEex2/oR82vmYD5Kli5assc62E91/img.png&quot; data-alt=&quot;langfuse 관측이 많죠?&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVW2FX/dJMcagzEex2/oR82vmYD5Kli5assc62E91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVW2FX%2FdJMcagzEex2%2FoR82vmYD5Kli5assc62E91%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;650&quot; height=&quot;396&quot; data-origin-width=&quot;1726&quot; data-origin-height=&quot;1052&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;langfuse 관측이 많죠?&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 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;Open WebUI&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;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Features&lt;/b&gt;: 채팅 인터페이스, 대화 기록, 모델 전환&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Integration&lt;/b&gt;: LiteLLM 게이트웨이와 연동되도록 사전 구성&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;b&gt;LiteLLM&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;여러 LLM 제공자에 대한 단일 인터페이스를 제공하는 통합 API 게이트웨이입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: 서로 다른 모델 제공자 간 API 호출 표준화&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Supported Models&lt;/b&gt;: vLLM, AWS Bedrock, OpenAI 호환 엔드포인트&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Load Balancing&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;b&gt;Langfuse&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;LLM 애플리케이션을 위한 포괄적인 관측성 플랫폼입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Monitoring&lt;/b&gt;: 토큰 사용량, 지연시간, 비용 추적&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Debugging&lt;/b&gt;: 전체 스택을 관통하는 개별 요청 추적&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Analytics&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;b&gt;vLLM&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;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Pre-loaded Models&lt;/b&gt;: Qwen 3 8B, DeepSeek R1 Qwen 3 8B (Neuron)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Optimization&lt;/b&gt;: Continuous Batching, PagedAttention, Tensor Parallelism&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Hardware Acceleration&lt;/b&gt;: AWS Neuron 칩에 최적화&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-heading=&quot;모듈 1. 모델과 상호작용&quot; data-ke-size=&quot;size26&quot;&gt;모듈 1. 모델과 상호작용&lt;/h2&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;br /&gt;Open WebUI가 LiteLLM 통합 API를 바라보고, LiteLLM이 세 개의 모델에 요청을 나눠줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;Open WebUI&quot; data-ke-size=&quot;size23&quot;&gt;Open WebUI&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;Open WebUI는 원래 Ollama WebUI라는 이름으로 시작한 오픈소스 프로젝트로,&lt;br /&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;b&gt;최신 채팅 인터페이스&lt;/b&gt;: ChatGPT와 유사한 깔끔하고 반응형 디자인&lt;/li&gt;
&lt;li&gt;&lt;b&gt;다중 모델 지원&lt;/b&gt;: 여러 모델 간 원활한 전환&lt;/li&gt;
&lt;li&gt;&lt;b&gt;대화 관리&lt;/b&gt;: 채팅 기록 저장, 정리 및 검색&lt;/li&gt;
&lt;li&gt;&lt;b&gt;파일 업로드&lt;/b&gt;: 문서 및 이미지 지원 (모델이 지원하는 경우)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프롬프트 템플릿&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;워크샵에서 사용된 Helm values는 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;# Open WebUI Helm values
nameOverride: openwebui

# ALB Ingress 구성
ingress:
  enabled: true
  annotations:
    alb.ingress.kubernetes.io/target-type: ip
    {{#if DOMAIN}}
    alb.ingress.kubernetes.io/listen-ports: '[{&quot;HTTPS&quot;:443}]'
    {{/if}}
  host: openwebui.{{{DOMAIN}}}

# LiteLLM API 게이트웨이 연결 (클러스터 내부 주소 사용)
openaiBaseApiUrl: http://litellm.litellm:4000/v1

extraEnvVars:
  - name: OPENAI_API_KEY
    value: {{{LITELLM_API_KEY}}}
  - name: WEBUI_ADMIN_EMAIL
    value: {{{OPENWEBUI_ADMIN_EMAIL}}}
  - name: WEBUI_ADMIN_PASSWORD
    value: {{{OPENWEBUI_ADMIN_PASSWORD}}}

# 로컬 Ollama 비활성화 (외부 모델 사용)
ollama:
  enabled: false
pipelines:
  enabled: false

# 대화를 위한 영구 스토리지
persistence:
  enabled: true
  size: 100Gi

# 리소스 할당
resources:
  requests:
    cpu: 1
    memory: 2Gi
  limits:
    memory: 2Gi
&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-heading=&quot;1. LiteLLM 통합&quot; data-ke-size=&quot;size20&quot;&gt;1. LiteLLM 통합&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Open WebUI는 모델 엔드포인트에 직접 연결하는 대신 LiteLLM에 연결합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;통합 API&lt;/b&gt;: 모든 모델에 대한 단일 엔드포인트&lt;/li&gt;
&lt;li&gt;&lt;b&gt;로드 밸런싱&lt;/b&gt;: 모델 레플리카 간 자동 분산&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Fallback 지원&lt;/b&gt;: 모델 간 원활한 전환&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LiteLLM은 AI 게이트웨이 역할을 하며,&lt;br /&gt;모든 모델에 대해 통합된 OpenAI 호환 인터페이스를 제공합니다.&lt;br /&gt;LiteLLM 자체는 모듈 2에서 자세히 다루겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-heading=&quot;2. AWS Load Balancer 통합&quot; data-ke-size=&quot;size20&quot;&gt;2. AWS Load Balancer 통합&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Ingress 구성은 Application Load Balancer(ALB)를 생성합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;HTTPS Termination&lt;/b&gt;: SSL/TLS를 로드 밸런서에서 처리&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Target Type IP&lt;/b&gt;: 더 나은 성능을 위한 직접 Pod 네트워킹&lt;/li&gt;
&lt;li&gt;&lt;b&gt;커스텀 도메인&lt;/b&gt;: https://openwebui.${DOMAIN}으로 접근 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-heading=&quot;3. 영구 스토리지&quot; data-ke-size=&quot;size20&quot;&gt;3. 영구 스토리지&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;100Gi의 EBS 스토리지가 다음을 보장합니다.&lt;/p&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;/li&gt;
&lt;li&gt;&lt;b&gt;사용자 설정&lt;/b&gt;: 세션 간 설정 유지&lt;/li&gt;
&lt;li&gt;&lt;b&gt;안정적인 성능&lt;/b&gt;: 애플리케이션의 일관된 I/O 성능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;EKS Auto Mode&lt;/b&gt;는 StorageClass만 정의하면 PVC에 대한 EBS 자동 프로비저닝&lt;br /&gt;수동 CSI 드라이버 설치와 노드 구성이 필요 없다는 점이 편리했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-heading=&quot;배포와 접속&quot; data-ke-size=&quot;size20&quot;&gt;배포와 접속&lt;/h4&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;pre class=&quot;livecodeserver&quot;&gt;&lt;code&gt;# Helm 레포지토리 추가
helm repo add open-webui https://open-webui.github.io/helm-charts
helm repo update

# 커스텀 구성으로 Open WebUI 설치
helm upgrade --install openwebui open-webui/open-webui \
  --namespace openwebui \
  --create-namespace \
  -f values.rendered.yaml

# Open WebUI URL 확인
echo &quot;Open WebUI URL: http://$(kubectl get ingress -n openwebui openwebui -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')&quot;

# 생성된 관리자 계정 조회 후 로그인
helm get values openwebui -n openwebui
&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;발급된 ALB 주소로 접속해 로그인하면, 모델 선택 드롭다운이 표시됩니다.&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;3024&quot; data-origin-height=&quot;1898&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wiDW7/dJMcafU6XDn/N9K4VqRnJiHKKy6GoH3mQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wiDW7/dJMcafU6XDn/N9K4VqRnJiHKKy6GoH3mQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wiDW7/dJMcafU6XDn/N9K4VqRnJiHKKy6GoH3mQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwiDW7%2FdJMcafU6XDn%2FN9K4VqRnJiHKKy6GoH3mQ1%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;624&quot; height=&quot;392&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;1898&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;드롭다운에는 qwen3-8b, deepseek-r1, 그리고 bedrock이 나타납니다.&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;EKS에서 직접 서빙 중인 모델과 Bedrock의 관리형 모델이&lt;br /&gt;하나의 UI에서 완전히 같은 방식으로 노출되는 것인데, 이것이 LiteLLM 게이트웨이의 효과입니다.&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;다만 bedrock/claude-4.5-sonnet은 EKS에서 호스팅되는 것이 아니라,&lt;br /&gt;LiteLLM을 거쳐 Bedrock API로 라우팅됩니다.&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;Open WebUI는 Agentic AI 스택에서 다음과 같이 통합되어 사용됩니다.&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;1578&quot; data-origin-height=&quot;997&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Itnet/dJMcaasI97n/Cui5MjgVdyKXsKOwfC4K41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Itnet/dJMcaasI97n/Cui5MjgVdyKXsKOwfC4K41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Itnet/dJMcaasI97n/Cui5MjgVdyKXsKOwfC4K41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FItnet%2FdJMcaasI97n%2FCui5MjgVdyKXsKOwfC4K41%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;1578&quot; height=&quot;997&quot; data-origin-width=&quot;1578&quot; data-origin-height=&quot;997&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;vLLM 모델이면 클러스터 내부 Pod로, Bedrock 모델이면 AWS API로 분기하지만,&lt;br /&gt;사용자 입장에서는 어떤 백엔드든 동일한 요청과 응답 형태를 갖습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;vLLM: 자체 호스팅 모델 서빙&quot; data-ke-size=&quot;size23&quot;&gt;vLLM: 자체 호스팅 모델 서빙&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;그렇다면 이러한 GenAI 모델들은 Kubernetes에서 실제로 어떻게 실행되고 있을까요?&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;pre class=&quot;vala&quot;&gt;&lt;code&gt;# 현재 실행 중인 vLLM 모델 확인
kubectl get pods -n vllm

# 채팅 경험 뒤의 실제 Deployment 확인
kubectl get deployments -n vllm -o wide

# 모델을 호스팅하는 노드 확인
kubectl get pods -n vllm -o wide

# vLLM 구성 디렉터리 확인
ls /workshop/components/llm-model/vllm/

# 방금 사용한 Qwen 3 배포 살펴보기
cat /workshop/components/llm-model/vllm/model-qwen3-8b-neuron.rendered.yaml

# DeepSeek 배포와 비교
cat /workshop/components/llm-model/vllm/model-deepseek-r1-qwen3-8b-neuron.rendered.yaml
&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;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;2180&quot; data-origin-height=&quot;614&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7Vh0g/dJMcabLZPyU/eQcnbL7p5hVRVXPag1lFV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7Vh0g/dJMcabLZPyU/eQcnbL7p5hVRVXPag1lFV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7Vh0g/dJMcabLZPyU/eQcnbL7p5hVRVXPag1lFV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7Vh0g%2FdJMcabLZPyU%2FeQcnbL7p5hVRVXPag1lFV0%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;2180&quot; height=&quot;614&quot; data-origin-width=&quot;2180&quot; data-origin-height=&quot;614&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;방금까지 채팅하던 두 모델이 각각 1/1 Running 상태의 Pod로 돌아가고 있습니다.&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;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;메시지 입력 &amp;rarr; Open WebUI &amp;rarr; LiteLLM &amp;rarr; vLLM Pod&lt;/li&gt;
&lt;li&gt;Pod가 AWS Neuron 하드웨어에서 요청 처리&lt;/li&gt;
&lt;li&gt;응답이 동일한 경로를 역으로 거쳐 브라우저에 도착&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;vLLM이란?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;LLM을 고속으로 추론하기 위한 효율적 엔진으로, 서빙 환경에서 높은 처리량과 낮은 지연 시간이 목표&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;출처: SKT Enterprise&lt;/span&gt;&lt;/p&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;vLLM은 다음과 같은 기능을 제공합니다.&lt;/p&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;/li&gt;
&lt;li&gt;&lt;b&gt;Continuous Batching&lt;/b&gt;: 최적의 하드웨어 활용을 위한 동적 요청 배칭&lt;/li&gt;
&lt;li&gt;&lt;b&gt;PagedAttention&lt;/b&gt;: 긴 컨텍스트를 위한 효율적인 메모리 관리&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Tensor Parallelism&lt;/b&gt;: 여러 가속기에 모델 분산&lt;/li&gt;
&lt;li&gt;&lt;b&gt;OpenAI 호환 API&lt;/b&gt;: OpenAI API의 드롭인 대체&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;&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;Open WebUI에서 DeepSeek 모델에게&lt;br /&gt;&quot;교촌 치킨이랑 처갓집 양념치킨 중에 어떤 게 더 맛있어? 근거를 수치 기반으로 제공해줘.&quot;라고 물어봤습니다.&lt;br /&gt;&lt;s&gt;(선택장애..)&lt;/s&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;3018&quot; data-origin-height=&quot;1724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lzOp0/dJMcaiKXeaQ/shU7EI5pvkfV03sKrtjVBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lzOp0/dJMcaiKXeaQ/shU7EI5pvkfV03sKrtjVBK/img.png&quot; data-alt=&quot;교촌이 이겼습니다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lzOp0/dJMcaiKXeaQ/shU7EI5pvkfV03sKrtjVBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlzOp0%2FdJMcaiKXeaQ%2FshU7EI5pvkfV03sKrtjVBK%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;655&quot; height=&quot;374&quot; data-origin-width=&quot;3018&quot; data-origin-height=&quot;1724&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 data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러고는 가격 대비 맛 만족도부터 성분 라벨 비교까지, 수치를 들어가며 제법 진지하게 비교해줍니다.&lt;br /&gt;&lt;s&gt;(둘 다 처음 보는 메뉴인데?)&lt;/s&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;이 질문에 답하는 동안 vLLM Pod의 로그를 실시간으로 지켜보면 다음과 같습니다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;participant:/workshop$ kubectl logs -f --tail=0 -n vllm deployment/deepseek-r1-qwen3-8b-neuron
(APIServer pid=1) INFO:     10.0.45.96:60236 - &quot;POST /v1/chat/completions HTTP/1.1&quot; 200 OK
INFO 08-01 13:16:36 [metrics.py:398] Avg prompt throughput: 4.2 tokens/s, Avg generation throughput: 0.1 tokens/s, Running: 1 reqs, GPU KV cache usage: 0.0%, CPU KV cache usage: 33.3%.
INFO 08-01 13:16:41 [metrics.py:398] Avg prompt throughput: 0.0 tokens/s, Avg generation throughput: 17.8 tokens/s, Running: 1 reqs, GPU KV cache usage: 0.0%, CPU KV cache usage: 33.3%.
INFO 08-01 13:16:46 [metrics.py:398] Avg prompt throughput: 0.0 tokens/s, Avg generation throughput: 18.2 tokens/s, Running: 1 reqs, GPU KV cache usage: 0.0%, CPU KV cache usage: 33.3%.
...(약 2분간 18 tokens/s 내외로 토큰 생성)...
INFO 08-01 13:18:22 [metrics.py:398] Avg prompt throughput: 301.5 tokens/s, Avg generation throughput: 11.9 tokens/s, Running: 1 reqs, GPU KV cache usage: 0.0%, CPU KV cache usage: 33.3%.
(APIServer pid=1) INFO:     10.0.45.96:60236 - &quot;POST /v1/chat/completions HTTP/1.1&quot; 200 OK
INFO 08-01 13:18:57 [metrics.py:398] Avg prompt throughput: 343.0 tokens/s, Avg generation throughput: 11.6 tokens/s, Running: 1 reqs, GPU KV cache usage: 0.0%, CPU KV cache usage: 33.3%.
INFO 08-01 13:19:02 [metrics.py:398] Avg prompt throughput: 0.0 tokens/s, Avg generation throughput: 18.2 tokens/s, Running: 1 reqs, GPU KV cache usage: 0.0%, CPU KV cache usage: 33.3%.

....
&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;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;: POST /v1/chat/completions로 프롬프트가 도착&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모델 처리 중&lt;/b&gt;: 토큰 생성 및 처리 지표가 5초 단위로 갱신&lt;/li&gt;
&lt;li&gt;&lt;b&gt;성능 통계&lt;/b&gt;: 처리량, 실행 중인 요청 수, KV 캐시 사용률&lt;/li&gt;
&lt;/ul&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;b&gt;Prompt throughput&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;평소에는 0, 요청이 들어와 프롬프트를 읽는 순간 300 tokens/s 이상으로 튀어 오릅니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Generation throughput&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;응답을 생성하는 동안 약 18 tokens/s로 일정하게 유지됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;KV cache usage&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GPU KV cache가 0인 이유는, GPU가 아닌 Neuron 위에서 실행되고 있기 때문입니다.&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 data-heading=&quot;AWS Neuron 배포 구성&quot; data-ke-size=&quot;size23&quot;&gt;AWS Neuron 배포 구성&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;AWS Neuron은 AWS Inferentia(inf2) 및 Trainium(trn1) 칩을 위한 SDK입니다.&lt;/p&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;: GPU 대비 추론당 최대 50% 낮은 비용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;LLM 최적화&lt;/b&gt;: 트랜스포머 아키텍처에 대한 기본 지원&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Quantization&lt;/b&gt;: 메모리 사용을 줄이기 위한 INT8 및 FP8 지원&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vLLM 배포는 네임스페이스, 스토리지, 시크릿, Deployment, Service로 구성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;# Namespace 격리
apiVersion: v1
kind: Namespace
metadata:
  name: vllm
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-heading=&quot;스토리지: 두 개의 캐시&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-heading=&quot;스토리지: 두 개의 캐시&quot; data-ke-size=&quot;size20&quot;&gt;스토리지: 두 개의 캐시&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Amazon EFS를 사용해 다운로드한 모델과 컴파일된 Neuron 그래프를 캐시합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;# pvc-huggingface-cache.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: huggingface-cache
  namespace: vllm
spec:
  storageClassName: efs
  accessModes:
    - ReadWriteMany  # 여러 Pod가 읽기/쓰기 가능
  resources:
    requests:
      storage: 100Gi
---
# pvc-neuron-cache.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: neuron-cache
  namespace: vllm
spec:
  storageClassName: efs
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 100Gi
&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;앞서 클러스터 구성에서 kubectl get pv로 확인했던 100Gi EFS 볼륨 2개가 바로 이 캐시들입니다.&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;HuggingFace 캐시&lt;/b&gt;: 다운로드한 모델 가중치 저장&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Neuron 캐시&lt;/b&gt;: 컴파일된 모델 그래프 저장&lt;/li&gt;
&lt;li&gt;&lt;b&gt;재사용성&lt;/b&gt;: 캐시된 데이터는 Pod 재시작 후에도 유지되어, 재배포가 훨씬 빨라짐&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-heading=&quot;시크릿: HuggingFace 토큰&quot; data-ke-size=&quot;size20&quot;&gt;시크릿: HuggingFace 토큰&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# secret.template.yaml
apiVersion: v1
kind: Secret
metadata:
  name: hf-token
  namespace: vllm
type: Opaque
stringData:
  token: ${HF_TOKEN}  # 배포 중 주입됨
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-heading=&quot;Deployment: Neuron 최적화 Qwen 3 8B&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-heading=&quot;Deployment: Neuron 최적화 Qwen 3 8B&quot; data-ke-size=&quot;size20&quot;&gt;Deployment: Neuron 최적화 Qwen 3 8B&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;# model-qwen3-8b-neuron.rendered.yaml (주요 섹션)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: qwen3-8b-neuron
  namespace: vllm
spec:
  replicas: 1
  selector:
    matchLabels:
      app: qwen3-8b-neuron
  template:
    spec:
      # Neuron 하드웨어를 위한 노드 선택
      nodeSelector:
        eks.amazonaws.com/instance-family: inf2
        node.kubernetes.io/instance-type: inf2.xlarge
      containers:
        - name: vllm
          image: public.ecr.aws/agentic-ai-platforms-on-k8s/vllm-neuron:qwen3-8b
          command: [&quot;vllm&quot;, &quot;serve&quot;]
          args:
            - --served-model-name=qwen3-8b-neuron
            - --trust-remote-code
            - --gpu-memory-utilization=0.90
            - --enable-auto-tool-choice
            - --tool-call-parser=hermes
            - --reasoning-parser=qwen3
            - --tensor-parallel-size=2
            - --max-num-seqs=1
            - --max-model-len=16384
          resources:
            requests:
              cpu: 3
              memory: 12Gi
              aws.amazon.com/neuroncore: 2  # 2개의 Neuron 코어 요청
            limits:
              aws.amazon.com/neuroncore: 2
&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;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;: Pod가 Neuron이 장착된 inf2 인스턴스에서만 실행되도록 보장&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Neuron 코어&lt;/b&gt;: neuroncore 리소스는 요청(requests)과 제한(limits)이 반드시 일치해야 함&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Tensor Parallelism&lt;/b&gt;: 더 빠른 추론을 위해 2개의 Neuron 코어에 모델 분할&lt;/li&gt;
&lt;li&gt;&lt;b&gt;컨텍스트와 동시성&lt;/b&gt;: 16K 컨텍스트 윈도우로, 한 번에 하나의 시퀀스만 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-heading=&quot;Service&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-heading=&quot;Service&quot; data-ke-size=&quot;size20&quot;&gt;Service&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Service는 vLLM Deployment를 노출해, LiteLLM 같은 다른 컴포넌트가 접근할 수 있도록 합니다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;apiVersion: v1
kind: Service
metadata:
  name: qwen3-8b-neuron
  namespace: vllm
spec:
  selector:
    app: qwen3-8b-neuron
  ports:
    - name: http
      port: 8000
&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;Selector&lt;/b&gt;: app: qwen3-8b-neuron 레이블이 있는 Pod와 매칭&lt;/li&gt;
&lt;li&gt;&lt;b&gt;포트 8000&lt;/b&gt;: OpenAI 호환 엔드포인트를 위한 표준 vLLM API 포트&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ClusterIP&lt;/b&gt;: 클러스터 내부에서만 접근 가능한 내부 서비스&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 외에도 LiteLLM을 통해 Bedrock 모델을 같은 인터페이스로 호출할 수 있습니다.&lt;/p&gt;
&lt;h3 data-heading=&quot;Open WebUI에서의 RAG&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-heading=&quot;Open WebUI에서의 RAG&quot; data-ke-size=&quot;size23&quot;&gt;Open WebUI에서의 RAG&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;Open WebUI에는 또한 기본 RAG(Retrieval Augmented Generation) 기능이 내장되어 있습니다.&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;RAG가 문서의 특정 컨텍스트를 제공해 AI의 응답을 어떻게 변화시키는지 확인해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 IDE 터미널에서, 모델이 알기 힘든 내용의 테스트 파일을 만듭니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;cat &amp;gt; super-secret.txt &amp;lt;&amp;lt; 'EOF'
Super Secret Document

This document contains classified information about the secret project.
Only authorized personnel are allowed to access this data.

Project Codename: Nightfall
Objective: Develop an untraceable communication device.
Status: In progress

Remember, this information is top secret and must not be shared with anyone.
EOF
&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;이 파일을 IDE 파일 탐색기에서 로컬 머신으로 다운로드한 뒤, Open WebUI에 업로드합니다.&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;다음으로 Open WebUI에서 Knowledge Base를 생성합니다.&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;1214&quot; data-origin-height=&quot;455&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FWw0t/dJMcabE463m/YFEHF5wacKHUK1bJmtC67k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FWw0t/dJMcabE463m/YFEHF5wacKHUK1bJmtC67k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FWw0t/dJMcabE463m/YFEHF5wacKHUK1bJmtC67k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFWw0t%2FdJMcabE463m%2FYFEHF5wacKHUK1bJmtC67k%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;734&quot; height=&quot;275&quot; data-origin-width=&quot;1214&quot; data-origin-height=&quot;455&quot;/&gt;&lt;/span&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;&lt;b&gt;Workspace &amp;gt; Knowledge&lt;/b&gt;로 이동해 새 Knowledge Base 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&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;b&gt;Name&lt;/b&gt;: super-secret-info&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Description&lt;/b&gt;: Store secret info in knowledge base&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Visibility&lt;/b&gt;: Private&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Create Knowledge&lt;/b&gt; 클릭 후, &lt;b&gt;+ &amp;gt; Upload files&lt;/b&gt;로 super-secret.txt 업로드&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;869&quot; data-origin-height=&quot;760&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYngk8/dJMb99UO4a9/grGcF6qZzgluFycvJ1oJt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYngk8/dJMb99UO4a9/grGcF6qZzgluFycvJ1oJt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYngk8/dJMb99UO4a9/grGcF6qZzgluFycvJ1oJt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYngk8%2FdJMb99UO4a9%2FgrGcF6qZzgluFycvJ1oJt1%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;491&quot; height=&quot;429&quot; data-origin-width=&quot;869&quot; data-origin-height=&quot;760&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;이제 bedrock/claude-4.5-sonnet에게 같은 질문을 RAG 유무에 따라 비교해봅니다.&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;질문은 &quot;What is the objective of project nightfall?&quot;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;RAG 없이 질문&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1515&quot; data-origin-height=&quot;549&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7uvvW/dJMcaiYsfSA/ocJk1PM7V6zmeum32Kb0QK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7uvvW/dJMcaiYsfSA/ocJk1PM7V6zmeum32Kb0QK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7uvvW/dJMcaiYsfSA/ocJk1PM7V6zmeum32Kb0QK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7uvvW%2FdJMcaiYsfSA%2FocJk1PM7V6zmeum32Kb0QK%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;777&quot; height=&quot;282&quot; data-origin-width=&quot;1515&quot; data-origin-height=&quot;549&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;RAG 없이 질문하면, 모델은 &quot;Project Nightfall에 대한 구체적인 정보가 없다&quot;며&lt;br /&gt;소설이나 게임, 군사 프로젝트 등의 가능성만 나열하고 오히려 맥락을 되묻습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;&lt;b&gt;2. Knowledge Base 연결 후 질문&lt;/b&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;1513&quot; data-origin-height=&quot;496&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJXUvQ/dJMcaiRNWOK/kdRE3WYDtLY1JRwKbIjgiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJXUvQ/dJMcaiRNWOK/kdRE3WYDtLY1JRwKbIjgiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJXUvQ/dJMcaiRNWOK/kdRE3WYDtLY1JRwKbIjgiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJXUvQ%2FdJMcaiRNWOK%2FkdRE3WYDtLY1JRwKbIjgiK%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;1513&quot; height=&quot;496&quot; data-origin-width=&quot;1513&quot; data-origin-height=&quot;496&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;Knowledge Base를 연결한 뒤에는 &lt;b&gt;Retrieved 1 source&lt;/b&gt; 표시와 함께,&lt;br /&gt;super-secret.txt를 출처로 인용하며 &quot;추적 불가능한 통신 장치 개발&quot;이라고 정확히 답합니다.&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;br /&gt;답변의 질이 완전히 달라진다는 것을 직접 확인할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;마무리&quot; data-ke-size=&quot;size23&quot;&gt;마무리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 EKS Auto Mode 기반의 워크샵 환경 구성과,&lt;br /&gt;모듈 1에서 다룬 모델과의 상호작용까지 정리해보았습니다.&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;다음 글에서는 모듈 2를 이어서,&lt;br /&gt;LiteLLM 게이트웨이와 Langfuse 관측성을 중심으로&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;관련하여 더 자세한 내용이 궁금하시다면,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/aws-samples/sample-genai-on-eks-starter-kit&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/aws-samples/sample-genai-on-eks-starter-kit&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1785602346787&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - aws-samples/sample-genai-on-eks-starter-kit: A comprehensive toolkit for deploying production-ready Generative AI infra&quot; data-og-description=&quot;A comprehensive toolkit for deploying production-ready Generative AI infrastructure on Amazon EKS. Includes pre-configured components for:   AI Gateway (LiteLLM)   LLM Serving (vLLM, SGLang, Ollam...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/aws-samples/sample-genai-on-eks-starter-kit&quot; data-og-url=&quot;https://github.com/aws-samples/sample-genai-on-eks-starter-kit&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dwBML3/dJMb9ia5y4C/E2xLBZRh6odm5fj1gDkn91/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/fRbqk/dJMb9gxzZQC/WIQXThXKhAX5j1o7P7CLf1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/aws-samples/sample-genai-on-eks-starter-kit&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/aws-samples/sample-genai-on-eks-starter-kit&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dwBML3/dJMb9ia5y4C/E2xLBZRh6odm5fj1gDkn91/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/fRbqk/dJMb9gxzZQC/WIQXThXKhAX5j1o7P7CLf1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&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;GitHub - aws-samples/sample-genai-on-eks-starter-kit: A comprehensive toolkit for deploying production-ready Generative AI infra&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A comprehensive toolkit for deploying production-ready Generative AI infrastructure on Amazon EKS. Includes pre-configured components for:   AI Gateway (LiteLLM)   LLM Serving (vLLM, SGLang, Ollam...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.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;</description>
      <category>DevOps</category>
      <author>frontheadlock</author>
      <guid isPermaLink="true">https://frontheadlock.tistory.com/18</guid>
      <comments>https://frontheadlock.tistory.com/18#entry18comment</comments>
      <pubDate>Sun, 2 Aug 2026 01:40:08 +0900</pubDate>
    </item>
    <item>
      <title>LDAP 알아보기</title>
      <link>https://frontheadlock.tistory.com/17</link>
      <description>&lt;h3 data-heading=&quot;LDAP란?&quot; data-ke-size=&quot;size23&quot;&gt;LDAP란?&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1402&quot; data-origin-height=&quot;1122&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k5BoN/dJMcaasxbwh/F6PPwyvOjRCow3dE5jaSvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k5BoN/dJMcaasxbwh/F6PPwyvOjRCow3dE5jaSvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k5BoN/dJMcaasxbwh/F6PPwyvOjRCow3dE5jaSvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk5BoN%2FdJMcaasxbwh%2FF6PPwyvOjRCow3dE5jaSvk%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;704&quot; height=&quot;563&quot; data-origin-width=&quot;1402&quot; data-origin-height=&quot;1122&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;LDAP란?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;LDAP(Lightweight Directory Access Protocol)는 디렉토리 서비스를 제공하기 위한 프로토콜&lt;br /&gt;네트워크상에서 조직이나 개인, 파일, 디바이스 등을 쉽게 조회할 수 있도록 해줍니다.&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;출처 : 삼성 SDS 블로그&lt;/span&gt;&lt;/p&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;우선 LDAP를 이해하기 위해서는 &quot;디렉터리 서비스&quot;에 대한 이해가 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디렉터리 서비스는 사람, 그룹, 장비, 계정 같은 개체의 속성 정보를 계층적으로 저장하고,&lt;br /&gt;조회와 인증에 최적화된 특수 목적의 데이터 저장소입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 말하면, 디렉터리 서비스란 일종의 조직도와 같습니다.&lt;br /&gt;읽기(조회, 인증)가 압도적으로 많고, 쓰기(사용자 추가, 수정)는 드물다는 가정 위에서 만들어졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서, 일반적으로 사용되는 RDB와의 차이가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흔히 사용되는 MySQL 같은 RDB와 디렉터리 서비스는 목적 자체가 다릅니다.&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;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YxVzh/dJMcafHoFfJ/KkeQtGcibpCPAXsG2SWQwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YxVzh/dJMcafHoFfJ/KkeQtGcibpCPAXsG2SWQwk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YxVzh/dJMcafHoFfJ/KkeQtGcibpCPAXsG2SWQwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYxVzh%2FdJMcafHoFfJ%2FKkeQtGcibpCPAXsG2SWQwk%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;792&quot; height=&quot;528&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&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;ul style=&quot;list-style-type: disc;&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;RDB : 정규화된 테이블과 조인으로 관계 표현&lt;/li&gt;
&lt;li&gt;DS : 하나의 계층 트리에 데이터를 배치&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;RDB : 복잡한 트랜잭션이나 조인, 즉시 정합성 등을 이뤄냄&lt;/li&gt;
&lt;li&gt;DS : 읽기 중심으로, 복제를 이용해 읽기 부하 분산&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;RDB : 애플리케이션들마다 제각각&lt;/li&gt;
&lt;li&gt;DS : objectClass와 속성이 표준화되어 서로 다른 시스템이 같은 cn, mail, uid 공유&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LDAP는 디렉터리 서비스라고 하지만, 실제로는 프로토콜입니다.&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;디렉터리 서비스의 표준 모델로 자리 잡은 X.500에 대해,&lt;br /&gt;X.500 디렉터리에 접근하기 위한 프로토콜이 DAP(Directory Access Protocol)였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DAP는 무거운 OSI 프로토콜 스택 전체를 요구하며, 사용에 있어 부담이 생길 수밖에 없었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 극복하기 위해 나온 것이 LDAP로, Lightweight가 붙은 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;다만, 이름에 Lightweight가 붙어 데이터도 가벼운? 줄 알지만,&lt;br /&gt;데이터가 가볍거나 작다는 것이 아니라,&lt;br /&gt;OSI 스택 전체를 요구하던 DAP 대비 프로토콜과 구현이 가볍다는 의미입니다.&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;또한 TCP 389번 포트 하나로 접속한다는 점에 차이가 있습니다.&lt;br /&gt;(평문으로 관리하기엔 어려움이 있어, TLS로 감싸는 636(LDAPS)또는 StartTLS로 암호화합니다.)&lt;/p&gt;
&lt;h3 data-heading=&quot;LDAP의 데이터 모델&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-heading=&quot;LDAP의 데이터 모델&quot; data-ke-size=&quot;size23&quot;&gt;LDAP의 데이터 모델&lt;/h3&gt;
&lt;h4 data-heading=&quot;트리&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-heading=&quot;트리&quot; data-ke-size=&quot;size20&quot;&gt;트리&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1402&quot; data-origin-height=&quot;1122&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oPluU/dJMcadCCH0w/HiptPCNkBqwUsa6X5nQZj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oPluU/dJMcadCCH0w/HiptPCNkBqwUsa6X5nQZj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oPluU/dJMcadCCH0w/HiptPCNkBqwUsa6X5nQZj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoPluU%2FdJMcadCCH0w%2FHiptPCNkBqwUsa6X5nQZj0%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;744&quot; height=&quot;595&quot; data-origin-width=&quot;1402&quot; data-origin-height=&quot;1122&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;앞서 LDAP는 트리를 이용해 데이터를 담는다고 하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 트리는 DIT (Directory Information Tree)라 부릅니다.&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;DIT 내 최소 단위는 Entry로,&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;그리고 이러한 엔트리는 DN(Distinguished Name)으로 트리 내에서 유일하게 식별됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DN을 이해하는 가장 좋은 비유는 파일 시스템의 절대 경로입니다.&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;uid=hong,ou=people,dc=lab,dc=example,dc=com
&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;DN을 분해하면 이렇게 됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;uid=hong : 같은 부모 밑 형제들 사이에서만 유일하면 되는 이름.&lt;/li&gt;
&lt;li&gt;ou=people : 부모 컨테이너(organizationalUnit, 부서/그룹 같은 계층).&lt;/li&gt;
&lt;li&gt;dc=lab,dc=example,dc=com : 트리의 뿌리(base DN).&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DN에 자주 등장하는 약어들은 각각 계층과 용도가 다릅니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;dc : domainComponent. 도메인을 조각낸 것, 보통 트리 뿌리를 짓는 데 씁니다.&lt;/li&gt;
&lt;li&gt;ou : organizationalUnit. 부서나 그룹 같은 컨테이너 계층.&lt;/li&gt;
&lt;li&gt;cn : commonName. 표시 이름(사람, 그룹 모두 사용).&lt;/li&gt;
&lt;li&gt;uid : userID. 로그인 아이디.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-heading=&quot;objectClass&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-heading=&quot;objectClass&quot; data-ke-size=&quot;size20&quot;&gt;objectClass&lt;/h4&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;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4ogog/dJMcaa699bg/kp679t9BLJgXUencV8IdQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4ogog/dJMcaa699bg/kp679t9BLJgXUencV8IdQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4ogog/dJMcaa699bg/kp679t9BLJgXUencV8IdQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4ogog%2FdJMcaa699bg%2Fkp679t9BLJgXUencV8IdQ1%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;774&quot; height=&quot;516&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&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;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;objectClass란?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;objectClass는 엔트리의 종류를 규정하고, 어떤 속성이 필수/선택인지 정하는 스키마 요소입니다.&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;출처 : RFC 4512&lt;/span&gt;&lt;/p&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;objectClass는 엔트리가 사람인지 그룹인지 결정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;objectClass는 일종의 폼 템플릿으로,&lt;br /&gt;엔트리에 inetOrgPerson 폼을 붙이면 이름칸(cn, sn)은 필수가 되고 메일칸은 선택이 됩니다.&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;이러한 objectClass는 STRUCTURAL, AUXILIARY, ABSTRACT(top)로 나뉩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 중 실무에서는 주로 STRUCTURAL과 AUXILIARY을 사용합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;STRUCTURAL
&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;AUXILIARY
&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;posixAccount가 대표적인 예시&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 구성된 엔트리들을 텍스트로 표현하는 표준 포맷이 LDIF입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;LDIF는 서버 간 데이터를 가져오고 내보내거나 변경을 기술할 때 사용됩니다.&lt;br /&gt;dn:으로 시작해 '속성: 값' 줄이 이어지고, 빈 줄로 레코드를 구분합니다.&lt;/p&gt;
&lt;pre class=&quot;ldif&quot;&gt;&lt;code&gt;dn: uid=hong,ou=people,dc=lab,dc=example,dc=com
objectClass: top
objectClass: inetOrgPerson
cn: Gildong Hong
sn: Hong
uid: hong
mail: hong@lab.example.com
&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;ldapsearch 를 사용할 경우, 스크립트를 활용해 ldap 내 조회를 더 쉽게 가져갈 수도 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1784124206701&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;LDAP_URI=&quot;ldapIP&quot;
DN=&quot;$1&quot;

if ldapsearch -x -H &quot;$LDAP_URI&quot; -b &quot;$DN&quot; -s base dn &amp;amp;&amp;gt; /dev/null; then
    echo &quot;[OK] 존재하는 DN: $DN&quot;
else
    echo &quot;[NO] 없는 DN: $DN&quot;
fi&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;LDAP 활용&quot; data-ke-size=&quot;size23&quot;&gt;LDAP 활용&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;이러한 LDAP는 특정 회사의 제품이 아니라, IETF의 RFC로 정의된 개방형 프로토콜입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자는 LDAP라는 프로그램을 설치하는 것이 아니라,&lt;br /&gt;LDAP라는 프로토콜(규칙)을 구현한 구현체를 설치해 사용하는 것입니다.&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;LDAP의 구현체에는 다음과 같은 프로그램이 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;OpenLDAP&lt;/li&gt;
&lt;li&gt;Microsoft Active Directory&lt;/li&gt;
&lt;li&gt;389 Directory Server&lt;/li&gt;
&lt;li&gt;Apache DS&lt;/li&gt;
&lt;li&gt;Red Hat Directory Server&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이들은 모두 LDAP 프로토콜을 구현한 서로 다른 제품으로,&lt;br /&gt;LDAP 자체는 표준 문서로서 벤더에 종속되지 않고 ldapsearch 같은 클라이언트로 접근이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;389DS&quot; data-ke-size=&quot;size23&quot;&gt;389DS&lt;/h3&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;750&quot; data-origin-height=&quot;530&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RWsSg/dJMcahZp7fw/4kYmSq3NiMP9CpOEPReWq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RWsSg/dJMcahZp7fw/4kYmSq3NiMP9CpOEPReWq1/img.png&quot; data-alt=&quot;389DS&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RWsSg/dJMcahZp7fw/4kYmSq3NiMP9CpOEPReWq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRWsSg%2FdJMcahZp7fw%2F4kYmSq3NiMP9CpOEPReWq1%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;723&quot; height=&quot;511&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;530&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;389DS&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 data-ke-size=&quot;size16&quot;&gt;사내에서는 389를 이용해 LDAP를 관리하고 있습니다.&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;사실 그동안 써 온 AD도 내부적으로는 LDAP(과 Kerberos)로 동작하는 디렉터리 서버입니다.&lt;br /&gt;다만 스키마와 관리 방식이 Windows에 강하게 묶여 있을 뿐이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 LDAP 구현체임에도, 사내에서 389 DS를 택한 데에는 Linux라는 장벽이 있었습니다.&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;Linux는 user를 모두 숫자(uidNumber, gidNumber)로 알아보는데,&lt;br /&gt;Windows AD는 사람을 SID로 알아보는 문제가 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;같은 사용자를 두 OS가 서로 다른 방식으로 식별하고 있던 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Linux가 사용자를 로그인시키려면 다음 값들이 필요합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;uidNumber : 숫자 사용자 ID&lt;/li&gt;
&lt;li&gt;gidNumber : 기본 그룹 ID&lt;/li&gt;
&lt;li&gt;homeDirectory : 홈 디렉터리 경로&lt;/li&gt;
&lt;li&gt;loginShell : 로그인 셸&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Windows AD는 사용자에게 SID, samAccountName은 주지만, POSIX를 쓰지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이를 극복하고자 사용하던 것이 SFU였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SFU는 AD 사용자에 uidNum, gidNum 같은 POSIX 속성을 붙여주고,&lt;br /&gt;이를 NIS처럼 배포해 UNIX가 AD 계정을 인식하도록 해줍니다.&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;이러한 SFU를 MS에서 deprecate하며, 내부적으로 Linux 환경 유저들에 한해 AD에서 분리하게 된 것입니다.&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;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 389 DS를 세웠다고 해서 리눅스가 알아서 계정을 봐주지는 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;연동을 담당하는 클라이언트 패키지도 하나가 아니라, 세대별로 나뉘어 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;nslcd : LDAP 조회와 인증만 담당하는 가볍고 단순한 데몬 (nss-pam-ldapd 패키지)&lt;/li&gt;
&lt;li&gt;nscd : 엄밀히는 LDAP 클라이언트가 아니라, 조회 결과를 캐시해주는 보조 데몬&lt;/li&gt;
&lt;li&gt;sssd : 조회에 캐싱, 오프라인 로그인, 접근 제어까지 묶은 현대적 기본값&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;이름이 다 비슷하게 생겨서 헷갈려요..&lt;/s&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;nslcd를 쓸 경우 PAM 계층의 pam_access로 관리자와 그룹의 접근 권한을 제어하지만,&lt;br /&gt;sssd를 쓸 경우 LDAP 연결, TLS, 캐시, 접근 제어까지 sssd.conf 한 파일로 수정점이 집약됩니다.&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;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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-heading=&quot;마무리&quot; data-ke-size=&quot;size20&quot;&gt;마무리&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;236&quot; data-origin-height=&quot;173&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/erjZ6I/dJMcafHoFfw/hMOHkRXkry8UYK6zkt9vY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/erjZ6I/dJMcafHoFfw/hMOHkRXkry8UYK6zkt9vY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/erjZ6I/dJMcafHoFfw/hMOHkRXkry8UYK6zkt9vY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FerjZ6I%2FdJMcafHoFfw%2FhMOHkRXkry8UYK6zkt9vY0%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;301&quot; height=&quot;221&quot; data-origin-width=&quot;236&quot; data-origin-height=&quot;173&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;입사 후 LDAP를 맡아 열심히 적응하는 중이지만,&lt;br /&gt;팀은 기존에 사용하던 389 DS에서 FreeIPA로의 전환을 검토 중입니다.&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;순수 LDAP은 '디렉터리', 즉 신원을 저장하고 조회하는 계층까지만 주기에,&lt;br /&gt;Kerberos 기반 SSO, HBAC, 중앙 sudo 규칙 같은 것들을 관리자가 직접 관리해야합니다.&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;하지만, FreeIPA는 이를 미리 묶어, ipa라는 단일 인터페이스로 관리하게 해줍니다.&lt;br /&gt;&lt;s&gt;(FreeIPA 야호 ..!)&lt;/s&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;다만 이런 FreeIPA도 결국은 LDAP을 활용합니다.&lt;br /&gt;FreeIPA의 디렉터리 백엔드가 바로 389 DS이기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 FreeIPA로 넘어가는 것은 LDAP을 버리는 것이 아니라, LDAP 위에 관리 계층을 얹는 것에 가깝습니다.&lt;br /&gt;앞서 'AD도 결국은 LDAP'라고 했는데, FreeIPA도 열어보면 심장은 389 DS인 셈이죠.&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;정리하면 LDAP은 특정 제품이 아니라,&lt;br /&gt;X.500에 뿌리를 둔 디렉터리 서비스에 TCP/IP로 접근하기 위한 경량 프로토콜입니다.&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;디렉터리는 트리(DIT)에 엔트리를 담아 DN으로 식별하고, objectClass로 종류와 속성을 규정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 그 위에서 389 DS 같은 구현체, SSSD 같은 클라이언트, TLS 같은 보안 장치가 실제 운영을 만듭니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AD든 FreeIPA든, 속을 열어보면 결국 LDAP이 있습니다.&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;팀은 FreeIPA로 넘어가지만, LDAP에 대한 공부가 헛수고가 아닐 것이라 믿습니다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <author>frontheadlock</author>
      <guid isPermaLink="true">https://frontheadlock.tistory.com/17</guid>
      <comments>https://frontheadlock.tistory.com/17#entry17comment</comments>
      <pubDate>Wed, 15 Jul 2026 23:16:20 +0900</pubDate>
    </item>
    <item>
      <title>요즘 개발자</title>
      <link>https://frontheadlock.tistory.com/16</link>
      <description>&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;1402&quot; data-origin-height=&quot;1486&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dl3tsB/dJMcag6CJWR/jcmHwShuBTjW6lowJF00n1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dl3tsB/dJMcag6CJWR/jcmHwShuBTjW6lowJF00n1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dl3tsB/dJMcag6CJWR/jcmHwShuBTjW6lowJF00n1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdl3tsB%2FdJMcag6CJWR%2FjcmHwShuBTjW6lowJF00n1%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;592&quot; height=&quot;627&quot; data-origin-width=&quot;1402&quot; data-origin-height=&quot;1486&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;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;요즘 개발자&lt;/span&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;/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;1426&quot; data-origin-height=&quot;1284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2pDPf/dJMcafs6u8x/KqwDcSfWcHBtti5m8ZMPk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2pDPf/dJMcafs6u8x/KqwDcSfWcHBtti5m8ZMPk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2pDPf/dJMcafs6u8x/KqwDcSfWcHBtti5m8ZMPk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc2pDPf%2FdJMcafs6u8x%2FKqwDcSfWcHBtti5m8ZMPk1%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;432&quot; height=&quot;389&quot; data-origin-width=&quot;1426&quot; data-origin-height=&quot;1284&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;제목부터 뭔가 MZ 개발자인 나와 딱 어울리는 책인 것 같아 보자마자 읽어보게 되었다.&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;/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;책을 읽으면서 생각보다 많은 고민을 해볼 수 있었다.&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;1. 소프트웨어 장인 정신을 갖는 개발자&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2. 회사가 정의하는 개발자&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;3. 내가 정의하는 개발자&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;개인적으로 3가지 모두 중요한 것 같다고 느꼈다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;개발자는 직업에 맞게 내가 만드는 것들에 대해 높은 수준의 완성도를 가지는 것도 중요하고,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;동시에 회사원으로써 회사의 문제를 해결하고 비전을 가져다주며,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;최종적으로 한 명의 인간으로써 내가 이 직업으로 어떤 가치를 실현하고 싶은지 알아야 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;처음 개발자라는 직업을 선택했던 이유는 단순했다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;코드를 통해 내가 무언가를 만들어내는게 즐거워서였다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;내가 만들어낸 작업물들로 큰 가치를 창출해본 경험은 없지만,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;주변인들로부터 해당 작업물에 대해 멋있다는 소리를 들을 때면 알게 모르게 뽕이 찼고,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;산출물을 만들어 나가며 동료들과 협업하는 그 과정 자체가 너무 즐거웠다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;물론 아직 내가 어떤 개발자가 되고 싶은지 명확하게 알고 있지는 못한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&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;살아남기 위해서는 '나'라는 사람을 팔 수 있어야 한다는 것이다.&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;/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;/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;/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;나도 그들처럼 언젠가는 타인에게 도움이 될 수 있는 사람으로 성장하고싶다.&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;/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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1120&quot; data-origin-height=&quot;888&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xk24i/dJMcagr0776/HtJpkh1Cz0E6fv9WCMTsp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xk24i/dJMcagr0776/HtJpkh1Cz0E6fv9WCMTsp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xk24i/dJMcagr0776/HtJpkh1Cz0E6fv9WCMTsp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxk24i%2FdJMcagr0776%2FHtJpkh1Cz0E6fv9WCMTsp1%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;493&quot; height=&quot;391&quot; data-origin-width=&quot;1120&quot; data-origin-height=&quot;888&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로도 기록하고, 회고하며 나의 길을 정립해 나가,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; 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;</description>
      <category>생각</category>
      <author>frontheadlock</author>
      <guid isPermaLink="true">https://frontheadlock.tistory.com/16</guid>
      <comments>https://frontheadlock.tistory.com/16#entry16comment</comments>
      <pubDate>Mon, 18 May 2026 22:36:10 +0900</pubDate>
    </item>
    <item>
      <title>OpenStack 시작 전에 알아 볼 컨테이너 이야기</title>
      <link>https://frontheadlock.tistory.com/15</link>
      <description>&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;323&quot; data-origin-height=&quot;156&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNkNod/dJMcagFwf7e/MeQGaAnnV1oignWUl68P31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNkNod/dJMcagFwf7e/MeQGaAnnV1oignWUl68P31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNkNod/dJMcagFwf7e/MeQGaAnnV1oignWUl68P31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNkNod%2FdJMcagFwf7e%2FMeQGaAnnV1oignWUl68P31%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;489&quot; height=&quot;236&quot; data-origin-width=&quot;323&quot; data-origin-height=&quot;156&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;OpenStack을 이해하기 위해서는 컨테이너를 함께 이해해야 합니다.&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;OpenStack을 배포하는 데에는 컨테이너가 사용되고,&lt;br /&gt;OpenInfra Foundation 내에서도 컨테이너와 관련된 기술이 계속 중요해지고 있습니다.&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-heading=&quot;초기 컴퓨팅 환경&quot; data-ke-size=&quot;size23&quot;&gt;초기 컴퓨팅 환경&lt;/h3&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;1055&quot; data-origin-height=&quot;1491&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cYSjP3/dJMcah5uddL/TbCE2y84ZtLymozcMxtG0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cYSjP3/dJMcah5uddL/TbCE2y84ZtLymozcMxtG0k/img.png&quot; data-alt=&quot;배치처리 vs 시분할처리&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cYSjP3/dJMcah5uddL/TbCE2y84ZtLymozcMxtG0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcYSjP3%2FdJMcah5uddL%2FTbCE2y84ZtLymozcMxtG0k%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;574&quot; height=&quot;811&quot; data-origin-width=&quot;1055&quot; data-origin-height=&quot;1491&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;배치처리 vs 시분할처리&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 data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너의 개념은 VM이 대중화되기 이전부터 존재했습니다.&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;이 시기에는 배치 처리를 중심으로 컴퓨팅 처리를 진행하였습니다.&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;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;이 시기에는 안정성을 위해 하나의 서버에서 하나의 어플리케이션만을 실행했었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;이러한 흐름 속에서 시분할 처리의 개념이 도입되기 시작했습니다.&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;시분할 처리는 CPU 시간을 아주 작은 단위로 쪼개 여러 프로세스에 차례대로 할당하여,&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;/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;/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;1960년대 중반 IBM은 CP-40 / CP-67 계열 시스템에서,&lt;br /&gt;하드웨어 전체를 가상으로 복제하는 기술을 만들었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;사용자에게 완전히 독립된 형태의 가상 컴퓨터를 제공하는 최초의 VM 개념이 처음으로 등장한 것입니다.&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;다만, 이 시기의 VM은 CPU 등을 포함한 많은 요소가 소프트웨어적으로 에뮬레이션되는 방식이었습니다.&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-heading=&quot;메인프레임에서 x86 서버로&quot; data-ke-size=&quot;size23&quot;&gt;메인프레임에서 x86 서버로&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;이전까지 서버 환경은 메인프레임 시대였습니다.&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;1990년대 후반과 2000년대 초반 닷컴 버블과 인터넷 보급으로,&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;메인프레임에서는 IBM이 제공하는 가상화 기술이 있었으나,&lt;br /&gt;x86 기반 저비용 서버 환경에서는 같은 수준의 가상화 기술이 없었습니다.&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;x86 서버는 메인프레임과 비교하여 값이 저렴하더라도 가상화 기술의 부재로,&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;하지만 VMware가 VMware ESXi, VMware Workstation 같은 솔루션으로,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x86 서버에서 사용 가능한 제품들을 만들며 x86 서버에서의 가상화를 이뤄냈습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이로 인해, 사용자들은 물리 자원의 사용량을 극대화할 수 있게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 호스트의 운영체제에 상관없이 게스트 OS로 다양한 OS를 올릴 수 있게 되며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대폭의 비용 절감으로 인한 x86 서버 시장의 확대로 이어졌습니다.&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;기업들은 인텔 기반 CPU를 사용하는 저비용 서버를 IT 인프라로 도입하기 시작했고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UNIX 기반의 서버에서 Linux 로 변화가 이뤄졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;x86의 유래&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;x86 서버는 Intel CPU 모델 명에서 비롯되었습니다.&lt;br /&gt;Intel CPU 모델 명이 80386, 80486 .. 처럼 86으로 끝났기 때문에,&lt;br /&gt;이 계열 CPU를 사용하는 서버를 x86 서버라고 불렀습니다.&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-heading=&quot;VM의 한계와 컨테이너적 사고&quot; data-ke-size=&quot;size23&quot;&gt;VM의 한계와 컨테이너적 사고&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;가상 머신은 강력한 격리를 제공하지만 무겁습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;starting time이 오래 걸리고, OS 전체를 포함해야 합니다.&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;br /&gt;누군가 시스템 파일을 깨뜨리거나 의존성을 파괴하기에, 영향을 주는 것을 막길 원한 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해 어플리케이션과 그 의존성, 시스템 lib, fsystem,network 등 프로세스 단위로 격리하고자,&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;h3 data-heading=&quot;chroot&quot; data-ke-size=&quot;size23&quot;&gt;chroot&lt;/h3&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;1122&quot; data-origin-height=&quot;1402&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKIJ5n/dJMcacb0U3T/OsqgIGscwB6xjFye3arSI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKIJ5n/dJMcacb0U3T/OsqgIGscwB6xjFye3arSI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKIJ5n/dJMcacb0U3T/OsqgIGscwB6xjFye3arSI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKIJ5n%2FdJMcacb0U3T%2FOsqgIGscwB6xjFye3arSI0%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;659&quot; height=&quot;823&quot; data-origin-width=&quot;1122&quot; data-origin-height=&quot;1402&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;컨테이너를 만드는 기술의 핵심은 1979년의 chroot 기술로 볼 수 있습니다.&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;chroot는 격리된 루트 파일 시스템을 제공합니다.&lt;br /&gt;특정 사용자나 프로세스에게 실제가 아닌 별도의 루트 파일 시스템을 보여줘,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;사용자가 shell을 얻어 접속하더라도, 사용자가 보는 환경을 제한할 수 있어졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker Container 안으로 shell 접속을 하면, 해당 컨테이너 만의 파일 시스템이 보이게 됩니다.&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;이는 호스트가 완전히 격리되어 있기에 가능한 것으로, Docker 만의 격리된 파일 시스템인 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;chroot는 파일 시스템 격리에 초점이 맞춰져 있습니다.&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;FreeBSD는 Jail을 만들게 되었습니다.&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;OpenStack , K8s 모두 이와 동일한 것으로 존재하는 기술들을 잘 엮어 하나의 플랫폼으로 포장한 것입니다.&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-heading=&quot;cgroups , namespaces&quot; data-ke-size=&quot;size23&quot;&gt;cgroups , namespaces&lt;/h3&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;1122&quot; data-origin-height=&quot;1402&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k46cD/dJMcaakXgBV/6DrylnAqGfKbKCbu2wGV20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k46cD/dJMcaakXgBV/6DrylnAqGfKbKCbu2wGV20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k46cD/dJMcaakXgBV/6DrylnAqGfKbKCbu2wGV20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk46cD%2FdJMcaakXgBV%2F6DrylnAqGfKbKCbu2wGV20%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;1122&quot; height=&quot;1402&quot; data-origin-width=&quot;1122&quot; data-origin-height=&quot;1402&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;현대 컨테이너의 근간은 cgroups와 namespaces입니다.&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;Linux의 대표적인 기술인 cgroups와 namespaces는 사실 구글에서 만든 기술로,&lt;br /&gt;2006년도 구글에서 진행한 process containers 프로젝트에서 비롯되었습니다.&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;해당 프로젝트에서는 프로세스의 CPU, memory, I/O 같은 리소스 사용량을 제한하며,&lt;br /&gt;여러 기존에 있던 격리 기술들을 활용하는 기술을 개발하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이 과정에서 computerolegroup (cgroup)으로 이름을 바꿔 리눅스 커널을 통합하며, 세상에 나왔습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 noisy neighbor 문제를 해결하기 위한 것으로,&lt;br /&gt;cloud service에서 특정 서비스에 트래픽이 몰려 리소스를 못쓰게 되는 현상을 방지하기 위한 것으로,&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;이로 인해, cgroup을 만들었고, 이를 발전시켜 실행 환경 자체를 격리하는 namespace까지 이어진 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cgroup과 namespace를 기반으로 사용자들은,&lt;br /&gt;PID, 네트워크 스펙, 마운트 지점 등 시스템의 주요 포인트들을 프로세스마다 격리된 시각으로 볼 수 있게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이렇게 만들어진 cgroups 와 namespace가 리눅스 커널에 들어오게 되며 리눅스가 발전하게 됩니다.&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-heading=&quot;LXC의 등장&quot; data-ke-size=&quot;size23&quot;&gt;LXC의 등장&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;LXC는 LinuX Containers의 약자로,&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;cgroups와 namespaces를 통합해 커널 패치 없이 컨테이너를 관리할 수 있게 한 최초의 사용자 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이때까지만 해도 컨테이너는 Linux 시스템을 매우 잘 아는 사람들의 전유물로,&lt;br /&gt;SW 개발자나 이에 관심없는 개발자들은 컨테이너에 대해 알지 못했습니다.&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;br /&gt;namespaces를 만들고, cgroups 설정 및 파일 시스템 준비 후 네트워크를 붙여 어플리케이션을 배포하는 일은&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;Docker의 등장&quot; data-ke-size=&quot;size23&quot;&gt;Docker의 등장&lt;/h3&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;1122&quot; data-origin-height=&quot;1402&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wNe6g/dJMcah5ueCC/zx7cx2D6IVFQFZtXI3ws7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wNe6g/dJMcah5ueCC/zx7cx2D6IVFQFZtXI3ws7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wNe6g/dJMcah5ueCC/zx7cx2D6IVFQFZtXI3ws7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwNe6g%2FdJMcah5ueCC%2Fzx7cx2D6IVFQFZtXI3ws7k%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;564&quot; height=&quot;705&quot; data-origin-width=&quot;1122&quot; data-origin-height=&quot;1402&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;2013년 3월 13일, Docker가 처음 등장하였습니다.&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;Docker는 기존의 Linux 엔지니어만 활용 가능했던 컨테이너 기술을,&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;개발자는 컨테이너 내부에서 cgroups와 namespaces가 어떻게 동작하는지 몰라도,&lt;br /&gt;docker start, docker run 같은 명령으로 컨테이너를 실행시킬 수 있게 되었습니다.&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;특히나, 2010년대 초반 개발자들 사이에서 Agile 방법론이 매우 중요한 키워드로 떠오르던 환경에서,&lt;br /&gt;MSA가 주목받으며 Docker도 함께 주목받게 되었습니다.&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;Docker를 활용하면 서비스를 작게 나눠 각각을 빠르게 배포하고, 교체함에 있어 훨씬 수월해지는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;컨테이너를 빠르게 만들고 실행할 수 있기에 MSA와 Agile 흐름 속에서 더욱 각광받았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DockerFile&lt;/p&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;특히나 Docker가 성공할 수 있었던 가장 큰 이유 중 하나는 Dockerfile 이었습니다.&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;Docker의 이미지는 Layer 구조를 가져,&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;예를 들어, OS와 런타임, 라이브러리 레이어는 그대로 재사용하고,&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;Dockerfile은 실행 환경을 파일로 정의하게 해주었습니다.&lt;br /&gt;이를 통해, 개발자는 어플리케이션이 어떤 환경에서 실행되어야 하는지,&lt;br /&gt;코드처럼 관리할 수 있게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Registry&lt;/p&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;또한, Docker가 대중화될 수 있었던 또 다른 이유는 Registry에 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Registry란 원격 저장소로 GitHub, PyPI, npm과 같은 역할을 수행합니다.&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;과거에는 개발자가 매번 웹 서버, DB , runtime 구성들을 반복해야 했습니다.&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;Registry가 등장하며 다른 사람이 만들어놓은 이미지를 가져와 이를 사용할 수 있게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Registry는 이미지를 공유하고, 재사용하게 만들었고, 컨테이너 생태계 확장에 결정적 역할을 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-heading=&quot;Docker의 한계&quot; data-ke-size=&quot;size23&quot;&gt;Docker의 한계&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;Docker Engine은 croups와 namespaces 같은 Linux 커널 기능을 이용해 컨테이너를 만들고 실행합니다.&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;하지만 Docker는 기본적으로 한 서버 내에서 컨테이너를 실행하고 관리하는 도구입니다.&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;br /&gt;Dokcer만으로는 여러 서버의 컨테이너를 중앙에서 파악하고, 제어하기에 어려움이 있습니다.&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;이를 극복하기 위해 Docker Compose 같은 도구가 등장했지만,&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;서비스가 커지고 컨테이너 개수가 많아지며 이를 해결하기 위한 오케스트레이션 도구의 전쟁이 벌어지게 되었습니다.&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;br /&gt;Apache Mesos, Docker Swarm, Kubernetes가 경쟁했습니다.&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;Google에서 Go를 기반으로 만든 K8s가 오늘날 산업의 표준으로 자리 잡았고,&lt;br /&gt;CNCF로 기부되며 오픈소스 생태계 전략도 K8s 확산에 중요한 역할을 하였습니다.&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;오늘날 OpenStack과 K8s는 분리된 개념이 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;OpenStack은 프라이빗 클라우드의 컴퓨트, 네트워크, 스토리지 기반을 제공하고,&lt;br /&gt;Kubernetes는 그 위에서 컨테이너와 AI 워크로드를 운영합니다.&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;OpenStack 관점에서의 컨테이너&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;컨테이너는 어플리케이션을 가볍게 실행하는 기술만은 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;운영 관점에서 보면 컨테이너는 아래의 기술이 OpenStack과 연결됩니다.&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 style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;OpenStack은 하나의 거대한 프로그램이 아닌,&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Nova, Neutron, Cinder, Glance, Keystone 같은 여러 서비스가 함께 동작하는 분산 시스템입니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;각 서비스는 API 서버, 스케줄러, 에이전트, 데이터베이스, 메시지 큐 등 다양한 컴포넌트와 함께 운영됩니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이런 시스템을 직접 설치하고 관리하기 위해서는 의존성 충돌, 버전 관리, 배포 순서, 장애 복구 같은 문제가 복잡해집니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너는 이 복잡성을 줄이는 데 도움을 줍니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;각 OpenStack 서비스를 컨테이너 이미지로 패키징해,&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;실행 환경을 더 일관되게 유지할 수 있고,&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;배포와 업그레이드도 더 예측 가능해집니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너는 OpenStack 위에서 실행되는 워크로드이기도 하지만,&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;동시에 OpenStack 자체를 배포하고 운영하는 방식에도 깊게 들어와 있습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; 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;517&quot; data-origin-height=&quot;512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GBAZ6/dJMcagyHb3g/ft1hrwnXnYkSk1pQYWkwkk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GBAZ6/dJMcagyHb3g/ft1hrwnXnYkSk1pQYWkwkk/img.jpg&quot; data-alt=&quot;파이팅&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GBAZ6/dJMcagyHb3g/ft1hrwnXnYkSk1pQYWkwkk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGBAZ6%2FdJMcagyHb3g%2Fft1hrwnXnYkSk1pQYWkwkk%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;517&quot; height=&quot;512&quot; data-origin-width=&quot;517&quot; data-origin-height=&quot;512&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;파이팅&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너는 어느 날 갑자기 등장한 기술이 아닙니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 흐름을 이해하면 OpenStack과 Kubernetes의 관계도 더 선명해집니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;OpenStack은 컴퓨트, 네트워크, 스토리지 같은 하부 인프라를 제공합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Kubernetes는 그 위에서 컨테이너화된 애플리케이션과 AI 워크로드를 운영합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너는 OpenStack 위에서 실행되는 대상일 뿐 아니라, OpenStack 자체를 배포하고 운영하는 방식에도 사용됩니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;OpenStack을 이해하기 위해서는 Nova, Neutron, Cinder 같은 컴포넌트와 더불어,&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;현대 인프라가 어떤 문제를 해결하기 위해 가상화로 발전했고,&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다시 컨테이너와 오케스트레이션으로 확장되었는지를 이해해야합니다.&lt;/p&gt;</description>
      <category>OpenStack</category>
      <author>frontheadlock</author>
      <guid isPermaLink="true">https://frontheadlock.tistory.com/15</guid>
      <comments>https://frontheadlock.tistory.com/15#entry15comment</comments>
      <pubDate>Tue, 12 May 2026 18:32:27 +0900</pubDate>
    </item>
    <item>
      <title>OpenStack Client 사용해보기</title>
      <link>https://frontheadlock.tistory.com/14</link>
      <description>&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;openstack.png&quot; data-origin-width=&quot;323&quot; data-origin-height=&quot;156&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ogiFD/dJMb997fIpb/4Jbf7oEbzz6vro9Oc6xA11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ogiFD/dJMb997fIpb/4Jbf7oEbzz6vro9Oc6xA11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ogiFD/dJMb997fIpb/4Jbf7oEbzz6vro9Oc6xA11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FogiFD%2FdJMb997fIpb%2F4Jbf7oEbzz6vro9Oc6xA11%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;474&quot; height=&quot;229&quot; data-filename=&quot;openstack.png&quot; data-origin-width=&quot;323&quot; data-origin-height=&quot;156&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;OpenStack을 사용하는 방법에는 여러가지가 있습니다.&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;OpenStack의 DevStack을 이용해 직접 구축한 후 이를 사용해보거나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;openstack client를 이용해 구축된 환경에 cli 형태로 접근할 수도 있습니다.&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;다만 openstack client는 단독으로 모든 것을 구성해주는 도구는 아니기에,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenStack 환경이 사전에 준비되어 있어야 합니다.&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;저의 경우 이미 사용 가능한 OpenStack 환경을 제공받았기 때문에,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 python-openstackclient를 직접 내려받아 CLI 동작을 확인해보겠습니다.&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;1. Source Code Clone&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 작업을 진행할 디렉토리에 소스코드를 clone 받습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1777271887315&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git clone https://opendev.org/openstack/python-openstackclient&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;br /&gt;실행 흐름을 따라가거나 디버깅할 때도 조금 더 수월하게 볼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;2. clouds.yaml 파일 생성&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenStackClient는 인증 정보를 clouds.yaml 파일로 관리할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1777271966733&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;clouds:
  my-cloud:
    auth:
      # Keystone 인증 엔드포인트 주소
      auth_url: 접속할 원격 서버 url
      username: '접속 유저명'
      password: '비밀번호'
      # 접속 테넌트명
      project_name: '프로젝트명'
      user_domain_name: 'Default'
      project_domain_name: 'Default'
    region_name: 'RegionOne'
    interface: 'public'
    identity_api_version: '3'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;clouds.yaml은 현재 clone 받은 루트 디렉토리에 생성하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 clouds.yaml을 생성해두면,&lt;br /&gt;이후 명령어에서 my-cloud라는 이름으로 해당 OpenStack 환경에 접근할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3. PyCharm을 이용한 venv 생성&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PyCharm을 이용해 python-openstackclient와 tox 등을 실행할 virtualenv를 생성해줍니다&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;1280&quot; data-origin-height=&quot;714&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSpV29/dJMcaffm36V/GMqIfg8q7nhZ9towdUQpv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSpV29/dJMcaffm36V/GMqIfg8q7nhZ9towdUQpv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSpV29/dJMcaffm36V/GMqIfg8q7nhZ9towdUQpv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSpV29%2FdJMcaffm36V%2FGMqIfg8q7nhZ9towdUQpv1%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;530&quot; height=&quot;296&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;714&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;OpenStack의 경우 python3.10 버전과 특히 잘맞아 3.10버전으로 가상환경을 세팅하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;4. 의존 라이브러리 설치&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;python-openstackclient를 실행하기 위해 의존 라이브러리를 virtualenv에 설치합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1777272097565&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 실행용 기본 의존성 설치
python3 -m pip install -r requirements.txt

# 테스트용 기본 의존성 설치
python3 -m pip install -r test-requirements.txt&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;5. python-openstackclient를 develop 모드로 설치하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 virtualenv에 python-openstackclient 자체를 설치합니다.&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;color: #000000;&quot;&gt;일반적으로 파이썬 코드를 받아 설치할 때는 `python &lt;/span&gt;&lt;a href=&quot;http://setup.py&quot;&gt;&lt;span style=&quot;color: #1155cc;&quot;&gt;setup.py&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt; install`을 이용하지만, &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;개발을 위해서는 아래 명령어로 develop 모드로 설치해아 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1777272195199&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python3 setup.py develop&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;6. openstack server list 실행해보기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;python-openstackclient의 진입점은 openstackclient/shell.py에 있습니다.&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;이 파일을 그냥 실행시키면 OpenStack CLI가 구동되므로,&lt;br /&gt;우리는 server list와 같은 인자를 함께 넘겨줘야 합니다.&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;540&quot; data-origin-height=&quot;212&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dbBfAo/dJMcaib40DJ/5x8R2zAvP5tz9NisnoQO3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dbBfAo/dJMcaib40DJ/5x8R2zAvP5tz9NisnoQO3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dbBfAo/dJMcaib40DJ/5x8R2zAvP5tz9NisnoQO3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdbBfAo%2FdJMcaib40DJ%2F5x8R2zAvP5tz9NisnoQO3K%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;451&quot; height=&quot;177&quot; data-origin-width=&quot;540&quot; data-origin-height=&quot;212&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;server list 값을 넣어주기 위해서는 shell.py 실행 이후,&lt;br /&gt;PyCharm에서 제공하는 Edit Configurations를 이용해 스크립트 인자를 넣어줄 수 있습니다.&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;1600&quot; data-origin-height=&quot;1360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lhsB7/dJMcacJHv8v/tVKjHdeunkKHwvxT9n4aDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lhsB7/dJMcacJHv8v/tVKjHdeunkKHwvxT9n4aDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lhsB7/dJMcacJHv8v/tVKjHdeunkKHwvxT9n4aDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlhsB7%2FdJMcacJHv8v%2FtVKjHdeunkKHwvxT9n4aDK%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;536&quot; height=&quot;456&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;1360&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1777272271917&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 서버 목록 조회
# clous.yaml에 정의한 my-cloud 설정 사용
server list --os-cloud my-cloud&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;여기서 --os-cloud my-cloud는 clouds.yaml에 설정한 OpenStack 환경 이름을 의미합니다.&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;간혹 Working Directory의 경로가 openstackclient 폴더까지 잡히는 경우가 있는데,&lt;br /&gt;이럴 때는 프로젝트 루트인 python-openstackclient까지 경로가 잡히도록 수정합니다.&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;이후 shell.py를 실행하면 아래와 같이 터미널에 서버 목록이 출력됩니다.&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;2860&quot; data-origin-height=&quot;1056&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PBASw/dJMcahYvBAg/zBlnzBeYcZWpWMRsIxgKwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PBASw/dJMcahYvBAg/zBlnzBeYcZWpWMRsIxgKwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PBASw/dJMcahYvBAg/zBlnzBeYcZWpWMRsIxgKwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPBASw%2FdJMcahYvBAg%2FzBlnzBeYcZWpWMRsIxgKwK%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;671&quot; height=&quot;248&quot; data-origin-width=&quot;2860&quot; data-origin-height=&quot;1056&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;openstack server list 직접 실행했을 때와 동일한 의미를 가집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;PyCharm에서 소스 기준으로 실행해도,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 우리가 사용하는 OpenStack CLI 동작을 그대로 확인할 수 있다는 뜻입니다.&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ID
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;UUID 형태로 구성된 서버의 고유 식별자입니다.&lt;/li&gt;
&lt;li&gt;OpenStack 내부에서 인스턴스를 구분할 때 사용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Name
&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;Status
&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;예를 들어 ACTIVE, SHUTOFF, ERROR 같은 값으로 확인할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Networks
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버가 연결된 네트워크와 할당된 IP 정보를 보여줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Image
&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;환경에 따라 Ubuntu를 쓰기도 하고, 가벼운 cirros 이미지를 사용하기도 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Flavor
&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;CPU, 메모리, 디스크와 같은 자원 크기를 정의하며, n1.nano는 1 vCPU, 512mb RAM 입니다.&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;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;7. tox 실행해보기&lt;/h4&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;br /&gt;마지막으로 tox를 실행해 현재 소스 기준에서 테스트가 정상적으로 수행되는지도 확인해볼 수 있습니다.&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;tox는 OpenStack 프로젝트에서 자주 사용하는 테스트 실행 도구이므로,&lt;br /&gt;코드를 읽거나 수정해보기에 유용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1777272664934&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# tox 설치
python3 -m pip install tox

# tox 실행
tox&lt;/code&gt;&lt;/pre&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;2860&quot; data-origin-height=&quot;1056&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMbde3/dJMcabYjgdE/jADLIXCE2bVAdnrPVzcre1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMbde3/dJMcabYjgdE/jADLIXCE2bVAdnrPVzcre1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMbde3/dJMcabYjgdE/jADLIXCE2bVAdnrPVzcre1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMbde3%2FdJMcabYjgdE%2FjADLIXCE2bVAdnrPVzcre1%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;627&quot; height=&quot;232&quot; data-origin-width=&quot;2860&quot; data-origin-height=&quot;1056&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;br /&gt;python-openstackclient 소스 코드를 직접 실행하고,&lt;br /&gt;원격 OpenStack 환경에 인증해 실제 CLI 명령이 어떻게 동작하는지 확인할 수 있습니다.&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;즉, 이미 구성된 OpenStack 환경이 있다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;openstackclient는 OpenStack의 동작을 가볍게 확인해보고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소스 수준에서 흐름을 따라가기에 꽤 좋은 출발점이 됩니다.&lt;/p&gt;</description>
      <category>OpenStack</category>
      <author>frontheadlock</author>
      <guid isPermaLink="true">https://frontheadlock.tistory.com/14</guid>
      <comments>https://frontheadlock.tistory.com/14#entry14comment</comments>
      <pubDate>Mon, 27 Apr 2026 16:19:44 +0900</pubDate>
    </item>
  </channel>
</rss>