<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Cloud Newbie's Blog</title>
    <link>https://itmango.tistory.com/</link>
    <description>클라우드라고 적어두었지만 사실상 DevOps, SRE 블로그에 가까운 곳</description>
    <language>ko</language>
    <pubDate>Tue, 16 Jun 2026 21:26:57 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>흑당망고</managingEditor>
    <image>
      <title>Cloud Newbie's Blog</title>
      <url>https://tistory1.daumcdn.net/tistory/5179661/attach/4337d4113049445fb9fa1f25e8e5c32e</url>
      <link>https://itmango.tistory.com</link>
    </image>
    <item>
      <title>【sk_buff란?】 부제: Linux와 K8S에서의 Packet흐름 feat. eBPF</title>
      <link>https://itmango.tistory.com/58</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지난번 AL 2023업그레이드할때 Node.js에서 겪을 수 있는 이슈를 설명하며 Cgroup이라는걸 알아보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Linux 커널에서 동작하는 재밌는 친구였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이번엔 Network 쪽을 알아보자&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;sk_buff란?&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;그게 머에요..?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/include/linux/skbuff.h&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://elixir.bootlin.com/linux/v7.1-rc6/source/include/linux/skbuff.h&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1780485024692&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;skbuff.h - include/linux/skbuff.h -  Linux source code v7.1-rc6 - Bootlin Elixir Cross Referencer&quot; data-og-description=&quot;&quot; data-og-host=&quot;elixir.bootlin.com&quot; data-og-source-url=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/include/linux/skbuff.h&quot; data-og-url=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/include/linux/skbuff.h&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/include/linux/skbuff.h&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/include/linux/skbuff.h&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;skbuff.h - include/linux/skbuff.h - Linux source code v7.1-rc6 - Bootlin Elixir Cross Referencer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;elixir.bootlin.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Linux 커널에서 네트워크 쪽을 컨트롤링할때 일반적으로 우리는 '패킷'이라는 단위를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 이 패킷이라는 것을 표현할때 가장 중요하게 사용되는 요소중 하나인 구조체가 존재하는데 &lt;b&gt;이 친구가 바로 sk_buff다.&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;이 sk_buff라는 친구가 어디서, 왜 사용될까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;rarr; 데이터(네트워크 포함)의 송/수신을 하게 되었을때부터 어플리케이션에 전달할때까지 모두 사용되는 구조체이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 알고 있는 OSI 7Layer로 보면 Layer2 ~ Layer4까지 모두 이 구조체를 통해서 전달을 한다는 의미다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;315&quot; data-origin-height=&quot;337&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3wX4N/dJMcaaetyl5/wXZ81bKZZdvk0CetyDkU7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3wX4N/dJMcaaetyl5/wXZ81bKZZdvk0CetyDkU7k/img.png&quot; data-alt=&quot;여기서 2~4까지 개입한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3wX4N/dJMcaaetyl5/wXZ81bKZZdvk0CetyDkU7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3wX4N%2FdJMcaaetyl5%2FwXZ81bKZZdvk0CetyDkU7k%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;315&quot; height=&quot;337&quot; data-origin-width=&quot;315&quot; data-origin-height=&quot;337&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;여기서 2~4까지 개입한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상식적으로 L1부터 L7까지의 기술이 연결되는건 모두가 알겠지만, 이 sk_buff라는 친구가 유독 특별한데는 이유가 있다.&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 Engineering 적인 측면에서 접근해보면 eBPF와 같은 고-급 기술이 이러한 sk_buff와 연관이 깊다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;eBPF라고 적어두면 긴가민가 할 수 있다. 하지만 이 친구를 예시로 들면 바로 아~ 싶을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 eBPF 기반으로 동작하는 친구중 가장 유명한 친구인 Hot한 CNI Cilium이다.&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;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zhkOy/dJMcah5KSqh/3akv6fstu3yGsQKgolS3M1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zhkOy/dJMcah5KSqh/3akv6fstu3yGsQKgolS3M1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zhkOy/dJMcah5KSqh/3akv6fstu3yGsQKgolS3M1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzhkOy%2FdJMcah5KSqh%2F3akv6fstu3yGsQKgolS3M1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;1024&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;왜 이 Cilium이 Hot하고 OverHead를 줄여주는지는 이번 블로그를 모두 보고나면 알 수 있을 것이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;sk_buff 구조 뜯어보기&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;404&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Lq9VC/dJMcadhXR4w/qcsun9xu95SEDmp8DnVejk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Lq9VC/dJMcadhXR4w/qcsun9xu95SEDmp8DnVejk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Lq9VC/dJMcadhXR4w/qcsun9xu95SEDmp8DnVejk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLq9VC%2FdJMcadhXR4w%2Fqcsun9xu95SEDmp8DnVejk%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;791&quot; height=&quot;404&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;404&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;주의&lt;/h4&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;h4 data-ke-size=&quot;size20&quot;&gt;struct sk_buff&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에는 메타데이터가 적재되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에 적혀있는 포인터 주소가 Head Romm, Data, Tail Room등을 가르킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 sk_buff와는 다른 존재로, 메모리에서도 별도로 관리가 되고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 중요한 내용이므로 여기에 함께 적어두었다.&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;Head Room&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수신할때는 쓰지 않고 &lt;b&gt;송신(TX)할때 사용되는 빈 공간이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패킷는 송신(TX)시 커널이 &lt;a href=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/skbuff.c#L2643&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;skb_push를&lt;/a&gt;&amp;nbsp;호출해 포인터를 뒤로(왼쪽으로) 후진시키며 TCP, IP, MAC 헤더를 차곡차곡 조립시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 해당 데이터들의 내용들이 들어갈 자리가 바로 Head Room이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션(L7)이 &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;아래가 바로 skb_push 함수다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 skb_push함수를 보면 현재 기준으로 뒤에 Head Room 방향으로 칸을 만들어서 Head Room의 일부 공간을 확보한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 헤더가 들어갈 자리가 만들어지게 되고 그때 헤더값을 넣는다.&lt;/p&gt;
&lt;pre id=&quot;code_1780503559843&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void *skb_push(struct sk_buff *skb, unsigned int len)
{
	skb-&amp;gt;data -= len;
	skb-&amp;gt;len  += len;
	if (unlikely(skb-&amp;gt;data &amp;lt; skb-&amp;gt;head))
		skb_under_panic(skb, len, __builtin_return_address(0));
	return skb-&amp;gt;data;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적인 통신에서는 커널이 기본적으로 넉넉하게 잡아두는 &lt;b data-index-in-node=&quot;40&quot; data-path-to-node=&quot;5,1,0&quot;&gt;표준 사이즈의 Head Room&lt;/b&gt;만으로도 포장(TCP/IP/MAC)을 치는 데 아무런 문제가 없지만, K8s CNI나 IPsec VPN처럼 패킷을 겹겹이 이중 삼중으로 포장(Encapsulation)해야 하는 환경에서는 &lt;b data-index-in-node=&quot;162&quot; data-path-to-node=&quot;5,1,0&quot;&gt;기본 Head Room 사이즈를 초과해버릴 수 있으므로 추가적인 아키텍처 고려가 필수적이다.&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Data&lt;/h4&gt;
&lt;p data-path-to-node=&quot;11,1&quot; data-ke-size=&quot;size16&quot;&gt;네트워크 인터페이스 Ring Buffer에 수신된 패킷은 DMA를 통해 커널의 sk_buff 구조체가 가리키는 '선형 Data 영역'에 적재된다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;11,1&quot; data-ke-size=&quot;size16&quot;&gt;이때 적재되는 것은 MAC, IP, TCP 헤더와 실제 데이터(Payload)가 모두 합쳐진 &lt;b data-index-in-node=&quot;144&quot; data-path-to-node=&quot;11,1&quot;&gt;Raw 데이터(Raw Packet)&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 data-path-to-node=&quot;11,2&quot;&gt;커널이 이 거대한 통뼈 데이터에서 헤더를 구분해 내는 원리의 경우 각 프로토콜 헤더의 크기와 특정 필드(N번째 Byte)에 어떤 값이 들어있는지 이미 국제 표준(RFC)으로 엄격하게 협약되어 있어 그리 어려운일은 아니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-path-to-node=&quot;11,2&quot; data-ke-size=&quot;size16&quot;&gt;커널은 데이터를 일일이 복사하거나 파싱하는 대신, 이 약속된 규격에 따라 &lt;a href=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/skbuff.c#L2663&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;skb_pull&lt;/a&gt; 같은 함수로 포인터만 뒤로 이동시키며 포장지(MAC, IP, TCP 헤더)를 차례대로 벗겨낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 모든 릴레이 과정이 끝나고 나면, &lt;b&gt;최종적으로 순수한 Payload만이 남아 어플리케이션으로 전달되게 된다.&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;단, 거대한 페이로드의 경우 메모리 최적화를 위해 Data 영역에 모두 담기지 않고 skb_shared_info를 통해 비선형(Non-linear) 메모리 페이지로 흩어져 관리된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Ring Buffer와 NIC, 그리고 AWS ENA나 K8s CNI 환경에서의 네트워크 인터페이스 동작 과정은 기회가 된다면 다른 포스팅에서 더 깊게 다루어볼 예정이다.&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;Tail Room&lt;/h4&gt;
&lt;p data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;사내망 방화벽과 AWS 클라우드를 VPN(IPsec)으로 연결할 때, 데이터 유출과 변조를 막기 위해 패킷을 암호화하는것은 누구나 아는 사실이다. 하지만 이때 &lt;b&gt;커널은 앞쪽(Head Room)에 ESP 헤더를 붙이는 것뿐만 아니라, 패킷의 맨 뒤(Tail Room)에도 'ESP 트레일러'와 '인증 데이터(ICV)'라는 꼬리표를 반드시 붙여야 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-path-to-node=&quot;5&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;이때 커널은 Tail Room 공간을 사용할 때&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/skbuff.c#L2622&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b data-path-to-node=&quot;6,1&quot; data-index-in-node=&quot;139&quot;&gt;skb_put&lt;/b&gt;&lt;/a&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;a href=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/skbuff.c#L2622&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/a&gt;함수를 호출하여 포인터를 뒤(오른쪽)로 밀어 공간을 확보한다. &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;이때&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b data-path-to-node=&quot;6,1,0&quot; data-index-in-node=&quot;41&quot;&gt;미리 넉넉하게 비워두었던 Tail Room 공간을 파먹으며(사용하며)&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;꼬리표가 들어갈 자리를 확보하는 것이다.&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1780504618374&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void *skb_put(struct sk_buff *skb, unsigned int len)
{
	void *tmp = skb_tail_pointer(skb);
	SKB_LINEAR_ASSERT(skb);
	skb-&amp;gt;tail += len;
	skb-&amp;gt;len  += len;
	if (unlikely(skb-&amp;gt;tail &amp;gt; skb-&amp;gt;end))
		skb_over_panic(skb, len, __builtin_return_address(0));
	return tmp;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-path-to-node=&quot;5&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;5&quot; data-ke-size=&quot;size16&quot;&gt;또한 패킷이 목적지에 도착하기 전, 선을 타고 오는 동안 노이즈 때문에 데이터가 깨지지 않았는지 확인하기 위해 패킷의 맨 끝에Checksum 데이터를 덧붙이는데, 최근에는 네트워크 카드(NIC) 하드웨어가 이 작업을 대신해 주는 경우(Hardware Offloading)가 많지만,&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이더넷 통신에는 &quot;아무리 작은 패킷이라도 전체 크기가 최소 64바이트는 되어야 전송할 수 있다&quot;는 규칙(CSMA/CD 제약)이 있다. 만약 애플리케이션이 보낸 데이터가 너무 작아서 전체 패킷 크기가 &lt;b&gt;64바이트에 미달한다면?&lt;/b&gt; 패킷이 Drop되지는 않는다.&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;b&gt;이런 경우를 대비해 커널은 Tail Room 공간을 파먹으며 남는 공간을 의미 없는 '0'으로 마구 채워 넣는다.&lt;/b&gt; 택배 상자가 너무 헐렁할 때 빈 공간에 뽁뽁이를 채워 넣는 것과 같은 원리라고 보면 된다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;skb_shared_info&lt;/h4&gt;
&lt;p data-path-to-node=&quot;10,1&quot; data-ke-size=&quot;size16&quot;&gt;만약 페이로드 자체가 수십 KB 단위로 매우 크다면 어떨까?&lt;/p&gt;
&lt;p data-path-to-node=&quot;10,1&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;커널은 이 거대한 데이터를 제한된 크기의 메인 선형 버퍼(Data 영역)에 꾸역꾸역 밀어 넣는 바보 같은 짓을 하지 않는다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-path-to-node=&quot;10,1&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;10,2&quot; data-ke-size=&quot;size16&quot;&gt;덩치가 큰 데이터를 담기 위해 커널 메모리에서 '거대하고 연속된 빈 공간'을 찾는 것은 메모리 단편화를 유발하고 심각한 성능 저하를 가져오기 때문이다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;10,2&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;10,3&quot; data-ke-size=&quot;size16&quot;&gt;대신 커널은 'Scatter-Gather'라는 고도의 전략을 사용한다. 거대한 페이로드는 커널의 남는 메모리 페이지(Page) 공간에 조각조각 흩어두고(Scatter), 메인 버퍼 꼬리에 위치한 skb_shared_info라는 구조체 명부에 &quot;이 데이터 조각들은 저기 메모리 주소들에 흩어져 있어&quot;라고 포인터만 기록해 두는 것이다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;10,3&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;10,4&quot; data-ke-size=&quot;size16&quot;&gt;이후 패킷이 네트워크 카드(NIC)로 전송될 때, 랜카드가 이 명부만 보고 흩어진 조각들을 직접 긁어모아(Gather) 선으로 쏴버린다. 데이터 복사를 시도조차 하지 않고 처리를 할 수 있는 효율적인 방법이라 생각되는 포인트이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;L1 ~ L2&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L6454&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L6454&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1780485456161&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;dev.c - net/core/dev.c -  Linux source code v7.1-rc6 - Bootlin Elixir Cross Referencer&quot; data-og-description=&quot;&quot; data-og-host=&quot;elixir.bootlin.com&quot; data-og-source-url=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L6454&quot; data-og-url=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L6454&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L6454&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L6454&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;dev.c - net/core/dev.c - Linux source code v7.1-rc6 - Bootlin Elixir Cross Referencer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;elixir.bootlin.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;L1에서 L2까지의 흐름은 다음과 같다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;RX (수신)일때&lt;/h4&gt;
&lt;pre class=&quot;reasonml&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;static __latent_entropy void net_rx_action(void)
{
	struct softnet_data *sd = this_cpu_ptr(&amp;amp;softnet_data);
	unsigned long time_limit = jiffies +
		usecs_to_jiffies(READ_ONCE(net_hotdata.netdev_budget_usecs));
	struct bpf_net_context __bpf_net_ctx, *bpf_net_ctx;
	int budget = READ_ONCE(net_hotdata.netdev_budget);
	LIST_HEAD(list);
	LIST_HEAD(repoll);

	bpf_net_ctx = bpf_net_ctx_set(&amp;amp;__bpf_net_ctx);
start:
	sd-&amp;gt;in_net_rx_action = true;
	local_irq_disable();
	list_splice_init(&amp;amp;sd-&amp;gt;poll_list, &amp;amp;list);
	local_irq_enable();

	for (;;) {
		struct napi_struct *n;

		skb_defer_free_flush();

		if (list_empty(&amp;amp;list)) {
			if (list_empty(&amp;amp;repoll)) {
				sd-&amp;gt;in_net_rx_action = false;
				barrier();
				/* We need to check if ____napi_schedule()
				 * had refilled poll_list while
				 * sd-&amp;gt;in_net_rx_action was true.
				 */
				if (!list_empty(&amp;amp;sd-&amp;gt;poll_list))
					goto start;
				if (!sd_has_rps_ipi_waiting(sd))
					goto end;
			}
			break;
		}

		n = list_first_entry(&amp;amp;list, struct napi_struct, poll_list);
		budget -= napi_poll(n, &amp;amp;repoll);

		/* If softirq window is exhausted then punt.
		 * Allow this to run for 2 jiffies since which will allow
		 * an average latency of 1.5/HZ.
		 */
		if (unlikely(budget &amp;lt;= 0 ||
			     time_after_eq(jiffies, time_limit))) {
			/* Pairs with READ_ONCE() in softnet_seq_show() */
			WRITE_ONCE(sd-&amp;gt;time_squeeze, sd-&amp;gt;time_squeeze + 1);
			break;
		}
	}

	local_irq_disable();

	list_splice_tail_init(&amp;amp;sd-&amp;gt;poll_list, &amp;amp;list);
	list_splice_tail(&amp;amp;repoll, &amp;amp;list);
	list_splice(&amp;amp;list, &amp;amp;sd-&amp;gt;poll_list);
	if (!list_empty(&amp;amp;sd-&amp;gt;poll_list))
		__raise_softirq_irqoff(NET_RX_SOFTIRQ);
	else
		sd-&amp;gt;in_net_rx_action = false;

	net_rps_action_and_irq_enable(sd);
end:
	bpf_net_ctx_clear(bpf_net_ctx);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L7914&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L7914&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781479318921&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;dev.c - net/core/dev.c -  Linux source code v7.1-rc6 - Bootlin Elixir Cross Referencer&quot; data-og-description=&quot;&quot; data-og-host=&quot;elixir.bootlin.com&quot; data-og-source-url=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L7914&quot; data-og-url=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L7914&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L7914&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L7914&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;dev.c - net/core/dev.c - Linux source code v7.1-rc6 - Bootlin Elixir Cross Referencer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;elixir.bootlin.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;처음 유저의 요청이 패킷 형태로 NIC(네트워크 카드)에 수신된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NIC에는 일반적으로 Ring Buffer라는 링 형태의 디스크립터 구조가 존재하며, NIC는 이를 통해 리눅스 커널과 상호작용한다.&lt;/p&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;[NIC 전송 이후]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NIC는 수신한 raw 패킷을 DMA(메모리에 직접 쓰는)방식으로 미리 할당된 RX 버퍼(rx_buffer/page)에 직접 적재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 그 위치는 rx descriptor가 가리킨다. 적재가 끝나면 &lt;b&gt;NIC가 HW 인터럽트를 발생&lt;/b&gt;시켜 커널에 &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;b&gt;[추가 동작]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 매 패킷마다 인터럽트로 처리하면 트래픽이 몰릴 때 인터럽트 폭주가 발생하므로, 커널은 NAPI라는 방식을 쓴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최초 인터럽트를 받은 뒤 &lt;b&gt;추가 인터럽트는 끄고&lt;/b&gt;, softirq(net_rx_action)가 &lt;b&gt;폴링&lt;/b&gt;으로 RX 버퍼를 비우며 &lt;b&gt;sk_buff를 구성한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 폴링 Budget은 기본 300이며, 이는 패킷 단위이다. NAPI는 이렇게 &lt;b&gt;정해진 &lt;span data-newtext-seq=&quot;109&quot;&gt;예산 한도 &lt;/span&gt;&lt;span data-newtext-seq=&quot;125&quot;&gt;내에서 바라보며 폴링한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;[DevOps/SRE Engineer를 위한 TIP]&lt;/b&gt;&lt;br /&gt;이 budget을 다 쓰거나 time_limit을 초과하면 time_squeeze 를 올리고 양보한다.&lt;br /&gt;이 값은 /proc/net/softnet_stat에서 확인 가능한 지표로, 계속 증가하면 budget이 부족하다는 신호이므로 튜닝의 근거가 된다.&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;[예외]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처리 못 한 작업이 남으면 __raise_softirq_irqoff로 softirq를 다시 예약해 다음 기회에 마저 비운다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한편 코드를 보면 함수 진입/종료에서 bpf_net_ctx를 설정&amp;middot;해제하는데, 이는 RX 경로 자체에 eBPF가 개입할 여지가 있음을 의미하며, 뒤에서 다룰 Cilium의 동작과 직결된다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;TX (송신) 일때&lt;/h4&gt;
&lt;pre class=&quot;cpp&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;static __latent_entropy void net_tx_action(void)
{
	struct softnet_data *sd = this_cpu_ptr(&amp;amp;softnet_data);

	if (sd-&amp;gt;completion_queue) {
		struct sk_buff *clist;

		local_irq_disable();
		clist = sd-&amp;gt;completion_queue;
		sd-&amp;gt;completion_queue = NULL;
		local_irq_enable();

		while (clist) {
			struct sk_buff *skb = clist;

			clist = clist-&amp;gt;next;

			WARN_ON(refcount_read(&amp;amp;skb-&amp;gt;users));
			if (likely(get_kfree_skb_cb(skb)-&amp;gt;reason == SKB_CONSUMED))
				trace_consume_skb(skb, net_tx_action);
			else
				trace_kfree_skb(skb, net_tx_action,
						get_kfree_skb_cb(skb)-&amp;gt;reason, NULL);

			if (skb-&amp;gt;fclone != SKB_FCLONE_UNAVAILABLE)
				__kfree_skb(skb);
			else
				__napi_kfree_skb(skb,
						 get_kfree_skb_cb(skb)-&amp;gt;reason);
		}
	}

	if (sd-&amp;gt;output_queue) {
		struct Qdisc *head;

		local_irq_disable();
		head = sd-&amp;gt;output_queue;
		sd-&amp;gt;output_queue = NULL;
		sd-&amp;gt;output_queue_tailp = &amp;amp;sd-&amp;gt;output_queue;
		local_irq_enable();

		rcu_read_lock();

		while (head) {
			spinlock_t *root_lock = NULL;
			struct sk_buff *to_free;
			struct Qdisc *q = head;

			head = head-&amp;gt;next_sched;

			/* We need to make sure head-&amp;gt;next_sched is read
			 * before clearing __QDISC_STATE_SCHED
			 */
			smp_mb__before_atomic();

			if (!(q-&amp;gt;flags &amp;amp; TCQ_F_NOLOCK)) {
				root_lock = qdisc_lock(q);
				spin_lock(root_lock);
			} else if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED,
						     &amp;amp;q-&amp;gt;state))) {
				/* There is a synchronize_net() between
				 * STATE_DEACTIVATED flag being set and
				 * qdisc_reset()/some_qdisc_is_busy() in
				 * dev_deactivate(), so we can safely bail out
				 * early here to avoid data race between
				 * qdisc_deactivate() and some_qdisc_is_busy()
				 * for lockless qdisc.
				 */
				clear_bit(__QDISC_STATE_SCHED, &amp;amp;q-&amp;gt;state);
				continue;
			}

			clear_bit(__QDISC_STATE_SCHED, &amp;amp;q-&amp;gt;state);
			to_free = qdisc_run(q);
			if (root_lock)
				spin_unlock(root_lock);
			tcf_kfree_skb_list(to_free, q, NULL, qdisc_dev(q));
		}

		rcu_read_unlock();
	}

	xfrm_dev_backlog(sd);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L5780&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L5780&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781479341865&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;dev.c - net/core/dev.c -  Linux source code v7.1-rc6 - Bootlin Elixir Cross Referencer&quot; data-og-description=&quot;&quot; data-og-host=&quot;elixir.bootlin.com&quot; data-og-source-url=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L5780&quot; data-og-url=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L5780&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L5780&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://elixir.bootlin.com/linux/v7.1-rc6/source/net/core/dev.c#L5780&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;dev.c - net/core/dev.c - Linux source code v7.1-rc6 - Bootlin Elixir Cross Referencer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;elixir.bootlin.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[초기]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이번엔 송신을 하는 입장이다보니 직접 애플리케이션이 send()/write()를 호출한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;소켓을 거쳐 &lt;b&gt;커널이 sk_buff&lt;/b&gt; &lt;b&gt;생성한다. &lt;/b&gt;RX는 NIC가 만들어서 위로 올렸지만, TX는 위(앱)에서 만들어서 아래로 내리는 형태이다.&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;b&gt;[헤더 붙이기]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위 Layer에서 부터 내려오면서 L4(TCP)&amp;rarr;L3(IP)&amp;rarr;L2(MAC) 헤더를 skb_push로 &lt;b&gt;앞쪽(Head Room)에 차곡차곡&lt;/b&gt; 붙인다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 앞에서 말한 Head Room쪽에서 설명한 &quot;RX에서 pull로 벗기던 걸, TX에선 push로 붙인다&quot;는 내용이 기억이 날 것 이다.&amp;nbsp;&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;b&gt;[qdisc]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;TX 동작에서 조금 중요한 비중을 차지하는 부분인데, TX할때 사실 중간에 패킷을 바로 NIC로 안 보내고 &lt;b&gt;qdisc 라는 큐를&lt;/b&gt; 거친다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 트래픽 셰이핑/우선순위/pfifo_fast 같은 게 동작하는데, 이게 RX의 NAPI budget에 대응하는 TX쪽 핵심 메커니즘이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;i&gt;&lt;b&gt;qdisc 내부의 스케줄링 알고리즘(셰이핑/우선순위 등)은 주제를 벗어나므로 깊게는 다루지 않는다.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;다만 코드상 net_tx_action의 동작만 짚고 넘어가자면 아래 두가지 동작만 기억하면 좋다.&lt;br /&gt;① completion_queue로 전송 완료된 skb를 해제한다.&lt;br /&gt;② output_queue를 돌며 qdisc_run으로 큐에 쌓인 패킷을 송신 처리한다는 흐름만 짚고 넘어간다.&lt;/blockquote&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;b&gt;[드라이버 &amp;rarr; DMA &amp;rarr; NIC 전송]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;qdisc에서 나온 skb를 드라이버가 받아서, &lt;b&gt;DMA로 NIC에 전달&lt;/b&gt; &amp;rarr; NIC가 회선으로 송출.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;RX에서는 DMA로 받았지만 이번엔 오히려 보내는 입장이기 때문에 TX에선 DMA로 보낸다.&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;b&gt;[전송 완료 후 정리]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;NIC가 &quot;다 보냈다&quot;라는 내용으로 인터럽트를 발생 &amp;rarr; 앞서 본 net_tx_action이 skb를 해제한다&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;L3 ~ L4&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;netif_receive_skb로 sk_buff가 스택에 진입한 직후부터의 동작이다.&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;L3&lt;/b&gt;&lt;i&gt;&lt;/i&gt;&lt;/h4&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;netif_receive_skb &amp;rarr; ip_rcv() (IPv4). 여기가 L2&amp;rarr;L3의 경계다.&lt;/p&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;ip_rcv에서 하는 검증]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- IP 헤더 체크섬, 버전, 길이 검증&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 여기단계에서 netfilter 훅이 박힘 &amp;rarr; NF_INET_PRE_ROUTING.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- iptables의 PREROUTING 체인이 여기 단계다. (DNAT 걸리는 지점)&lt;/p&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;[라우팅 결정 (ip_rcv_finish &amp;rarr; ip_route_input)]&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;b&gt;로컬&lt;/b&gt;&amp;nbsp;&amp;rarr; ip_local_deliver &amp;rarr; L4로 올림&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;포워딩이면&lt;/b&gt; &amp;rarr; ip_forward &amp;rarr; 다시 나감 (여기서 NF_INET_FORWARD 훅)&lt;/p&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;p data-ke-size=&quot;size16&quot;&gt;- NF_INET_LOCAL_IN (iptables INPUT 체인)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무슨 권투선수도 아니고 계속 훅만 날리나 싶겠지만, 이 동작들이 L3에서 가장 중요한 단계이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 훅이라는 것은 패킷을 이동시키는 게 아니라, 라우팅으로 정해진 경로의 길목마다 앉아서 패킷을 검사하거나 변형하거나 걸러낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iptables/Cilium이 개입하는 게 전부 이 훅 지점이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;L4&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ip_local_deliver &amp;rarr; 프로토콜 핸들러 호출]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 헤더의 protocol 필드 보고 &amp;rarr; TCP면 tcp_v4_rcv, UDP면 udp_rcv&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- sk_buff 글에서 &quot;헤더 N번째 바이트 보고 구분&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;b&gt;[소켓 찾기 (demux)]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 4-tuple(출발IP/포트, 목적IP/포트)로 어느 소켓에 속하는지 해시 테이블에서 찾는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 소켓 못 찾으면? TCP는 RST, UDP는 ICMP port unreachable를 뱉는다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[TCP 상태 처리 + 리시브 큐 적재]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- tcp_v4_rcv &amp;rarr; 시퀀스 검증, 상태머신(ESTABLISHED 등) 처리를 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 정상이면 소켓의 receive queue에 sk_buff 적재&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 앱이 recv() 호출하면 거기서 꺼내간다. 그러면 비로소 유저스페이스까지 도달하게 된다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;그럼 TX는?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;TX는 역순이다. 절대 쓰기 귀찮아서 요약하는게 아니라 진짜 역순이다.&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;앱 send() &amp;rarr; tcp_sendmsg &amp;rarr; ip_queue_xmit(L3, 라우팅+헤더) &amp;rarr;&lt;br /&gt;NF_INET_LOCAL_OUT/POSTROUTING(SNAT) &amp;rarr; L2(아까 한 qdisc)&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;그래서 Cilium은?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iptables는 이 훅마다 규칙을 순차 검사하는데, 규칙이 수천 개로 늘면(K8S Service가 많아질수록) 선형 탐색 비용이 커진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cilium은 이 netfilter 훅 체인 자체를 eBPF로 대체해 이런 탐색 비용을 줄이는데, 자세한 건 진짜 바로 뒤에서 다룬다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Cilium?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;우선 CNI라는 것에 대한 이해도가 있는 사람을 대상으로 설명을 진행한다.&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[왜 기존 CNI방식이 느린가]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 kube-proxy의 iptables 모드 문제를 깔고 들어가야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적인 동작에서 쿠버는 K8S Service(ClusterIP) &amp;rarr; Pod IP 변환을 iptables DNAT 규칙으로 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(PRE_ROUTING에 들어가있다.)&lt;/p&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/Pod가 늘면 &lt;b&gt;규칙이 선형(O(n))으로 증가하는 구조가 된다.&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;p data-ke-size=&quot;size16&quot;&gt;Service 수천 개면 규칙은 수만 개이고 이는 매칭 비용 폭증시키는데 영향을 주고 룰 업데이트를 위해 전체 테이블을 다시 쓰기 때문 룰 업데이트도 느려진다.&lt;/p&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;[eBPF가 어디서 개입하나]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;eBPF는 커널 &lt;b&gt;여러 훅 포인트&lt;/b&gt;에 프로그램을 붙일 수 있다. 여기서 핵심이 XDP랑 tc(traffic control) ingress이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;XDP&lt;/b&gt;: 스택 진입 전이다. 거의 NIC 드라이버 레벨에서 패킷 가로채는데 이는 sk_buff 만들어지기도 전이다. 그래서 제일 빠른 지점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;tc/eBPF&lt;/b&gt;: sk_buff 생긴 직후이며, 여기는 아까 설명 중 L2~L3 사이. Cilium이 주로 여기랑 XDP 부분을 자주 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 Cilium은 netfilter 훅 체인(PRE_ROUTING 등)에 도달하기 전에 eBPF로 가로채서 처리해버리기 때문에 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;&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;: iptables가 규칙 순차 검사하던 걸, eBPF는 &lt;b&gt;해시맵(eBPF map)으로 O(1)&lt;/b&gt; 조회한다. 즉 Service가 수천 개여도 한 방에 찾을 수 있다는 말이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;경로 단축&lt;/b&gt;: XDP는 네트워크 스택 대부분을 &lt;b&gt;건너뛴다. &lt;/b&gt;Pod 간 통신에서 불필요한 iptables/netfilter/라우팅 전부 우회하게 되고 아까 우리가 본 sk_buff 글에서 '그 긴거' 라고 불려도 될 정도의 양인 릴레이들을 스킵한다.&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;마무리 정리&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;417&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpWml1/dJMcaicFzdZ/FNsPwPOro50JmmOOh2JTd1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpWml1/dJMcaicFzdZ/FNsPwPOro50JmmOOh2JTd1/img.jpg&quot; data-alt=&quot;펀하고 쿨하고 섹시한 Kernel과 Network&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpWml1/dJMcaicFzdZ/FNsPwPOro50JmmOOh2JTd1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpWml1%2FdJMcaicFzdZ%2FFNsPwPOro50JmmOOh2JTd1%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;559&quot; height=&quot;417&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;417&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;펀하고 쿨하고 섹시한 Kernel과 Network&lt;/figcaption&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;sk_buff = 패킷이 스택 타고 올라가며 겪는 그 모든 릴레이&lt;/li&gt;
&lt;li&gt;Cilium/eBPF = &lt;b&gt;그 릴레이 자체를 줄이거나 건너뛰는 것&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 위에서 복잡하고 머리아픈 sk_buff의 여정을 알았기에, 그걸 단축하는 eBPF의 가치를 이해할 수 있었다고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cilium 뿐만 아니라 이런 네트워크 스택에서의 간결함과 인터럽트를 통한 오버헤드 절감 등은 실제로 우리가 쓰고 있는 쿠버 내에서 다양한 곳에 존재한다.&lt;/p&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>cilium</category>
      <category>Cilium이 좋은 이유</category>
      <category>DevOps</category>
      <category>K8S Kernel</category>
      <category>NAPI</category>
      <category>Ring Buffer</category>
      <category>sk_buff</category>
      <category>네트워크 커널</category>
      <author>흑당망고</author>
      <guid isPermaLink="true">https://itmango.tistory.com/58</guid>
      <comments>https://itmango.tistory.com/58#entry58comment</comments>
      <pubDate>Thu, 4 Jun 2026 01:41:58 +0900</pubDate>
    </item>
    <item>
      <title>【Full AI Product 구성】 부제: AI로 어디까지 가능할까?</title>
      <link>https://itmango.tistory.com/57</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;시작하기 앞서&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자는 현재 DevOps로 근무중인 평범한 직장인 1이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글부터 시작해서 앞으로 n일 동안(얼마나 진행할지는 미지수) AI를 이용해서 모든 개발, 아이디어, 운영까지 해본 뒤 이후에 내가 하는 검토 업무까지 AI에게 위임이 가능할지에 대한 고찰을 해보려고 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;아이디어&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아이디어는 현재 마땅히 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시장 조사를 해본 경험이 있는 것도 아니고, 해봐야 IT동향 정도만 살펴본 내가 조금 더 넓은 시야를 가진 PM처럼 시장을 관측하는 것은 어렵다고 판단했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 이런 시장 동향에 대한 리서치는 OpenClaw를 쓰기로 했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1094&quot; data-origin-height=&quot;836&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IZfLQ/dJMcabKrhwm/FAO9qTSj8DMTQkAp9YNppK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IZfLQ/dJMcabKrhwm/FAO9qTSj8DMTQkAp9YNppK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IZfLQ/dJMcabKrhwm/FAO9qTSj8DMTQkAp9YNppK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIZfLQ%2FdJMcabKrhwm%2FFAO9qTSj8DMTQkAp9YNppK%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;504&quot; height=&quot;385&quot; data-origin-width=&quot;1094&quot; data-origin-height=&quot;836&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenClaw인 이유?&lt;br /&gt;➝ 별도로 없다. 단지 내가 어디서든 아이디어가 생각나면 대화하고 기록해주는 Agent가 필요했을 뿐이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;770&quot; data-origin-height=&quot;690&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yjZxY/dJMcahDPDkC/pIG9pdRuexNKkDdj842KPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yjZxY/dJMcahDPDkC/pIG9pdRuexNKkDdj842KPK/img.png&quot; data-alt=&quot;열심히 md파일을 깃헙에 올려주는 Agent&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yjZxY/dJMcahDPDkC/pIG9pdRuexNKkDdj842KPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyjZxY%2FdJMcahDPDkC%2FpIG9pdRuexNKkDdj842KPK%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;247&quot; height=&quot;221&quot; data-origin-width=&quot;770&quot; data-origin-height=&quot;690&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;열심히 md파일을 깃헙에 올려주는 Agent&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;개발&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발은 세가지를 비교해보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Cursor를 통한 AI Agentic Coding&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Claude Code를 이용한 CLI 기반 Agentic Coding&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Kiro/Kiro CLI를 이용한 Coding&lt;/p&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에게 먹일 수 있는 형태로 나누어 각각 다른 영역을 3개의 Agent들에게 먹여서 코딩해볼 예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 결과물이 좋은 Agent에게 나머지 2개의 Agent가 트롤링한 코드의 리팩토링도 맡길 예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cursor를 사용하는 이유: 크레딧 다 쓰니까 더 해보라고 나한테 100크래딧을 공짜로 줘서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Claude Code를 사용하는 이유: anthropic이 현재 Vibe Coding 계열에선 원탑 모델인 Opus와 Sonnet을 보유하고 있기 때문&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kiro/Kiro CLI를 사용하는 이유: 위 2개의 Agent보다 토큰을 효율적으로 잘 쓴다는 외국 포럼에서의 이야기가 있어서 테스트 삼아&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHwslZ/dJMcagLJuMw/D4ajgHRNJBqHHynD7EgL50/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHwslZ/dJMcagLJuMw/D4ajgHRNJBqHHynD7EgL50/img.webp&quot; data-alt=&quot;https://dev.to/cristiansifuentes/cursor-vs-windsurf-vs-cline-vs-claude-code-vs-kilo-code-2fpd&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHwslZ/dJMcagLJuMw/D4ajgHRNJBqHHynD7EgL50/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHwslZ%2FdJMcagLJuMw%2FD4ajgHRNJBqHHynD7EgL50%2Fimg.webp&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;462&quot; height=&quot;462&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;800&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://dev.to/cristiansifuentes/cursor-vs-windsurf-vs-cline-vs-claude-code-vs-kilo-code-2fpd&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 많이들 고민하는 고민 지점이긴 한 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글에 조금만 검색해보아도 windsurf, cursor, claude code, kiro, antigravity 와 같은 Agent IDE 혹은 Agent CLI를 서로 비교하고 있으니 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 실상은 모두 모델은 대부분 Opus, Sonnet을 이용하는 사용자들이 대부분일 것이고 Agent가 제공하는 Spec기반 구체화 같은 토큰을 절감할 수 있는 다양한 방법론적인 차이점만 있을 것으로 예상된다.&lt;/p&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;내가 써본 언어라면 평가를 할 수 있고, 써보지 않은 언어라면 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;참고로 모든 개발 과정에 있어서 민감값이 없다면 그 부분들은 모두 github에 공개 레포에 올려둘 예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;인프라&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인프라는 홈랩에 올려볼 예정이다.&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-ke-size=&quot;size23&quot;&gt;이 글이 의미하는 것&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서 말한 모든 요소를 완료했다는 글이 올라오면 정말로 AI가 많은 발전을 이뤘다고 느끼면 될 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 업계에 있으면서 많은 체감을 하고는 있지만 이것은 현재 우리가 마주한 눈앞 문제를 해결하는데만 사용하면 느낀 부분이고, 이런 업무와 관련이 아예없는 분야에 대해서도 AI가 모든 프로덕트를 혼자 잘 구성하고 운영하고, 기획한다면 정말 무서울 것 같다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <author>흑당망고</author>
      <guid isPermaLink="true">https://itmango.tistory.com/57</guid>
      <comments>https://itmango.tistory.com/57#entry57comment</comments>
      <pubDate>Sat, 28 Mar 2026 19:50:54 +0900</pubDate>
    </item>
    <item>
      <title>【Node.js에 대한 간단한 고찰】 부제: Node의 메모리 관리 방법</title>
      <link>https://itmango.tistory.com/56</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JAVA, Python, Rust 모두 각각 메모리를 관리하는 방식이 참 다양하고 다릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이중에서 FrontEnd의 표준이 된 코드 발사대인 Node.js의 메모리 관리 방식에 대해서 알아볼까 합니다.&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;Node.js의 관리 Layer&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node.js는 근본적으로 Crome을 동작시키는 V8 Engine을 기반으로 동작합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;V8 Engine이 브라우저 프로그램에서 동작된다면 여기서 JS를 동작시키는 엔진을 똑 떼서 가져와 CLI기반의 JS코드를 동작시킬 수 있도록 만든 것이 바로 Node.js입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://nodejs.org/en/learn/getting-started/the-v8-javascript-engine&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://nodejs.org/en/learn/getting-started/the-v8-javascript-engine&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1773575785345&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Node.js &amp;mdash; The V8 JavaScript Engine&quot; data-og-description=&quot;Node.js&amp;reg; is a free, open-source, cross-platform JavaScript runtime environment that lets developers create servers, web apps, command line tools and scripts.&quot; data-og-host=&quot;nodejs.org&quot; data-og-source-url=&quot;https://nodejs.org/en/learn/getting-started/the-v8-javascript-engine&quot; data-og-url=&quot;https://nodejs.org/en/learn/getting-started/the-v8-javascript-engine&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bUeQ0W/dJMb8PGuQRD/IUYDp6z6GTV8NRtPF0y4W1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bWs3gE/dJMb8Xkd3rM/Kwon10k4m4HCbmEOqv0tUk/img.png?width=224&amp;amp;height=256&amp;amp;face=0_0_224_256&quot;&gt;&lt;a href=&quot;https://nodejs.org/en/learn/getting-started/the-v8-javascript-engine&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://nodejs.org/en/learn/getting-started/the-v8-javascript-engine&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bUeQ0W/dJMb8PGuQRD/IUYDp6z6GTV8NRtPF0y4W1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bWs3gE/dJMb8Xkd3rM/Kwon10k4m4HCbmEOqv0tUk/img.png?width=224&amp;amp;height=256&amp;amp;face=0_0_224_256');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Node.js &amp;mdash; The V8 JavaScript Engine&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Node.js&amp;reg; is a free, open-source, cross-platform JavaScript runtime environment that lets developers create servers, web apps, command line tools and scripts.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;nodejs.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, Node.js는 근본적으로 V8엔진을 이용해 JS코드의 파싱을 하고 동작을 시키는 일종의 Wrapper역할을 한다고도 볼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 System과 연결된 동작의 경우는 V8에서 관리를 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C언어로 작성하여 Linux, Window의 Low Level인 Kernel과 상호작용을 하기 위함이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A라는 동작을 했을때 Node가 V8엔진의 API를 호출하여 V8엔진이 커널에게 자신이 해야하는 동작을 전달해주는 형태인 겁니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;메모리는 어디서 관리할까?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 메모리는 어느 Layer에서 관리를 할까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;V8? Node?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정답은 V8 Engine과 Node 모두 합니다.&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;그게 무슨 말도 안되는 소리임 System Level은 V8 Engine이 한다고 위에서 이야기했잖아;&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;우리가 아는 메모리는 V8 Engine이 관리하는게 맞지요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 GC 즉, 가비지 컬렉터는?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node가 동작시킵니다.&lt;/p&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/v8/v8/blob/14.8.30/src/base/platform/platform-linux.cc&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/v8/v8/blob/14.8.30/src/base/platform/platform-linux.cc&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1773576925862&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;v8/src/base/platform/platform-linux.cc at 14.8.30 &amp;middot; v8/v8&quot; data-og-description=&quot;The official mirror of the V8 Git repository. Contribute to v8/v8 development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/v8/v8/blob/14.8.30/src/base/platform/platform-linux.cc&quot; data-og-url=&quot;https://github.com/v8/v8/blob/14.8.30/src/base/platform/platform-linux.cc&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/MGGC4/dJMb9lk5PS5/rvWzEhyDO6CygHpfhHvoL0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/gps84/dJMb9cBGNyg/6rWK4kfb4wggE6rjKHsJTK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/v8/v8/blob/14.8.30/src/base/platform/platform-linux.cc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/v8/v8/blob/14.8.30/src/base/platform/platform-linux.cc&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/MGGC4/dJMb9lk5PS5/rvWzEhyDO6CygHpfhHvoL0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/gps84/dJMb9cBGNyg/6rWK4kfb4wggE6rjKHsJTK/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;v8/src/base/platform/platform-linux.cc at 14.8.30 &amp;middot; v8/v8&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The official mirror of the V8 Git repository. Contribute to v8/v8 development by creating an account on GitHub.&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;이 파일을 한번 뜯어봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1773577027912&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 55ac243aa000-55ac243ac000 r--p 00000000 fe:01 31594735 /usr/bin/foo
if (!ReadHex(&amp;amp;entry.start, &amp;amp;delim)) return std::nullopt;
if (!ReadHex(&amp;amp;entry.end, &amp;amp;delim)) return std::nullopt;
for (int i = 0; i &amp;lt; 4; ++i) {
    if (!ReadChar(&amp;amp;entry.raw_permissions[i])) return std::nullopt;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1773577047511&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int fd = open(enclosing_region.pathname, O_RDONLY);
struct stat stat_buf;
if (fstat(fd, &amp;amp;stat_buf)) { /* 에러 처리 */ }

if (stat_buf.st_dev != enclosing_region.dev ||
    stat_buf.st_ino != enclosing_region.inode) {
    close(fd);
    return false;
}

void* mapped_address = mmap(new_address, size, protection,
                            MAP_FIXED | MAP_PRIVATE, fd, offset_in_file);&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;즉 System과 강결합된 코드들이 많은 모습이죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그에 반면에 이번엔 해당 파일을 한번 훑어보죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/nodejs/node/blob/2ea7a7b67c3d698a0e80d2591365e2dc5c5f7a81/deps/uv/src/unix/linux.c#L2130&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/nodejs/node/blob/2ea7a7b67c3d698a0e80d2591365e2dc5c5f7a81/deps/uv/src/unix/linux.c#L2130&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1773577217555&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;node/deps/uv/src/unix/linux.c at 2ea7a7b67c3d698a0e80d2591365e2dc5c5f7a81 &amp;middot; nodejs/node&quot; data-og-description=&quot;Node.js JavaScript runtime ✨ ✨. Contribute to nodejs/node development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/nodejs/node/blob/2ea7a7b67c3d698a0e80d2591365e2dc5c5f7a81/deps/uv/src/unix/linux.c#L2130&quot; data-og-url=&quot;https://github.com/nodejs/node/blob/2ea7a7b67c3d698a0e80d2591365e2dc5c5f7a81/deps/uv/src/unix/linux.c&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c61kzb/dJMb9efcDmp/T1fO8emCXomH5qqrLaaIBk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bUoT6j/dJMb9dHmLkI/tkOQXa0DSF2CSSbIcSyWkK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/nodejs/node/blob/2ea7a7b67c3d698a0e80d2591365e2dc5c5f7a81/deps/uv/src/unix/linux.c#L2130&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/nodejs/node/blob/2ea7a7b67c3d698a0e80d2591365e2dc5c5f7a81/deps/uv/src/unix/linux.c#L2130&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c61kzb/dJMb9efcDmp/T1fO8emCXomH5qqrLaaIBk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bUoT6j/dJMb9dHmLkI/tkOQXa0DSF2CSSbIcSyWkK/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;node/deps/uv/src/unix/linux.c at 2ea7a7b67c3d698a0e80d2591365e2dc5c5f7a81 &amp;middot; nodejs/node&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Node.js JavaScript runtime ✨ ✨. Contribute to nodejs/node development by creating an account on GitHub.&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;코드가 길어서 특정 줄만 링크를 가져왔긴합니다.&lt;/p&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을 v1과 v2로 분기처리해서 호출하는 모습이 포착됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1773577528184&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static void uv__get_cgroup2_memory_limits(char buf[static 1024], uint64_t* high,
                                          uint64_t* max) {
  char filename[4097];
  char* p;
  int n;

  /* Find out where the controller is mounted. */
  p = buf + strlen(&quot;0::/&quot;);
  n = (int) strcspn(p, &quot;\n&quot;);

  /* Read the memory limits of the controller. */
  snprintf(filename, sizeof(filename), &quot;/sys/fs/cgroup/%.*s/memory.max&quot;, n, p);
  *max = uv__read_uint64(filename);
  snprintf(filename, sizeof(filename), &quot;/sys/fs/cgroup/%.*s/memory.high&quot;, n, p);
  *high = uv__read_uint64(filename);
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1773577563295&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static void uv__get_cgroup1_memory_limits(char buf[static 1024], uint64_t* high,
                                          uint64_t* max) {
  char filename[4097];
  char* p;
  int n;
  uint64_t cgroup1_max;

  /* Find out where the controller is mounted. */
  p = uv__cgroup1_find_memory_controller(buf, &amp;amp;n);
  if (p != NULL) {
    snprintf(filename, sizeof(filename),
             &quot;/sys/fs/cgroup/memory/%.*s/memory.soft_limit_in_bytes&quot;, n, p);
    *high = uv__read_uint64(filename);

    snprintf(filename, sizeof(filename),
             &quot;/sys/fs/cgroup/memory/%.*s/memory.limit_in_bytes&quot;, n, p);
    *max = uv__read_uint64(filename);

    /* If the controller wasn't mounted, the reads above will have failed,
     * as indicated by uv__read_uint64 returning 0.
     */
     if (*high != 0 &amp;amp;&amp;amp; *max != 0)
       goto update_limits;
  }&lt;/code&gt;&lt;/pre&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 data-ke-size=&quot;size16&quot;&gt;다음과 같은 결론을 낼 수 있겠네요.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;V8&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;System Level에서 메모리의 실제 주소를 요청/할당/파기 하는 동작은 &lt;b&gt;V8 Engine&lt;/b&gt;에서 동작을 합니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;왜 이걸 V8에서 할까?&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;V8엔진은 앞서 설명한 바와 같이 브라우저의 JS파싱을 하는 엔진이기 때문이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 브라우저 레벨에서도 누군가는 메모리 관리를 해주어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, GC와 같은 동작은 더 상위 Layer에서 처리하면 되기 때문에 V8엔진의 설계적인 방향에서는 제외되었을 가능성이 높다고 볼 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Node&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GC를 동작시키기 위한 현재 메모리 상태를 감지하는 것은 Node에서 동작을 합니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;이건 왜 Node에서 할까?&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node는 V8 Engine을 래핑하고 그 위에서 JS가 동작가능하도록 만든 프로그램입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 V8에서 메모리를 할당/파기/호출하는 것과 다르게 언제 인메모리에 적재된 데이터를 갈아 엎을지, 내 메모리 현황은 어떤지는 V8보다 상위 Layer인 Node에서 하는 것이 맞고, V8에선 당연히 구현이 안되어 있기 때문으로 보는게 맞겠네요.&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;이 글에서 DevOps가 얻을 수 있는 인사이트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;K8S 1.25버전 부터는 공식적으로 cgroup v2를 지원합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 대한 내용은 &lt;a href=&quot;https://man7.org/linux/man-pages/man7/cgroups.7.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;해당&lt;/a&gt; 사이트에서 더 깊게 볼 수 있으니 참고해보시면 좋습니다.&lt;/p&gt;
&lt;figure id=&quot;og_1773577959167&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;cgroups(7) - Linux manual page&quot; data-og-description=&quot;cgroups(7) &amp;mdash; Linux manual page cgroups(7) Miscellaneous Information Manual cgroups(7) NAME &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; top cgroups - Linux control groups DESCRIPTION &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; top Control groups, usually referred to as cgroups, are a Linux kernel feature which allow p&quot; data-og-host=&quot;man7.org&quot; data-og-source-url=&quot;https://man7.org/linux/man-pages/man7/cgroups.7.html&quot; data-og-url=&quot;https://man7.org/linux/man-pages/man7/cgroups.7.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://man7.org/linux/man-pages/man7/cgroups.7.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://man7.org/linux/man-pages/man7/cgroups.7.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;cgroups(7) - Linux manual page&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;cgroups(7) &amp;mdash; Linux manual page cgroups(7) Miscellaneous Information Manual cgroups(7) NAME &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; top cgroups - Linux control groups DESCRIPTION &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; top Control groups, usually referred to as cgroups, are a Linux kernel feature which allow p&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;man7.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;대부분 AWS의 EKS를 사용하는 사람들은 공감하겠지만 AWS에서는 Amazon 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;이미 1.33 Cluster Upgrade를 해본 사람을 공감하겠지만 옛날부터 Amazon Linux 2를 쓰던 사람들은 필연적으로 EKS Cluster 1.33 업그레이드에서 Amazon Linux 2023으로 넘어가야하는 피눈물 나는 작업을 해보았을 거라 예상됩니다...ㅜ&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;text-align: left;&quot;&gt;기존 클러스터 업그레이드 작업도 기본적으로 무중단 Multi Cluster Blue/Green Update 환경을 만들어 두지 않는 이상 힘든 작업이었겠지만 이번 1.33은 더욱 크게 느껴질 것 같네요.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이유는?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 Cluster 업그레이드 딸깍 &amp;rarr; Node AMI 교체 후 Rolling 형태로만 해도 충분히 동작 했을 겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이번엔 근간이 되는 AMI 자체를 엎어야하는 상황이 생겨버렸죠.&lt;/p&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1518&quot; data-origin-height=&quot;979&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bs5NmL/dJMcahXYlq1/VkbLI7FXhDOe2rEkOIRjX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bs5NmL/dJMcahXYlq1/VkbLI7FXhDOe2rEkOIRjX1/img.png&quot; data-alt=&quot;https://repost.aws/questions/QUNMXffcGsRbyyNef9DyEQKQ/amazon-linux-2-%EC%84%9C%ED%8F%AC%ED%8A%B8-%EC%A2%85%EB%A3%8C%EC%97%90-%EA%B4%80%ED%95%B4%EC%84%9C&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bs5NmL/dJMcahXYlq1/VkbLI7FXhDOe2rEkOIRjX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbs5NmL%2FdJMcahXYlq1%2FVkbLI7FXhDOe2rEkOIRjX1%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;1518&quot; height=&quot;979&quot; data-origin-width=&quot;1518&quot; data-origin-height=&quot;979&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://repost.aws/questions/QUNMXffcGsRbyyNef9DyEQKQ/amazon-linux-2-%EC%84%9C%ED%8F%AC%ED%8A%B8-%EC%A2%85%EB%A3%8C%EC%97%90-%EA%B4%80%ED%95%B4%EC%84%9C&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;AL 2가 불안불안하더니 결국 종료해버렸습니다 ㅋㅋ ㅜㅜㅜ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1602&quot; data-origin-height=&quot;745&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cccnmM/dJMcagLycfq/tIsWQdIdkbEyq8Iu8k0PJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cccnmM/dJMcagLycfq/tIsWQdIdkbEyq8Iu8k0PJ0/img.png&quot; data-alt=&quot;https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/kubernetes-versions-standard.html#kubernetes-1-33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cccnmM/dJMcagLycfq/tIsWQdIdkbEyq8Iu8k0PJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcccnmM%2FdJMcagLycfq%2FtIsWQdIdkbEyq8Iu8k0PJ0%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;1094&quot; height=&quot;509&quot; data-origin-width=&quot;1602&quot; data-origin-height=&quot;745&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/kubernetes-versions-standard.html#kubernetes-1-33&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이젠 EKS에서도 Amazon Linux 2의 지원을 종료해버렸기에 이젠 AMI 교체가 필연적으로 이루어져야겠죠...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AL 2023에선 어떤 문제가 있을까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너의 자원을 관리하는 cgroup이 바로 위에서 언급한 cgroup v2로 업데이트 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 cgroup v1을 지원하던 구버전의 언어/프레임워크는 모두 업데이트를 강행해야만 한다는 의미 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기선 Node.js의 메모리 관리만을 다루기 때문에 Node.js의 지원 버전을 말해볼까 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;바로 20.3버전 부터 지원합니다.&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;a href=&quot;https://www.reddit.com/r/node/comments/1c29sge/cgroups_v2_support_in_nodejs/?tl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.reddit.com/r/node/comments/1c29sge/cgroups_v2_support_in_nodejs/?tl=ko&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 이슈가 있고,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;20버전의 코드를 보면 cgroup v1, v2에 대한 분기처리(함수)가 없었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/nodejs/node/blob/e7618fb5a5fc25d76b6474e2a6607f04fd6f10e0/deps/uv/src/unix/linux-core.c#L796&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/nodejs/node/blob/e7618fb5a5fc25d76b6474e2a6607f04fd6f10e0/deps/uv/src/unix/linux-core.c#L796&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;20.03은?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/nodejs/node/blob/57679e1c97a90057d5ca9e1f0d1f3c6255d20200/deps/uv/src/unix/linux.c#L1874&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/nodejs/node/blob/57679e1c97a90057d5ca9e1f0d1f3c6255d20200/deps/uv/src/unix/linux.c#L1874&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1773579866963&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;node/deps/uv/src/unix/linux.c at 57679e1c97a90057d5ca9e1f0d1f3c6255d20200 &amp;middot; nodejs/node&quot; data-og-description=&quot;Node.js JavaScript runtime ✨ ✨. Contribute to nodejs/node development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/nodejs/node/blob/57679e1c97a90057d5ca9e1f0d1f3c6255d20200/deps/uv/src/unix/linux.c#L1874&quot; data-og-url=&quot;https://github.com/nodejs/node/blob/57679e1c97a90057d5ca9e1f0d1f3c6255d20200/deps/uv/src/unix/linux.c&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Vjj26/dJMb9b3QKy2/jKDXEeIU7q9AmSfDLbZ2w1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/cCbOAE/dJMb9hCZ0k0/FFyElE5MuEs89sHzo0CCQ1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/nodejs/node/blob/57679e1c97a90057d5ca9e1f0d1f3c6255d20200/deps/uv/src/unix/linux.c#L1874&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/nodejs/node/blob/57679e1c97a90057d5ca9e1f0d1f3c6255d20200/deps/uv/src/unix/linux.c#L1874&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Vjj26/dJMb9b3QKy2/jKDXEeIU7q9AmSfDLbZ2w1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/cCbOAE/dJMb9hCZ0k0/FFyElE5MuEs89sHzo0CCQ1/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;node/deps/uv/src/unix/linux.c at 57679e1c97a90057d5ca9e1f0d1f3c6255d20200 &amp;middot; nodejs/node&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Node.js JavaScript runtime ✨ ✨. Contribute to nodejs/node development by creating an account on GitHub.&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;cgroup v1, v2에 대한 분기처리도 생기고, 기존에 linux-&amp;lt;역할&amp;gt;.c 형태의 파일들이 linux.c로 통합된 모습을 볼 수 있습니다.&lt;/p&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 Linux 2023 AMI에서 20.03버전 이전 버전을 사용할 경우 cgroup v2를 지원하는 Amazon Linux 2023에서는 Node.js가 자신에게 할당된 Memory를 읽지 못하고 적재하다가 OOM이 펑펑 터질 수 있다는 슬픈 이야기 입니다..&lt;/p&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;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;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python은 결론만 이야기하면 cgroup 이슈가 자체적으로는 존재하지 않았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 JAVA는...? 있네요~!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 따로 다루지는 않겠습니다. (넘 길어요...이해도도 떨어지고 말이죠)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://younsl.github.io/blog/cgroup-v2/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://younsl.github.io/blog/cgroup-v2/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1773580470577&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;cgroup v2&quot; data-og-description=&quot;back2024-09-30 cgroup v2개요cgroup v1에서 cgroup v2로 전환할 경우 발생할 수 있는 문제를 정리한 페이지입니다.Amazon Linux 2023은 기본적으로 cgroup v2를 사용합니다. 따라서 Amazon Linux 2에서 Amazon Linux 2023으&quot; data-og-host=&quot;younsl.github.io&quot; data-og-source-url=&quot;https://younsl.github.io/blog/cgroup-v2/&quot; data-og-url=&quot;https://younsl.github.io/blog/cgroup-v2/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/lMflC/dJMb8952ipm/KkxZ0k8KSQOgjLVxgNVuu0/img.png?width=1628&amp;amp;height=1646&amp;amp;face=0_0_1628_1646,https://scrap.kakaocdn.net/dn/1Jyzo/dJMb9fZt1Fm/KMUDwcMaxk4LnDYyJ6oCEk/img.png?width=1680&amp;amp;height=1236&amp;amp;face=0_0_1680_1236,https://scrap.kakaocdn.net/dn/dvT1dR/dJMb83krCuL/xUrOk423SPXsqwDMt5wM70/img.png?width=2374&amp;amp;height=647&amp;amp;face=0_0_2374_647&quot;&gt;&lt;a href=&quot;https://younsl.github.io/blog/cgroup-v2/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://younsl.github.io/blog/cgroup-v2/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/lMflC/dJMb8952ipm/KkxZ0k8KSQOgjLVxgNVuu0/img.png?width=1628&amp;amp;height=1646&amp;amp;face=0_0_1628_1646,https://scrap.kakaocdn.net/dn/1Jyzo/dJMb9fZt1Fm/KMUDwcMaxk4LnDYyJ6oCEk/img.png?width=1680&amp;amp;height=1236&amp;amp;face=0_0_1680_1236,https://scrap.kakaocdn.net/dn/dvT1dR/dJMb83krCuL/xUrOk423SPXsqwDMt5wM70/img.png?width=2374&amp;amp;height=647&amp;amp;face=0_0_2374_647');&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;cgroup v2&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;back2024-09-30 cgroup v2개요cgroup v1에서 cgroup v2로 전환할 경우 발생할 수 있는 문제를 정리한 페이지입니다.Amazon Linux 2023은 기본적으로 cgroup v2를 사용합니다. 따라서 Amazon Linux 2에서 Amazon Linux 2023으&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;younsl.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대신 처음보는 블로그이지만 잘 정리해둔 블로그가 있어서 링크를 가져왔으니 참고해보면 좋을 것 같습니다~&lt;/p&gt;</description>
      <category>프로그래밍/Node.js</category>
      <category>EKS 1.33 Nodejs</category>
      <category>EKS Cluster Upgarde 1.33 Node.js</category>
      <category>Node.js 20.03 업데이트</category>
      <category>Node.js cgroup v2</category>
      <category>Node.js GC</category>
      <category>Node.js 메모리</category>
      <category>Node.js 메모리 관리</category>
      <category>nodejs메모리</category>
      <author>흑당망고</author>
      <guid isPermaLink="true">https://itmango.tistory.com/56</guid>
      <comments>https://itmango.tistory.com/56#entry56comment</comments>
      <pubDate>Sun, 15 Mar 2026 22:16:29 +0900</pubDate>
    </item>
    <item>
      <title>【우선순위를 나누는 방법】 부제: 비지니스 임팩트와 현실간의 간극</title>
      <link>https://itmango.tistory.com/55</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이번 글은 기술적인 내용이 아닙니다.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;우선순위를 어떻게해야 잘 나눌까?&lt;/h2&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;h3 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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;누군가는 그런 마인드 셋이 책임감이 없다고 질책할 수도 있다. 하지만 이를 나쁘다고 마냥 질책할 수도 없는 노릇이 그 행동들은 사회에서 규정한 매니저라는 Role과 실무자라는 Role이 해야하는 몫에 대해 충실한 것일 뿐이기 때문이다.&lt;/p&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1279&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2CGiw/dJMcad10Ag5/Kvf23WCJpgPUVbOSLRNX2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2CGiw/dJMcad10Ag5/Kvf23WCJpgPUVbOSLRNX2k/img.png&quot; data-alt=&quot;출처: https://www.linkedin.com/pulse/%EC%8B%A4%EB%AC%B4%ED%98%95-%EA%B4%80%EB%A6%AC%EC%9E%90%EB%8A%94-%EC%97%86%EB%8B%A4-thing-hands-on-manager-sue-yeon-yun-p1zhc&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2CGiw/dJMcad10Ag5/Kvf23WCJpgPUVbOSLRNX2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc2CGiw%2FdJMcad10Ag5%2FKvf23WCJpgPUVbOSLRNX2k%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;1279&quot; height=&quot;720&quot; data-origin-width=&quot;1279&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: https://www.linkedin.com/pulse/%EC%8B%A4%EB%AC%B4%ED%98%95-%EA%B4%80%EB%A6%AC%EC%9E%90%EB%8A%94-%EC%97%86%EB%8B%A4-thing-hands-on-manager-sue-yeon-yun-p1zhc&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;하지만, A고객사 B고객사 미팅이 겹쳤을때 스스로 판단해 'B 고객사는 우선순위가 낮아'라며 B와의 미팅을 파기하는 행위를 신입사원이 했다고 예시를 들어보자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- B와 우리 회사의 관계가 중요하다면?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 추후의 사업 방향에서 Key Man이 B고객사의 팀장이라면?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 사실을 신입에게 알려주지 않고 이런 Key Man에게 직접 보낸 윗선의 잘못이 있겠지만 그 사항은 차치하고, 결국에 문제를 일으킨 것은 신입의 독단적인 우선순위 판단 때문이라고 봐야한다.&lt;/p&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;b&gt;결국 위에서부터 쭉쭉 내려오는 Top-Down 형식의 우선순위 결정이 이루어지고 있다고 볼 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;작은 기업&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작은기업은 어떨까? 작은 기업에서의 우선순위는 생각보다 더욱 더 추상적이다.&lt;/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;- A라는 일은 빨리 할 수록 미래의 업무의 업무 효율을 곱절로 향상시킬 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- B라는 일은 지금 해야만 회사에 돈을 벌어올 수 있다.&lt;/p&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;B &amp;rarr; A 아니야?&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;하지만 대부분 놓치는 것이 B라는 일 하위에 붙는 업무들이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;B를 했을때 따라오는 오퍼레이션성 업무들이 있을 것이다. 가령 고객대응 등이 있을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때문에 A라는 일은 하염없이 미룰 수 밖에 없다면 당신은 어떻게 선택을 하겠는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A로 업무 효율을 곱절로 향상시킨 상태로 B를 수행하며 하위로 붙는 오퍼레이션 업무를 진행하겠는가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아니면 B를 모두 완료하고 A라는 업무를 &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;/p&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;199&quot; data-origin-height=&quot;254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5S0Y7/dJMcadgGAaB/uYczQuiiCkdraWxrrmJtc0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5S0Y7/dJMcadgGAaB/uYczQuiiCkdraWxrrmJtc0/img.jpg&quot; data-alt=&quot;출처: https://kospomagazine.co.kr/page/vol119/view.php?idx=91&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5S0Y7/dJMcadgGAaB/uYczQuiiCkdraWxrrmJtc0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5S0Y7%2FdJMcadgGAaB%2FuYczQuiiCkdraWxrrmJtc0%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;199&quot; height=&quot;254&quot; data-origin-width=&quot;199&quot; data-origin-height=&quot;254&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: https://kospomagazine.co.kr/page/vol119/view.php?idx=91&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;b&gt;A를 선택하든 B를 선택하든 무엇이 최고의 선택이였는지는 결과를 보기 전까지 절대 알 수 없다.&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;작은 기업이 Bottom-UP 구조가 많은 것도 이런 이유 중 하나라고 보면 된다.&lt;/p&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-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;/p&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;- 난 퇴근 직후인 지금 Riot Client를 켜서 LOL을 한판 땡기고 싶다.&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;이 상황 3가지에서 우선순위를 어떻게 매겨야하는가(나라면 현실적으로는 롤하다가 배민으로 시켜먹겠지만)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상황을 3개의 Layer로 나누어서 보자&lt;/p&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 data-ke-size=&quot;size16&quot;&gt;2. 설거지를 하기 위한 준비 요소는 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 독립성을 가진 LOL 플레이라는 선택지가 존재&lt;/p&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;rarr; 저녁 식사 &amp;rarr; LOL 순으로 진행한다.&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;/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;식사라는 인간 필수요소를 채우기 위한 저녁을 먹는 것이고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유흥이라는 요소를 채우기 위해 LOL을 하는 것이다.&lt;/p&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;순서.png&quot; data-origin-width=&quot;1714&quot; data-origin-height=&quot;363&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FeuWC/dJMcadAVlJI/9pVIPJl9Ykn49FgrPKLMuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FeuWC/dJMcadAVlJI/9pVIPJl9Ykn49FgrPKLMuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FeuWC/dJMcadAVlJI/9pVIPJl9Ykn49FgrPKLMuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFeuWC%2FdJMcadAVlJI%2F9pVIPJl9Ykn49FgrPKLMuk%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;1714&quot; height=&quot;363&quot; data-filename=&quot;순서.png&quot; data-origin-width=&quot;1714&quot; data-origin-height=&quot;363&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;h2 data-ke-size=&quot;size26&quot;&gt;결론은?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;업무우선순위 매트릭스라고 부르는 형태의 업무 우선순위를 조정하는 방식들이 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1633&quot; data-origin-height=&quot;1251&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V3j7A/dJMcaiI1ZL2/Ea8ZdM6vS6ITNqYLehujfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V3j7A/dJMcaiI1ZL2/Ea8ZdM6vS6ITNqYLehujfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V3j7A/dJMcaiI1ZL2/Ea8ZdM6vS6ITNqYLehujfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV3j7A%2FdJMcaiI1ZL2%2FEa8ZdM6vS6ITNqYLehujfk%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;1633&quot; height=&quot;1251&quot; data-origin-width=&quot;1633&quot; data-origin-height=&quot;1251&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 나는 결정을 직접 해야하는 작은 기업에 재직하는 낮은 연차를 대상으로 글을 작성하고 있기에 이러한 구체적인 선정 방식은 배제할까 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 업무를 나누는 가장 좋은 기준은 비지니스 임팩트 순서이다.&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;회사에 기여하는 사람이 높은 효율을 낼 수 있도록 서포팅해주는 것도 높은 비지니스 임팩트를 가지는 것이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;현실&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분 임팩트를 가지는 업무를 알고는 있지만, 혼동을하는 것이 가장 큰 문제이다.&lt;/p&gt;
&lt;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;이는 자연스러운 현상이기 때문에 주기적으로 머리속에 복기만 한다면 능동적인 태도를 가진 이들은 이를 해결 할 수 있다.&lt;/p&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;409&quot; data-origin-height=&quot;364&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B0mDJ/dJMcaihZq4f/uunZ0kgxAykfTrNpfraA70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B0mDJ/dJMcaihZq4f/uunZ0kgxAykfTrNpfraA70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B0mDJ/dJMcaihZq4f/uunZ0kgxAykfTrNpfraA70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB0mDJ%2FdJMcaihZq4f%2FuunZ0kgxAykfTrNpfraA70%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;409&quot; height=&quot;364&quot; data-origin-width=&quot;409&quot; data-origin-height=&quot;364&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;그저 안정적인 생활을 즐기는 사람이라면 요즘 AI가 자신의 자리를 위협하고, 이에 밀려나지 않기 위해서는 마인드셋에 재 장착이 필요한 상황이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2040&quot; data-origin-height=&quot;1360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WkxBc/dJMcaiWzaug/UnsYRueVSu9fS5HPvN3Umk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WkxBc/dJMcaiWzaug/UnsYRueVSu9fS5HPvN3Umk/img.jpg&quot; data-alt=&quot;가장 HOT한 AI Agent Tool이다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WkxBc/dJMcaiWzaug/UnsYRueVSu9fS5HPvN3Umk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWkxBc%2FdJMcaiWzaug%2FUnsYRueVSu9fS5HPvN3Umk%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;2040&quot; height=&quot;1360&quot; data-origin-width=&quot;2040&quot; data-origin-height=&quot;1360&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;가장 HOT한 AI Agent Tool이다.&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;사실 이보다 더 큰 문제들도 다양하게 존재한다.&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;- 리더가 승진에만 관심이 있을때&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;&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;/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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;922&quot; data-origin-height=&quot;499&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTOkDb/dJMcaaEhGTb/8RWlgqxqKGzZrXpkk7wykk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTOkDb/dJMcaaEhGTb/8RWlgqxqKGzZrXpkk7wykk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTOkDb/dJMcaaEhGTb/8RWlgqxqKGzZrXpkk7wykk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTOkDb%2FdJMcaaEhGTb%2F8RWlgqxqKGzZrXpkk7wykk%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;922&quot; height=&quot;499&quot; data-origin-width=&quot;922&quot; data-origin-height=&quot;499&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;임팩트를 어떻게 구분하나요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비지니스적인 임팩트를 알기 위해선 회사의 시스템, 비지니스 모델을 파악하는 것이 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그를 파악해두었다면 앞으로 업무의 우선순위를 나눌 수 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 회사의 재정상태가 좋지 않다면?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 비용절감 업무가 임팩트가 높다.&lt;/p&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;rarr; 성숙도를 올리는 업무를 발제하여 이를 가장 우선적으로 수행하면 된다.&lt;/p&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;134&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y5W7U/dJMcabb5JHr/0XAApMXDbKdORbKZubeKHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y5W7U/dJMcabb5JHr/0XAApMXDbKdORbKZubeKHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y5W7U/dJMcabb5JHr/0XAApMXDbKdORbKZubeKHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy5W7U%2FdJMcabb5JHr%2F0XAApMXDbKdORbKZubeKHk%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;375&quot; height=&quot;134&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;134&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;그럼 그렇게 우선순위를 선정한 업무는 어떻게해야 잘할 수 있나요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;업무를 잘 처리하는 것과 우선순위 결정은 아예 영역 자체가 다른 부분이다.&lt;/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;</description>
      <category>일상</category>
      <category>비지니스 임팩트</category>
      <category>업무 우선순위</category>
      <category>우선순위 매트릭스</category>
      <category>우선순위를 잘 조정하는법</category>
      <category>임팩트</category>
      <author>흑당망고</author>
      <guid isPermaLink="true">https://itmango.tistory.com/55</guid>
      <comments>https://itmango.tistory.com/55#entry55comment</comments>
      <pubDate>Wed, 18 Feb 2026 23:36:27 +0900</pubDate>
    </item>
    <item>
      <title>【엔드포인트 모니터링】 부제: BlackBox Exporter + ArgoCD + Grafana</title>
      <link>https://itmango.tistory.com/54</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;내 근황&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이직을 했습니다...&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;h2 data-ke-size=&quot;size26&quot;&gt;홈 서버 근황&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;솔직히 홈서버의 변화가 좀 많았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ELK, Vector, 신규 앱 등록까지 다양한 변화들이 있었죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 중 가장 큰 변화는 오늘 진행한 BlackBox Exporter를 도입한 점 입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;그게 뭔데요?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엔드포인트 레벨에서의 Latency 체크 기능입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/prometheus/blackbox_exporter&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/prometheus/blackbox_exporter&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1770912168819&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 - prometheus/blackbox_exporter: Blackbox prober exporter&quot; data-og-description=&quot;Blackbox prober exporter. Contribute to prometheus/blackbox_exporter development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/prometheus/blackbox_exporter&quot; data-og-url=&quot;https://github.com/prometheus/blackbox_exporter&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b9HI2w/dJMb9eTLJxw/SWGOyEQlOq0xWAc71OxFtk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bzm5Pj/dJMb8T9Vw7B/44421a8S9sn3gGkvXxdTWK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/prometheus/blackbox_exporter&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/prometheus/blackbox_exporter&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b9HI2w/dJMb9eTLJxw/SWGOyEQlOq0xWAc71OxFtk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bzm5Pj/dJMb8T9Vw7B/44421a8S9sn3gGkvXxdTWK/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 - prometheus/blackbox_exporter: Blackbox prober exporter&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Blackbox prober exporter. Contribute to prometheus/blackbox_exporter development by creating an account on GitHub.&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;Prometheus가 공식적으로 지원하는 익스텐션 기능이라고 생각하면 됩니다. 즉 그닥...메인이 되지는 못한 서자 포지션으로 보이더라고요..ㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 그와 동시에 Prometheus가 유명한 오픈소스인 만큼 나름 체급있는(?) 서브기능이라고 생각하면 나쁘지만은 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가볍게 기능 디테일을 설명하면 해당 오픈소스는 대표적으로 아래 3개의 프로토콜 체킹을 지원합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- HTTP/S&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- DNS&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ICMP&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로토콜 3개가 각각의 역할이 너무 다르긴 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 대부분 서비스에서 REST API를 사용하기에 RSET API의 근간인 HTTP/S를 이용했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(물론 여기서 보여드린 예제는 FrontEnd긴 하지만요)&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;설정 법&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;현재 내 상황&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 홈서버를 Proxmox를 통해 나누어 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;Application을 app-of-apps에 넣어두고 Application yaml파일, values파일, chart파일 3개를 통해서 오픈소스 Helm Chart를 사용하고 있습니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;3 Layer의 장점 및 관점적 이유&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 저는 Factor가 다른 Area에 대해서는 LifeCycle을 따로 따로 가져가는 것을 올바른 구성이라고 생각하곤 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인프라 레벨에서의 사이드 이펙트 방지가 가장 큰 이유가 될 수 있고 IaC의 가시성 확보도 이유에 포함되겠네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3Layer를 통해서 인프라를 구성하게 될 경우 다음과 같은 장점이 있겠네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- values의 life Cycle과 Application Manifest file의 life Cycle을 따로 가져갈 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Chart 주소 변경이 쉽습니다. bitnami같은 경우 인수되면서 기존 Helm Chart를 이젠 쓰기 어려운 문제가 생겼는데 이럴 경우 빠른 변경이 가능합니다.&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;Helm yaml 파일 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자! 본론으로 돌아가서 Application 파일을 작성해보면 다음과 같네요.&lt;/p&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;&amp;gt; Application 파일&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1770912746224&quot; class=&quot;yaml&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: prometheus-blackbox-exporter
  namespace: argocd
spec:
  project: default
  source:
    repoURL: 'https://github.com/&amp;lt;유저명 or 그룹명&amp;gt;/&amp;lt;레포명&amp;gt;'
    targetRevision: HEAD
    path: &amp;lt;차트경로&amp;gt;
    helm:
      valueFiles:
        - &amp;lt;Values파일명&amp;gt;.yaml
  destination:
    server: '&amp;lt;K8S서버주소&amp;gt;'
    namespace: &amp;lt;생성할_네임스페이스&amp;gt;
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=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;b&gt;&amp;gt; Values 파일&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1770912819522&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;prometheus-blackbox-exporter:
  restartPolicy: Always

  config:
    modules:
      http_2xx:
        prober: http
        timeout: 5s
        http:
          preferred_ip_protocol: &quot;ip4&quot;

  serviceMonitor:
    enabled: true
    defaults:
      labels:
        release: &amp;lt;프로메테우스_레이블명&amp;gt;
      interval: 30s
      scrapeTimeout: 30s
      module: http_2xx
    
    targets:
      - name: &amp;lt;타겟의_그룹이름&amp;gt;
        url: &amp;lt;타겟_URL&amp;gt;

  resources:
    limits:
      memory: 100Mi
    requests:
      cpu: 50m
      memory: 50Mi&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;b&gt;&amp;gt; Chart 파일&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1770912844641&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apiVersion: v2
name: blackbox-exporter-wrapper
description: A wrapper chart for Prometheus Blackbox Exporter
type: application
version: 1.0.0
appVersion: &quot;v0.25.0&quot;

dependencies:
  - name: prometheus-blackbox-exporter
    version: 9.1.0
    repository: https://prometheus-community.github.io/helm-charts&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;데이터 확인 방법&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1차 확인&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 쿠버 클러스터로 API를 쏴서 포트포워딩을 해봅시다.&lt;/p&gt;
&lt;pre id=&quot;code_1770913744203&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl port-forward svc/prometheus-blackbox-exporter 9115:9115 -n &amp;lt;네임스페이스&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;접속해보면 다음과 같이 화면이 나오게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;353&quot; data-origin-height=&quot;387&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ww5eG/dJMcaiPJI4Q/S1hWjNDrCqdOTjoEMiiLr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ww5eG/dJMcaiPJI4Q/S1hWjNDrCqdOTjoEMiiLr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ww5eG/dJMcaiPJI4Q/S1hWjNDrCqdOTjoEMiiLr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fww5eG%2FdJMcaiPJI4Q%2FS1hWjNDrCqdOTjoEMiiLr1%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;353&quot; height=&quot;387&quot; data-origin-width=&quot;353&quot; data-origin-height=&quot;387&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차적으로 잘 넘어왔나? 에 대한 여부이지 이 데이터가 시각화 툴에서 한번에 볼 수 있도록 잘 기록되는가? 와는 조금 다른 영역입니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;시각화 해보기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 저는 여기에 한술 더 떠서 Grafana를 통해 매트릭을 시각화 하였습니다.&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2216&quot; data-origin-height=&quot;501&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIu391/dJMcaa5h6PH/v03mr9pBKGPiYIw4t7b5Hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIu391/dJMcaa5h6PH/v03mr9pBKGPiYIw4t7b5Hk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIu391/dJMcaa5h6PH/v03mr9pBKGPiYIw4t7b5Hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIu391%2FdJMcaa5h6PH%2Fv03mr9pBKGPiYIw4t7b5Hk%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;2216&quot; height=&quot;501&quot; data-origin-width=&quot;2216&quot; data-origin-height=&quot;501&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;200&quot; data-origin-height=&quot;170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SUNvQ/dJMcadASyWg/I0c8XckVPLNqd5oObSkte1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SUNvQ/dJMcadASyWg/I0c8XckVPLNqd5oObSkte1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SUNvQ/dJMcadASyWg/I0c8XckVPLNqd5oObSkte1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSUNvQ%2FdJMcadASyWg%2FI0c8XckVPLNqd5oObSkte1%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;200&quot; height=&quot;170&quot; data-origin-width=&quot;200&quot; data-origin-height=&quot;170&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;2. Template을 가져오기 위해 아래와 같은 &quot;대시보드 가져오기&quot;를 클릭 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1136&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tcz8s/dJMcaf6A092/BKuSOB5wrGfmdMfwAI8OP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tcz8s/dJMcaf6A092/BKuSOB5wrGfmdMfwAI8OP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tcz8s/dJMcaf6A092/BKuSOB5wrGfmdMfwAI8OP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ftcz8s%2FdJMcaf6A092%2FBKuSOB5wrGfmdMfwAI8OP0%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;1136&quot; height=&quot;567&quot; data-origin-width=&quot;1136&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;340&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mZZeW/dJMcabJVczs/kOJEoCKIDaPM9mEPK6hB2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mZZeW/dJMcabJVczs/kOJEoCKIDaPM9mEPK6hB2K/img.png&quot; data-alt=&quot;혹여라도 저장할거냐고 하면 안한다고 하면 됩니다....굳이 필요없어요&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mZZeW/dJMcabJVczs/kOJEoCKIDaPM9mEPK6hB2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmZZeW%2FdJMcabJVczs%2FkOJEoCKIDaPM9mEPK6hB2K%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;340&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;340&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;3. 이제 '7587' 라고 입력 후 불러오기를 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;657&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ehKKTn/dJMcaaYvT67/fnIdHUVFynpYw1OySHPViK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ehKKTn/dJMcaaYvT67/fnIdHUVFynpYw1OySHPViK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ehKKTn/dJMcaaYvT67/fnIdHUVFynpYw1OySHPViK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FehKKTn%2FdJMcaaYvT67%2FfnIdHUVFynpYw1OySHPViK%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;674&quot; height=&quot;764&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;657&quot; data-origin-height=&quot;427&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;4. 아래와 같이 변경되면 이름, 폴더, UID등을 수정하고 데이터 소스를 Prometheus로 지정합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;822&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mDosq/dJMcab4bKF2/HPyxDjpsIFnCmakfqbku01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mDosq/dJMcab4bKF2/HPyxDjpsIFnCmakfqbku01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mDosq/dJMcab4bKF2/HPyxDjpsIFnCmakfqbku01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmDosq%2FdJMcab4bKF2%2FHPyxDjpsIFnCmakfqbku01%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;684&quot; height=&quot;822&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;822&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 Import를 하면 대시보드가 생깁니다. 들어가보면 다음과 같이 Health Check한 내용에 대해서 분석해서 말해줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2244&quot; data-origin-height=&quot;841&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/U1cs8/dJMcaiCebas/cYx4KWq1Px0i0GyvHiuHBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/U1cs8/dJMcaiCebas/cYx4KWq1Px0i0GyvHiuHBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/U1cs8/dJMcaiCebas/cYx4KWq1Px0i0GyvHiuHBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FU1cs8%2FdJMcaiCebas%2FcYx4KWq1Px0i0GyvHiuHBk%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;2244&quot; height=&quot;841&quot; data-origin-width=&quot;2244&quot; data-origin-height=&quot;841&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;간단 FAQ&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;rarr; Alert Manager와 연동하여 Slack과 같은 협업 툴에 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;그럼 이거로 어떤 인사이트를 얻을 수 있냐?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 기존에는 APM에 의존해서 애플리케이션 내부 레벨만 관측했다면 이제는 실 사용자 기준으로 확인이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 그냥 curl cronjob 쏘는거랑 뭐가 다르냐?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 정확한 관점입니다. 다를게 없어요 ㅋㅋ 다만 수기로 curl 때린 값을 Metric화 해서 귀찮게 내부 모니터링 데이터 소스로 쏴줄 필요 없고, 레이턴시 등까지 모두 체킹하도록 도와주는 편의성 관점으로 보면 꽤 괜찮지 않나요?&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;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 해당 글이 그렇게 까지 유익한 글은 아니지만 다들 큰 바운더리 내에서의 구성법만 있고 실질적인 프로덕트에서 사용할만한 Application, Chart 등의 설정을 적어둔 블로그를 못찾아서 직접하고 남기는 겁니다.....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;별로 특별한 글은 아니니 궁금하신 점 있으면 댓글 마구마구 남겨주세요~!&lt;/p&gt;</description>
      <category>DevOps/K8S</category>
      <category>Blackbox Exporter ArgoCD</category>
      <category>Blackbox Exporter Grafana</category>
      <category>Blackbox Exporter Helm Chart</category>
      <category>grafana</category>
      <category>Helm chart</category>
      <category>metric</category>
      <category>Prometheus</category>
      <category>Prometheus Blackbox Exporter</category>
      <category>그라파나</category>
      <category>블랙박스 익스포터 그라파나</category>
      <author>흑당망고</author>
      <guid isPermaLink="true">https://itmango.tistory.com/54</guid>
      <comments>https://itmango.tistory.com/54#entry54comment</comments>
      <pubDate>Fri, 13 Feb 2026 01:37:54 +0900</pubDate>
    </item>
    <item>
      <title>【K8S Pod 모니터링 툴을 만들어보았다】 부제: Rust는 어려워</title>
      <link>https://itmango.tistory.com/53</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에 한번 서버가 죽고 난 이후 현재 서버상태를 주기적으로 Github에 올릴 수 있는 로직을 만들어보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Rust도 공부할겸 기초적인 문법을 통해서 한번 진행해보았습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결과물&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/lucia-land/server-status&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/lucia-land/server-status&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1759860937728&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 - lucia-land/server-status&quot; data-og-description=&quot;Contribute to lucia-land/server-status development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/lucia-land/server-status&quot; data-og-url=&quot;https://github.com/lucia-land/server-status&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/duTJHK/hyZKdZIBs1/B4SOGyJtgmzTFk7NtILLmK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bOeGOg/hyZKJXxBye/wWkJThCqqEginexkIX5vA0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/lucia-land/server-status&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/lucia-land/server-status&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/duTJHK/hyZKdZIBs1/B4SOGyJtgmzTFk7NtILLmK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bOeGOg/hyZKJXxBye/wWkJThCqqEginexkIX5vA0/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 - lucia-land/server-status&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to lucia-land/server-status development by creating an account on GitHub.&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;일단은 짧게나마 Rust로 작성해보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Rust로 작성한 이유는 홈서버인 만큼 메모리 효율성이 가비지 컬렉터에 의존하지 않는 서비스를 올리고 싶었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 아직 숙련도 이슈로인해 제대로 관리는 못하겠지만 말이죠 ㅎㅎ...ㅜ&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;동작 로직&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동작 로직은 매우 간단합니다. main.rs에서 API요청 하는 로직을 mod로 추가해서 10분마다 K8S API Call을 진행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;./kube/config를 확인해 홈서버에 APIServer로 요청을 보내고 값을 돌려받으면 그 값을 토대로 status.log를 내보냅니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;logic.png&quot; data-origin-width=&quot;973&quot; data-origin-height=&quot;595&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMH3I7/btsQ3xM1QLz/KPOrPHFTYeVqGQo44LSdYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMH3I7/btsQ3xM1QLz/KPOrPHFTYeVqGQo44LSdYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMH3I7/btsQ3xM1QLz/KPOrPHFTYeVqGQo44LSdYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMH3I7%2FbtsQ3xM1QLz%2FKPOrPHFTYeVqGQo44LSdYK%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;973&quot; height=&quot;595&quot; data-filename=&quot;logic.png&quot; data-origin-width=&quot;973&quot; data-origin-height=&quot;595&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;간략 설명&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;라이센스&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라이센스는 MIT 라이센스를 따릅니다.&lt;/p&gt;
&lt;pre id=&quot;code_1759862006004&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;MIT License

Copyright (c) 2024 server-status

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the &quot;Software&quot;), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;cargo.toml&lt;/h3&gt;
&lt;pre id=&quot;code_1759862042197&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[package]
name = &quot;server-status&quot;
version = &quot;0.1.0&quot;
edition = &quot;2024&quot;

[dependencies]
anyhow = &quot;1.0.100&quot;
chrono = &quot;0.4.42&quot;
k8s-openapi = { version = &quot;0.26.0&quot;, default-features = false, features = [&quot;v1_30&quot;] }
kube = { version = &quot;2.0.1&quot;, features = [&quot;runtime&quot;, &quot;derive&quot;] }
serde = { version = &quot;1.0.228&quot;, features = [&quot;derive&quot;] }
serde_json = &quot;1.0.145&quot;
tokio = { version = &quot;1.47.1&quot;, features = [&quot;full&quot;] }
log = &quot;0.4&quot;
env_logger = &quot;0.11&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;toml파일은 직접 한줄 한줄 패키지를 add시키면서 검수했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 제 환경이 window인 만큼 조금 더 Cross Build를 하지 않게끔 설정하려고 노력했습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;main&lt;/h3&gt;
&lt;pre id=&quot;code_1759862138313&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mod cron_action;

use tokio::time::{interval, Duration};
use chrono::Local;
use anyhow::Result;
use std::io::Write;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 mod를 통해 cron_action이라는 k8s api 요청을하는 파일을 불러왔습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 github_push라는 모듈도 추가할 예정인 만큼 한줄 정도 여유를 뒀습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 외로는 tokio라는 국룰 비동기 라이브러리를 추가했네요..&lt;/p&gt;
&lt;pre id=&quot;code_1759862300745&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#[tokio::main]
async fn main() -&amp;gt; Result&amp;lt;()&amp;gt; {
    let mut ticker = interval(Duration::from_secs(60 * 10));

    loop {
        ticker.tick().await;
        let local_now = Local::now();
        println!(&quot;[{local_now}] Collecting cluster status...&quot;);

        match cron_action::collect_pod_status().await {
            Ok(pods) =&amp;gt; {
                let log_entry = format!(&quot;[{}] Pod Status Check:\n{}\n---\n&quot;, 
                                      local_now, pods.join(&quot;\n&quot;));
                
                std::fs::OpenOptions::new()
                    .create(true)
                    .append(true)
                    .open(&quot;status.log&quot;)?
                    .write_all(log_entry.as_bytes())?;
                
                println!(&quot;✅ Logged {} pod statuses to status.log&quot;, pods.len());
            }
            Err(e) =&amp;gt; {
                let error_log = format!(&quot;[{}] ERROR: {}\n&quot;, local_now, e);
                std::fs::OpenOptions::new()
                    .create(true)
                    .append(true)
                    .open(&quot;status.log&quot;)?
                    .write_all(error_log.as_bytes())?;
                eprintln!(&quot;❌ Error: {e}&quot;);
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;async fn문을 사용하기 위해서는 tokio를 추가해야하더군요ㅜ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10분마다 일정하게 한번씩 작업을 순차적으로 해야하는 만큼 비동기 프로그래밍 작업을 하는게 추후 확장성 측면에서 좋다고 판단했습니다..! (이건 상당히 개인적인 로드맵이기 때문에...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;결론&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;루프를 돌면서 10분마다 k8s용 모듈이 트리거 되고 리턴으로 Ok에 값이 날라오면 그 값을 status.log로 파일 시스템을 오픈해 저장 후 성공 로그를 print하는 코드입니다..!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(무척 짧고 쉽죠?)&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;향후 계획&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아쉽게도 현재는 아직 서비스 형태로 올라와있진 않습니다.&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;p data-ke-size=&quot;size16&quot;&gt;그리고 Rust를 좀 더 공부해서 status.log파일을 주기적으로 github에 public하게 자동으로 올릴 수 있도록 설정하고자 계획 중에 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 좀 더 생각해보면 서비스, 인그레스등과 같은 주요 컴포넌트도 모니터링하는게 맞을 것 같아서 점점 확장해볼까 합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안이 무척이나 중요한 만큼 vault같은 서비스를 먼저 K8S에 띄우고 그 이후에 github deploykey를 올려서 설정해야겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 전에! 이렇게 한 내용을 좀 더 그 즉시 즉시 기록할 수 있게끔 K8S에 Jira, 컨플을 내부에 띄워볼 예정입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;여담&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 코드를 혼자 열심히 써보다가 컴파일 오류도 아니고 로직을 어떻게 짜야하는지 비동기는 어떻게 쓰는지를 모르겠어서 결국 초기엔 손 안대고 혼자 해보려고했던 계획과 다르게 GPT와 상담을 해버렸습니다....(저 특유의 이모지들은 GPT짓입니다 ㅜㅜ)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직은 rust 숙련도가 무척이나 부족한 것도 사실이고 이렇게 부족한걸 어떻게 다듬을지를 모르겠어서 냅다 만들어봤습니다.&lt;/p&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 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또한 아무래도 고가용성 및 안정성을 위해 저렴한 UPS같은걸 하나 구비할까 합니다.&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PqZmN/btsQ4zKm5KN/R0wgqRkmfevkPa3vKRP0lk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PqZmN/btsQ4zKm5KN/R0wgqRkmfevkPa3vKRP0lk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PqZmN/btsQ4zKm5KN/R0wgqRkmfevkPa3vKRP0lk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPqZmN%2FbtsQ4zKm5KN%2FR0wgqRkmfevkPa3vKRP0lk%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;480&quot; height=&quot;268&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;268&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>프로그래밍/Rust</category>
      <category>k8s</category>
      <category>rust</category>
      <category>rust로 k8s다루기</category>
      <category>홈서버</category>
      <author>흑당망고</author>
      <guid isPermaLink="true">https://itmango.tistory.com/53</guid>
      <comments>https://itmango.tistory.com/53#entry53comment</comments>
      <pubDate>Wed, 8 Oct 2025 03:46:06 +0900</pubDate>
    </item>
    <item>
      <title>【Rust 첫 걸음】 부제: 이게 뭐지</title>
      <link>https://itmango.tistory.com/52</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희 회사는 현재 Rust 또한 사용하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 Python, TS, GO 다양하게 사용하고 있기에 무엇이 메인인가에 대한 답은 제가 공식적으로 하기 어렵네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 적어도 제가 속한 작은 그룹안에서는 Rust가 메인 언어입니다.&lt;/p&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년 반이나 되어가는데 부끄럽게도 전 아직 Python과 TS만 사용할 줄 알고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다고 그 두 언어를 잘하는가?에 대해서도 선뜻 자신있게 이야기하지는 못할듯 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;히스토리&lt;/h2&gt;
&lt;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;1. 개발을 해보자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 그 개발을 (익명의 사람들과)다 같이해보자&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;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;/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;1. 실용성이 있을 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 재미가 있을 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 오픈소스 커뮤니티가 활발한 언어일 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3가지를 모두 충족한 언어는 &lt;b&gt;&lt;a href=&quot;https://rust-lang.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Rust&lt;/a&gt;&lt;/b&gt;였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 아직 한국에선 대부분 GO, JAVA, PYTHON을 다들 사용하고 있지만, Rust도 충분히 매력적이고 현재 회사에 기여도 할 수 있겠다는 생각이 들었습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/High-PO?tab=repositories&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/High-PO?tab=repositories&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1759751315336&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;profile&quot; data-og-title=&quot;High-PO - Overview&quot; data-og-description=&quot;I am a third‑year DevOps / AWS Cloud Engineer and have experience as an AWS Cloud Technical Architect. - High-PO&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/High-PO?tab=repositories&quot; data-og-url=&quot;https://github.com/High-PO&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/xJrTa/hyZKhHGa3X/Qhu3YbYeiRWedO2NRbr1zk/img.png?width=420&amp;amp;height=420&amp;amp;face=0_0_420_420,https://scrap.kakaocdn.net/dn/S8g8p/hyZJ8jEHjB/wbfktTU15cB41zeE2fVrDk/img.png?width=420&amp;amp;height=420&amp;amp;face=0_0_420_420&quot;&gt;&lt;a href=&quot;https://github.com/High-PO?tab=repositories&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/High-PO?tab=repositories&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/xJrTa/hyZKhHGa3X/Qhu3YbYeiRWedO2NRbr1zk/img.png?width=420&amp;amp;height=420&amp;amp;face=0_0_420_420,https://scrap.kakaocdn.net/dn/S8g8p/hyZJ8jEHjB/wbfktTU15cB41zeE2fVrDk/img.png?width=420&amp;amp;height=420&amp;amp;face=0_0_420_420');&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;High-PO - Overview&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I am a third‑year DevOps / AWS Cloud Engineer and have experience as an AWS Cloud Technical Architect. - High-PO&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;실제로 제 깃헙 레포의 8할은 쓰레기 더미라고 볼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 안에서 좋은걸 찾기가 더 어려울 정도죠 (하나정도는 있지 않을까? 하는 마음에 적기)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;시작&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글에 단순히 &quot;rust 공부법&quot;을 검색하니&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&quot;easy rust&quot;로 가볍게 공부하면 속성으로는 배울 수 있지만 정공법은 아니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #333333; text-align: center;&quot;&gt;라는 포스팅속 내용을 보게 되었습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #333333; text-align: center;&quot;&gt;어짜피 지금 도파민 팡팡터지는 언어를 공부하는거고 처음부터 딥하면 던질거 같으니(배우기 어렵다는 악명은 알고 있습니다) easy rust로 공부하기 시작했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/Dhghomon/easy_rust&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/Dhghomon/easy_rust&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1759751825877&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 - Dhghomon/easy_rust: Rust explained using easy English&quot; data-og-description=&quot;Rust explained using easy English. Contribute to Dhghomon/easy_rust development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/Dhghomon/easy_rust&quot; data-og-url=&quot;https://github.com/Dhghomon/easy_rust&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/f9mtm/hyZKKWfNA4/GenLihRBuXS9rtOqVzVX8K/img.png?width=1200&amp;amp;height=600&amp;amp;face=1006_136_1066_201,https://scrap.kakaocdn.net/dn/hK87A/hyZKEuXiIz/ykX66kX0tokKvRuogmjPZ1/img.png?width=1200&amp;amp;height=600&amp;amp;face=1006_136_1066_201&quot;&gt;&lt;a href=&quot;https://github.com/Dhghomon/easy_rust&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/Dhghomon/easy_rust&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/f9mtm/hyZKKWfNA4/GenLihRBuXS9rtOqVzVX8K/img.png?width=1200&amp;amp;height=600&amp;amp;face=1006_136_1066_201,https://scrap.kakaocdn.net/dn/hK87A/hyZKEuXiIz/ykX66kX0tokKvRuogmjPZ1/img.png?width=1200&amp;amp;height=600&amp;amp;face=1006_136_1066_201');&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 - Dhghomon/easy_rust: Rust explained using easy English&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Rust explained using easy English. Contribute to Dhghomon/easy_rust development by creating an account on GitHub.&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;아뿔싸 영어더군요. 영알못이라서 잘못 배울 가능성이 높아 찾아보니 이분이 한국어로도 강의를 해두었더랍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(외국인분이 한국어로 Rust를 가르치시는 모습은 정말 신기했습니다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://youtube.com/playlist?list=PLfllocyHVgsSJf1zO6k6o3SX2mbZjAqYE&amp;amp;si=iAB_OCh3z3PdAa1F&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/playlist?list=PLfllocyHVgsSJf1zO6k6o3SX2mbZjAqYE&amp;amp;si=iAB_OCh3z3PdAa1F&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1759751896931&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Easy Rust Korean / Rust in a Month of Lunches 한국어판&quot; data-og-description=&quot; &quot; data-og-host=&quot;www.youtube.com&quot; data-og-source-url=&quot;https://youtube.com/playlist?list=PLfllocyHVgsSJf1zO6k6o3SX2mbZjAqYE&amp;amp;si=iAB_OCh3z3PdAa1F&quot; data-og-url=&quot;http://www.youtube.com/playlist?list=PLfllocyHVgsSJf1zO6k6o3SX2mbZjAqYE&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/f7lwu/hyZKhAUAi1/Hz59IiFWM0jwVDt2KK1vJ0/img.jpg?width=480&amp;amp;height=270&amp;amp;face=0_0_480_270,https://scrap.kakaocdn.net/dn/b79r4B/hyZKc7rDOR/sikBY90BkbDQJiP9PscZM1/img.jpg?width=480&amp;amp;height=270&amp;amp;face=0_0_480_270&quot;&gt;&lt;a href=&quot;https://youtube.com/playlist?list=PLfllocyHVgsSJf1zO6k6o3SX2mbZjAqYE&amp;amp;si=iAB_OCh3z3PdAa1F&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://youtube.com/playlist?list=PLfllocyHVgsSJf1zO6k6o3SX2mbZjAqYE&amp;amp;si=iAB_OCh3z3PdAa1F&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/f7lwu/hyZKhAUAi1/Hz59IiFWM0jwVDt2KK1vJ0/img.jpg?width=480&amp;amp;height=270&amp;amp;face=0_0_480_270,https://scrap.kakaocdn.net/dn/b79r4B/hyZKc7rDOR/sikBY90BkbDQJiP9PscZM1/img.jpg?width=480&amp;amp;height=270&amp;amp;face=0_0_480_270');&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;Easy Rust Korean / Rust in a Month of Lunches 한국어판&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.youtube.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;현재&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강의 수가 180개나 되어 아직 전부보진 못했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;20개 정도 본 결과 러스트는 생각보다 상당히 매력적인 언어였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 9분의 1밖에 보지 않았는데, 심지어 이건 쉽게 풀어서 180강의 인건데도 너무 매력적이였습니다.&lt;/p&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;</description>
      <category>DevOps</category>
      <category>rust</category>
      <category>개발공부</category>
      <category>서버프로그래밍</category>
      <author>흑당망고</author>
      <guid isPermaLink="true">https://itmango.tistory.com/52</guid>
      <comments>https://itmango.tistory.com/52#entry52comment</comments>
      <pubDate>Mon, 6 Oct 2025 21:07:16 +0900</pubDate>
    </item>
    <item>
      <title>【Proxmox 살려보기】 부제: 너무 늦은 서비스 부활</title>
      <link>https://itmango.tistory.com/51</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;시작하기 앞서 갑자기 많은 백그라운드 히스토리없이 진행하기엔 애매한감이 있어 설명부터 작성해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 현재 아래 구조로 운영되는 K8S 홈서버를 운영하고 있습니다. 약 3개월 정도 된듯하네요...&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;My_project.png&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;641&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chY1lm/btsQ3Z9VONt/THfeK0Rok5QXvsx60N3kvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chY1lm/btsQ3Z9VONt/THfeK0Rok5QXvsx60N3kvk/img.png&quot; data-alt=&quot;https://www.lucia.land&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chY1lm/btsQ3Z9VONt/THfeK0Rok5QXvsx60N3kvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchY1lm%2FbtsQ3Z9VONt%2FTHfeK0Rok5QXvsx60N3kvk%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;761&quot; height=&quot;641&quot; data-filename=&quot;My_project.png&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;641&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://www.lucia.land&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혼자한 것은 아니며, 점점 고도화해나갈 생각으로 제 집에 서버를 두고 VPN 형태로 다른 사람이 연결해서 함께 작업이 가능한 환경을 만들었습니다. 현재 &lt;a href=&quot;https://github.com/shashax42&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/shashax42&lt;/a&gt; 님과 함께 XR페이지를 구축해서 운영하고 있는 상황입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나, &lt;a href=&quot;https://blog.itmango.net/50&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;해당 글&lt;/a&gt;과 같이 최근 서버가 죽었었고 바쁜일에 치여 서버를 살리지 못하고 있었습니다...ㅜㅜ(사실 그냥 귀찮음이겠지요...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 인프라에 대한 분석과 어떻게 살렸는지를 조금 구체적으로 열거 및 스스로 반성을 해볼까 합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Registry가 있는데 왜 ECR을 또 쓰나요?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실은 원래 Harbor만 사용하는 그림을 생각했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 막상 Harbor를 띄우고 나니 K8S에 PVC관련해 이슈가 자꾸 발생하더군요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VM을 새로 띄워 Restiry를 구축까지 했지만 인증오류가 꾸준히 발생하여 우선 서비스를 올려보고 이후 고도화하고자 해당 내용과 같이 구성하였습니다.&lt;/p&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;Harbor 고도화는 별거 없고 Harbor에서 내부 인증방식등을 학습해 보안강화 차원으로 진행할까 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ECR유기 스텝은 CI/CD에서 조금 변환을 해야할듯 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;고도화로드맵.png&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;888&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CEyL5/btsQ1ph6yQp/6IuhCQOkTZc87HjPH9lfC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CEyL5/btsQ1ph6yQp/6IuhCQOkTZc87HjPH9lfC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CEyL5/btsQ1ph6yQp/6IuhCQOkTZc87HjPH9lfC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCEyL5%2FbtsQ1ph6yQp%2F6IuhCQOkTZc87HjPH9lfC1%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;401&quot; data-filename=&quot;고도화로드맵.png&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;888&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Proxmox 트러블 슛팅&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정상적인 Proxmox는 처음 접속했을때 아래와 같은 사진이 출력이 되어야합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjaPiQ/btsQ2emL6kn/ilvj4QmBhqvSXgbRXhAUJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjaPiQ/btsQ2emL6kn/ilvj4QmBhqvSXgbRXhAUJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjaPiQ/btsQ2emL6kn/ilvj4QmBhqvSXgbRXhAUJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjaPiQ%2FbtsQ2emL6kn%2Filvj4QmBhqvSXgbRXhAUJk%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;1203&quot; height=&quot;648&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;648&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 아무런 화면이 출력이 되지 않는 문제가 발생해버리고 말았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오랜만에 다시 찾아본 결과 아래 3가지 패키지를 위주로 봐야했었습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1759585278396&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pveproxy
pvedaemon
pve-cluster&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3가지를 우선 점검하기 시작했습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1759585302546&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo systemctl status pveproxy pvedaemon pve-cluster&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 3가지의 상태를 확인해본 결과 pveproxy가 죽어있는 것을 확인했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pveproxy는 말 그대로 proxmox ve로의 접속을 유도해주는 proxy서버 역할을 해주는 서비스 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;접속만 안되고 실제 OS에서는 모든 프로세스가 살아있기 때문에 해당 서비스만 재시작해주면 고쳐질 것 이라 예상했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조금 더 로그를 보고 분석해볼까 하다가 어짜피 정전으로 인한 강제 종료였기도 하고, 이를 더 파기에는 아직 OS레벨 지식이 부족하기에 넘기기로 했습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1759585379870&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo systemctl restart pveproxy
sudo reboot&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어를 통해 재시작을 진행하고, 리부트 까지 진행해주었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 정상적으로 동작하기 시작했습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;커널?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트러블 슛팅을 하다가 한가지 궁금한 사항이 생겼습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 현재 Debian OS에 커널만 Proxmox 커널로 바꾸어서 사용 중인데 이게 BP가 맞는지가 궁금해졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조금 찾아본 결과 아래와 같은 레퍼런스가 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pve.proxmox.com/wiki/Install_Proxmox_VE_on_Debian_12_Bookworm&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://pve.proxmox.com/wiki/Install_Proxmox_VE_on_Debian_12_Bookworm&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1759586141476&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Install Proxmox VE on Debian 12 Bookworm - Proxmox VE&quot; data-og-description=&quot;Introduction The installation of a supported Proxmox VE server should be done via bare-metal ISO installer. In some cases it makes sense to install Proxmox VE on top of a running Debian Bookworm 64-bit, especially if you want a custom partition layout. For&quot; data-og-host=&quot;pve.proxmox.com&quot; data-og-source-url=&quot;https://pve.proxmox.com/wiki/Install_Proxmox_VE_on_Debian_12_Bookworm&quot; data-og-url=&quot;https://pve.proxmox.com/wiki/Install_Proxmox_VE_on_Debian_12_Bookworm&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://pve.proxmox.com/wiki/Install_Proxmox_VE_on_Debian_12_Bookworm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pve.proxmox.com/wiki/Install_Proxmox_VE_on_Debian_12_Bookworm&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Install Proxmox VE on Debian 12 Bookworm - Proxmox VE&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Introduction The installation of a supported Proxmox VE server should be done via bare-metal ISO installer. In some cases it makes sense to install Proxmox VE on top of a running Debian Bookworm 64-bit, especially if you want a custom partition layout. For&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pve.proxmox.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식적으로 Debian OS에서 Proxmox VE 커널을 장려하고 있던 사실을 알게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음엔 단순히 온몸비틀기 하려고 문서 찾으면서 했던건데 생각보다 꾸준히 지원 잘해주고 밀어주고 있었습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;마무리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평소랑 다르게 말투나 이런게 좀 친근했네요..ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 다음엔 기술적으로 어떻게 이 서버를 바꿔볼지, 모니터링은 어떻게 해볼지에 대해서 생각해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 Rust를 학습하고 있기 때문에 Rust + AI + 서버 와 관련된 글로 돌아올 것 같습니다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>ECR</category>
      <category>Harbor</category>
      <category>k8s</category>
      <category>Proxmox</category>
      <category>pveproxy</category>
      <category>홈서버</category>
      <author>흑당망고</author>
      <guid isPermaLink="true">https://itmango.tistory.com/51</guid>
      <comments>https://itmango.tistory.com/51#entry51comment</comments>
      <pubDate>Sat, 4 Oct 2025 22:58:18 +0900</pubDate>
    </item>
    <item>
      <title>【홈서버가 죽었다】 부제: 재발방지 대책?</title>
      <link>https://itmango.tistory.com/50</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;홈서버?&lt;/h2&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;h2 data-ke-size=&quot;size26&quot;&gt;영향도&lt;/h2&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;당연히 배포에 필요한 CICD도 다 죽었다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;어떻게 해결할까&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로 정전이 나지 않으면 참 좋겠지만 그건 어려울 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 내린 결론은 소형 UPS를 달자!로 나왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소형 UPS는 저렴한 가격에 구매 가능하고 이를 토대로 정전이 되었었는지도 파악이 가능하니 더 좋을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 상당히 막막하다 클러스터 다시 만들고 거기에 ArgoCD다시 배포하고 등등 언제 다할지를 모르겠다 Jenkins셋업도 상당히 오래 걸릴듯하고...&lt;/p&gt;</description>
      <category>DevOps</category>
      <author>흑당망고</author>
      <guid isPermaLink="true">https://itmango.tistory.com/50</guid>
      <comments>https://itmango.tistory.com/50#entry50comment</comments>
      <pubDate>Mon, 11 Aug 2025 09:50:18 +0900</pubDate>
    </item>
    <item>
      <title>【AI를 이용해 생산성을 높이자】 부제: AI를 고민하는 이유?</title>
      <link>https://itmango.tistory.com/49</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI를 사용하는 곳은 정말 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;링크드인을 3분만 둘러보면 너도 나도 모두 AI 이야기만 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 이러한 글들이 많다고해서 실제로 AI를 사용하는 사람이 정말 많을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 보안 컴플라이언스 요건을 무시하고도 사용하는 곳이 정말 많을까?&lt;/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;h2 data-ke-size=&quot;size26&quot;&gt;정말 안전한가?&lt;/h2&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;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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러한 부분은 스스로 잘 검열하여 AI를 사용하면 오히려 좋은 결과를 얻을 수 있다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순한 로직, 코드 퀄리티는 AI가 훨씬 높다는 점을 인지하고 있으면 좋겠다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;어떻게 생산성을 늘릴 수 있을까?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 github에 내가 올린 가벼운 프로젝트다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/High-PO/gws&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/High-PO/gws&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1753636990666&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 - High-PO/gws: How do you use AWS CLI v2 as an IAM user with MFA enabled?&quot; data-og-description=&quot;How do you use AWS CLI v2 as an IAM user with MFA enabled? - High-PO/gws&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/High-PO/gws&quot; data-og-url=&quot;https://github.com/High-PO/gws&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/eHFC7/hyZqZzOIHZ/feeb52uvoFCkGCkPICC6Ck/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/dbWRrM/hyZnmco9U4/nY4NZFbTCWzJTSCgtyDRG0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/High-PO/gws&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/High-PO/gws&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/eHFC7/hyZqZzOIHZ/feeb52uvoFCkGCkPICC6Ck/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/dbWRrM/hyZnmco9U4/nY4NZFbTCWzJTSCgtyDRG0/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 - High-PO/gws: How do you use AWS CLI v2 as an IAM user with MFA enabled?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;How do you use AWS CLI v2 as an IAM user with MFA enabled? - High-PO/gws&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;이 코드는 Mac에서 여러 AWS 계정을 스위칭해가면서 MFA인증을해 세션을 여는 프로그램을 담은 프로젝트이다.&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;p data-ke-size=&quot;size16&quot;&gt;모든 코드는 GO언어로 작성하였고, AI를 사용해서 개발했다.&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;p data-ke-size=&quot;size16&quot;&gt;e.g.)&lt;/p&gt;
&lt;pre id=&quot;code_1753637059602&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func showDetailedUsage() {
	fmt.Println(&quot;GWS - Go + AWS CLI v2&quot;)
	fmt.Println(&quot;=====================&quot;)
	fmt.Println(&quot;A tool to easily use AWS CLI v2 as an MFA-enabled IAM user on macOS.&quot;)
	fmt.Println()
	fmt.Println(&quot;USAGE:&quot;)
	fmt.Println(&quot;  gws &amp;lt;mfa-token&amp;gt;                  # Use default AWS profile with MFA token&quot;)
	fmt.Println(&quot;  gws &amp;lt;profile&amp;gt; &amp;lt;mfa-token&amp;gt;        # Use specific AWS profile with MFA token&quot;)
	fmt.Println(&quot;  gws help                         # Show this help message&quot;)
	fmt.Println(&quot;  gws help &amp;lt;command&amp;gt;               # Show detailed help for a specific command&quot;)
	fmt.Println(&quot;  gws --version                    # Show version information&quot;)
	fmt.Println()
	fmt.Println(&quot;EXAMPLES:&quot;)
	fmt.Println(&quot;  1. Using default profile:&quot;)
	fmt.Println(&quot;     $ gws 123456&quot;)
	fmt.Println(&quot;     This will authenticate using your default AWS profile with MFA token 123456&quot;)
	fmt.Println()
	fmt.Println(&quot;  2. Using a specific profile:&quot;)
	fmt.Println(&quot;     $ gws production 654321&quot;)
	fmt.Println(&quot;     This will authenticate using the 'production' AWS profile with MFA token 654321&quot;)
	fmt.Println()
	fmt.Println(&quot;ARGUMENTS:&quot;)
	fmt.Println(&quot;  &amp;lt;profile&amp;gt;      AWS profile name configured in ~/.aws/config&quot;)
	fmt.Println(&quot;  &amp;lt;mfa-token&amp;gt;    6-digit code from your MFA device (e.g., Google Authenticator)&quot;)
	fmt.Println()
	fmt.Println(&quot;NOTES:&quot;)
	fmt.Println(&quot;  - MFA serial numbers are stored in ~/gws/config.json per profile&quot;)
	fmt.Println(&quot;  - On first use with a profile, you'll be prompted for the MFA serial number&quot;)
	fmt.Println(&quot;  - The tool creates a new shell session with temporary AWS credentials&quot;)
	fmt.Println(&quot;  - Credentials are valid for 12 hours by default (AWS STS limitation)&quot;)
	fmt.Println()
	fmt.Println(&quot;For more information on a specific command, use: gws help &amp;lt;command&amp;gt;&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;fmt.Println을 정말 많이 사용했다.&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;MFA인증을하며 계정을 왔다 갔다하는게 힘들었고 각 커멘드를 여러번 수정하면서 사용하는 것은 재사용성이 떨어진다고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DevOps가 하는 업무중 하나인 &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;어떻게 하였고 얼마나 걸렸는지 말해보자면&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클루드코드 설치: 3분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클루드코드로 작업: 0분 = 실제로 작업하는 동안 나는 내 할일을 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트러블슛팅: 0분 = 또 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;&lt;b&gt;총합: 3분&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;말도 안되지 않는가? 3분으로 내가 평소 매일 낭비했던 10분을 절약했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작년 7월부터 지금까지 1년이고 매주 5일간 근무했으니 단순 계산으로만 해도 &lt;b&gt;2,400분이 낭비된 것이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;고작 3분으로 2,400분인 40시간을 절약&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툴이 존재한다. ChatGPT, 클루드, 클루드코드, 윈드서프, 제미나이 CLI, 커서, 코파일럿 등등&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-ke-size=&quot;size26&quot;&gt;결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자신에게 맞는 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 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;</description>
      <category>DevOps</category>
      <category>AI</category>
      <category>AI 프로젝트</category>
      <category>ai생산성</category>
      <category>AWS</category>
      <category>go</category>
      <category>생산성</category>
      <author>흑당망고</author>
      <guid isPermaLink="true">https://itmango.tistory.com/49</guid>
      <comments>https://itmango.tistory.com/49#entry49comment</comments>
      <pubDate>Mon, 28 Jul 2025 02:46:15 +0900</pubDate>
    </item>
  </channel>
</rss>