<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ops Insights – Karpenter</title><link>https://docs.makgol.com/karpenter/</link><description>Recent content in Karpenter on Ops Insights</description><generator>Hugo -- gohugo.io</generator><language>ko-KR</language><copyright>© 2026 Mont</copyright><lastBuildDate>Thu, 30 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://docs.makgol.com/karpenter/index.xml" rel="self" type="application/rss+xml"/><item><title>0.36 → 1.6 — v1 전환과 그 직후</title><link>https://docs.makgol.com/karpenter/01-changelog-v1-transition/</link><pubDate>Sat, 01 Aug 2026 00:00:00 +0000</pubDate><guid>https://docs.makgol.com/karpenter/01-changelog-v1-transition/</guid><description>
&lt;h1&gt;01 · 0.36 → 1.6 — v1이 바꾼 것은 API가 아니라 동작이다&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;v1beta1→v1을 &amp;ldquo;필드 이름이 바뀐 일&amp;quot;로 읽으면 사고가 납니다. changelog에서 위험한 절은 &lt;strong&gt;Behavior Changes&lt;/strong&gt;이고 그중 둘은 &lt;strong&gt;옵트아웃이 없습니다&lt;/strong&gt; — drift는 Stable 승격과 함께 feature gate가 삭제됐고(&lt;a href="https://github.com/kubernetes-sigs/karpenter/pull/1311"target="_blank" rel="noopener"&gt;core#1311&lt;/a&gt;), expiration은 forceful로 되돌아갔습니다(&lt;a href="https://github.com/kubernetes-sigs/karpenter/pull/1333"target="_blank" rel="noopener"&gt;core#1333&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;forceful expiration이 무시하는 건 PodDisruptionBudget(PDB)이 아닙니다.&lt;/strong&gt; 무시하는 것은 &amp;ldquo;대체 노드가 &lt;code&gt;Initialized&lt;/code&gt;가 될 때까지 드레인을 시작하지 않는다&amp;quot;는 사전 안전장치와 disruption budget입니다. &lt;code&gt;nodeclaim.expiration&lt;/code&gt; 컨트롤러는 후보 평가 없이 NodeClaim을 바로 &lt;code&gt;Delete&lt;/code&gt;합니다(&lt;code&gt;controllers/nodeclaim/expiration/controller.go:82&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;consolidateAfter&lt;/code&gt;가 v1에서 필수 필드입니다.&lt;/strong&gt; v1beta1의 &lt;code&gt;WhenUnderutilized&lt;/code&gt;에서는 설정조차 불가능했던 값이라 기존 동작을 유지하려면 &lt;code&gt;0s&lt;/code&gt;를 명시해야 합니다. &lt;code&gt;Never&lt;/code&gt;는 그 NodePool의 consolidation을 통째로 끕니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;terminationGracePeriod&lt;/code&gt;(&lt;a href="https://github.com/kubernetes-sigs/karpenter/pull/916"target="_blank" rel="noopener"&gt;core#916&lt;/a&gt;)가 최종 승자입니다.&lt;/strong&gt; 만료되면 PDB·&lt;code&gt;do-not-disrupt&lt;/code&gt; 무관하게 남은 파드가 강제 삭제됩니다. 반대로 TGP를 걸면 drift가 &amp;ldquo;PDB·&lt;code&gt;do-not-disrupt&lt;/code&gt; 파드가 있는 노드&amp;quot;까지 후보로 채택합니다 — 안전장치를 스스로 꺼주는 대가로 CVE 패치를 밀 수 있게 됩니다. 노드 최대 수명 = &lt;code&gt;expireAfter&lt;/code&gt;(기본 &lt;code&gt;720h&lt;/code&gt;, 상한이지 하한이 아닙니다) + TGP.&lt;/li&gt;
&lt;li&gt;disruption budgets가 &lt;code&gt;Drifted&lt;/code&gt;/&lt;code&gt;Underutilized&lt;/code&gt;/&lt;code&gt;Empty&lt;/code&gt; &lt;strong&gt;reason별로&lt;/strong&gt; 나뉘었습니다(&lt;a href="https://github.com/kubernetes-sigs/karpenter/pull/991"target="_blank" rel="noopener"&gt;core#991&lt;/a&gt;, &lt;a href="https://github.com/kubernetes-sigs/karpenter/pull/1377"target="_blank" rel="noopener"&gt;core#1377&lt;/a&gt;). 삭제된 drift feature gate의 자리를 reason별 budget이 메웁니다 — 업스트림이 제시하는 유일한 drift 통제 수단입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1.1.0이 v1beta1 서빙을 끝냈습니다.&lt;/strong&gt; &lt;code&gt;nodeClassRef.group&lt;/code&gt;/&lt;code&gt;kind&lt;/code&gt;가 강제 필수가 되고 kubelet 호환 어노테이션이 사라집니다. 같은 릴리스의 Bottlerocket + &lt;code&gt;instanceStorePolicy: RAID0&lt;/code&gt;은 &lt;strong&gt;v1.22.0 미만 이미지에서 노드가 join하지 못합니다.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1.2.0의 메트릭 reason 라벨 snake_case 전환은 CI가 못 잡는 알람 무효화입니다.&lt;/strong&gt; &lt;code&gt;reason=&amp;quot;Drifted&amp;quot;&lt;/code&gt; 쿼리는 에러 없이 결과가 0이 됩니다. 같은 릴리스에서 &lt;code&gt;nodeclass.status&lt;/code&gt;·&lt;code&gt;nodeclass.termination&lt;/code&gt;이 &lt;code&gt;nodeclass&lt;/code&gt;로 합쳐졌습니다(&lt;a href="https://github.com/aws/karpenter-provider-aws/pull/7597"target="_blank" rel="noopener"&gt;aws#7597&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1.6.0에서 native On-Demand Capacity Reservation(ODCR)이 beta·기본 활성화됐습니다&lt;/strong&gt;(&lt;a href="https://github.com/kubernetes-sigs/karpenter/pull/2365"target="_blank" rel="noopener"&gt;core#2365&lt;/a&gt;). &lt;code&gt;open&lt;/code&gt; eligibility ODCR을 &lt;code&gt;capacityReservationSelectorTerms&lt;/code&gt;에 등재하지 않고 올리면 &lt;strong&gt;예약을 안 쓰면서 요금은 계속 나갑니다&lt;/strong&gt; — 이 구간에서 가장 비싼 회귀입니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MinValuesPolicy&lt;/code&gt;(1.6, &lt;a href="https://github.com/kubernetes-sigs/karpenter/pull/2299"target="_blank" rel="noopener"&gt;core#2299&lt;/a&gt;·&lt;a href="https://github.com/aws/karpenter-provider-aws/pull/8250"target="_blank" rel="noopener"&gt;aws#8250&lt;/a&gt;)는 전역 옵션이고 기본값은 &lt;code&gt;Strict&lt;/code&gt;입니다. &lt;code&gt;minValues&lt;/code&gt; 자체는 v0.35.0(&lt;a href="https://github.com/kubernetes-sigs/karpenter/pull/963"target="_blank" rel="noopener"&gt;core#963&lt;/a&gt;)부터 있던 API로 0.36 운영자에게 새 기능이 아닙니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;v1 마이그레이션 가이드 763줄의 절반은 &amp;ldquo;필드가 어디로 갔다&amp;quot;는 표라 &lt;code&gt;kubectl apply&lt;/code&gt; 실패로 바로 드러납니다. 진짜 위험한 건 &lt;strong&gt;매니페스트가 그대로 통과하는데 클러스터가 다르게 행동하는&lt;/strong&gt; 항목입니다 — 만료된 노드가 대체 없이 드레인을 시작하고, 끄고 있던 drift가 켜지고, 쓴 적 없는 &lt;code&gt;consolidateAfter&lt;/code&gt;가 필수가 됩니다.&lt;/p&gt;</description></item><item><title>1.7 → 1.14 — 운영에 쓸 기능들</title><link>https://docs.makgol.com/karpenter/02-changelog-maturity/</link><pubDate>Thu, 30 Jul 2026 00:00:00 +0000</pubDate><guid>https://docs.makgol.com/karpenter/02-changelog-maturity/</guid><description>
&lt;h1&gt;02 · 1.7 → 1.14 — 지금 켤 만한 것과 미룰 것&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;1.7 이후 8개 마이너에서 API breaking은 사실상 없습니다. 대신 켜야 비로소 쓸 수 있는 기능이 라벨·feature gate·신규 CRD·IAM 네 층으로 쌓였습니다.&lt;/li&gt;
&lt;li&gt;flex 배제는 라벨 한 줄입니다 — &lt;code&gt;karpenter.k8s.aws/instance-capability-flex&lt;/code&gt;를 &lt;code&gt;In [&amp;quot;false&amp;quot;]&lt;/code&gt;로. &lt;code&gt;DoesNotExist&lt;/code&gt;로 쓰면 모든 인스턴스 타입이 배제되어 노드가 하나도 안 뜹니다(§2.2).&lt;/li&gt;
&lt;li&gt;기존 NodePool에 배제를 추가하면 떠 있는 flex 노드가 전부 &lt;code&gt;RequirementsDrifted&lt;/code&gt;로 교체됩니다. &amp;ldquo;다음부터&amp;quot;가 아니라 &amp;ldquo;지금 있는 걸 몰아낸다&amp;quot;입니다.&lt;/li&gt;
&lt;li&gt;알람이 에러 없이 깨진 곳이 둘입니다(1.7): &lt;code&gt;karpenter_pods_pods_drained_total&lt;/code&gt; → &lt;code&gt;karpenter_pods_drained_total&lt;/code&gt;, &lt;code&gt;disrupted_total&lt;/code&gt;의 reason &lt;code&gt;liveness&lt;/code&gt; → &lt;code&gt;registration_timeout&lt;/code&gt;(§3).&lt;/li&gt;
&lt;li&gt;업그레이드 자체가 노드를 교체하는 버전도 있습니다 — 1.12는 CA bundle이 drift 해시에 들어가면서 전 노드를 일괄 drifted로 만듭니다(§6.1). 1.8.4는 건너뜁니다(TopologySpreadConstraint(TSC) 회귀, 업스트림이 업그레이드 금지 명시).&lt;/li&gt;
&lt;li&gt;1.14 Balanced consolidation은 게이트가 없습니다 — &lt;code&gt;consolidationPolicy: Balanced&lt;/code&gt; 한 줄이면 됩니다(§7.2). Capacity Buffers는 alpha 게이트에 신규 CRD까지 필요하고 업스트림 문서가 코드보다 낡았습니다(§7.1).&lt;/li&gt;
&lt;li&gt;IAM 권한은 세 번 늘었습니다 — 1.7 &lt;code&gt;iam:ListInstanceProfiles&lt;/code&gt;, 1.11 &lt;code&gt;ec2:DescribePlacementGroups&lt;/code&gt;, 1.12 &lt;code&gt;ec2:DescribeInstanceStatus&lt;/code&gt;(§9).&lt;/li&gt;
&lt;li&gt;우리 기준(blue-green으로 0.36.2 → 1.14.0 직행) 판정은 §8.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;왜 이 문서인가.&lt;/strong&gt; 릴리스노트는 &amp;ldquo;무엇이 머지됐냐&amp;quot;까지만 말합니다. 필요한 구분은 셋 — ① 켜면 이득인 것, ② 설정·권한·CRD를 건드릴 것, ③ 업그레이드 자체가 노드를 교체하는 것. 이 문서는 그 셋으로 1.7~1.14를 나눠 판정합니다.&lt;/p&gt;</description></item><item><title>키워드 레퍼런스 — NodePool로 스케줄링을 통제한다</title><link>https://docs.makgol.com/karpenter/03-keyword-reference/</link><pubDate>Sat, 01 Aug 2026 00:00:00 +0000</pubDate><guid>https://docs.makgol.com/karpenter/03-keyword-reference/</guid><description>
&lt;h1&gt;03 · 키워드 레퍼런스 — NodePool 안에서 affinity를 쓴다는 것&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;Karpenter에는 &lt;code&gt;affinity:&lt;/code&gt; 필드가 없습니다. NodePool &lt;code&gt;spec.template.spec.requirements&lt;/code&gt;가 node affinity와 &lt;strong&gt;같은 문법(NodeSelectorRequirement)&lt;/strong&gt; 으로 &amp;ldquo;이 풀이 만들 수 있는 노드의 집합&amp;quot;을 정의합니다. 파드의 nodeSelector·affinity·topologySpread는 그 집합과 교집합을 이룹니다 — 파드 요구는 &lt;strong&gt;NodePool 요구의 부분집합이어야&lt;/strong&gt; 스케줄됩니다.&lt;/li&gt;
&lt;li&gt;NodePool이 어떤 well-known 라벨에 requirement를 걸지 않으면 &lt;strong&gt;그 축은 클라우드가 파는 모든 값이 허용&lt;/strong&gt;됩니다. arch·capacity-type·세대처럼 조직 차원에서 강제할 조건을 파드에만 두면 요구를 빠뜨린 워크로드가 무제한 오퍼링을 얻습니다.&lt;/li&gt;
&lt;li&gt;연산자는 8개다 — 표준 6개 + Karpenter 확장 &lt;strong&gt;&lt;code&gt;Gte&lt;/code&gt;/&lt;code&gt;Lte&lt;/code&gt;(v1.9.0, &lt;a href="https://github.com/kubernetes-sigs/karpenter/pull/2674"target="_blank" rel="noopener"&gt;core#2674&lt;/a&gt;)&lt;/strong&gt;. 이 4개 비교 연산자는 값이 &lt;strong&gt;1개인 음이 아닌 정수&lt;/strong&gt;여야 합니다. 정수로 파싱되지 않는 라벨값에는 매치 자체가 안 됩니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;preferred는 힌트가 아니다.&lt;/strong&gt; Karpenter는 preferred affinity를 처음엔 required로 취급하고 실패하면 정해진 순서로 한 겹씩 벗깁니다. 그 순서에서 &lt;strong&gt;required nodeAffinity의 OR term 순회가 preferred 제거보다 먼저&lt;/strong&gt;입니다 — &amp;ldquo;내가 원한 인스턴스가 왜 안 떴나&amp;quot;의 답이 §3.2다.&lt;/li&gt;
&lt;li&gt;topologySpreadConstraint(TSC)의 &lt;code&gt;topologyKey&lt;/code&gt;는 AWS에서 &lt;strong&gt;zone·hostname·capacity-type 세 개뿐&lt;/strong&gt;이고 &lt;code&gt;topology.kubernetes.io/region&lt;/code&gt;은 미지원입니다. &lt;code&gt;DoNotSchedule&lt;/code&gt;은 완화 대상에서 빠집니다. 도메인이 부족하면 그대로 영구 Pending입니다. 그리고 다른 파드가 나에게 걸어둔 &lt;strong&gt;preferred&lt;/strong&gt; anti-affinity는 코드가 &lt;strong&gt;의도적으로 추적하지 않아&lt;/strong&gt; 전혀 반영되지 않습니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;karpenter.k8s.aws/instance-capability-flex&lt;/code&gt;(1.7, &lt;a href="https://github.com/aws/karpenter-provider-aws/pull/8315"target="_blank" rel="noopener"&gt;aws#8315&lt;/a&gt; → 개명 &lt;a href="https://github.com/aws/karpenter-provider-aws/pull/8490"target="_blank" rel="noopener"&gt;aws#8490&lt;/a&gt;)로 flex를 배제할 때 &lt;strong&gt;&lt;code&gt;DoesNotExist&lt;/code&gt;를 쓰면 인스턴스 타입 전체가 배제&lt;/strong&gt;됩니다. 정답은 &lt;code&gt;In [&amp;quot;false&amp;quot;]&lt;/code&gt;입니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;karpenter.sh/capacity-type&lt;/code&gt;은 &lt;code&gt;spot&lt;/code&gt;/&lt;code&gt;on-demand&lt;/code&gt;/&lt;code&gt;reserved&lt;/code&gt; 3값이고 &lt;strong&gt;reserved가 최우선 소비&lt;/strong&gt;됩니다. &lt;code&gt;nodeSelector&lt;/code&gt;로 &lt;code&gt;on-demand&lt;/code&gt;를 정확 일치시킨 워크로드는 On-Demand Capacity Reservation(ODCR) 노드에 절대 안 뜹니다 — nodeAffinity &lt;code&gt;In [on-demand, reserved]&lt;/code&gt;로 바꿔야 합니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;minValues&lt;/code&gt;는 &lt;strong&gt;NodePool 전용&lt;/strong&gt;이고 &lt;code&gt;In&lt;/code&gt;에서만 값 개수가 검증됩니다. 패밀리를 여러 개 나열해도 minValues가 없으면 스케줄러는 다양성을 강제하지 않습니다 — 스팟 동시 회수 리스크가 이 한 필드로 갈립니다.&lt;/li&gt;
&lt;li&gt;교집합이 비면 실패로 끝나지 않고 &lt;strong&gt;파드가 Pending으로 남아 백오프 재시도&lt;/strong&gt;됩니다. 즉 오설정과 일시적 용량 부족이 같은 겉모습을 갖습니다. 구분은 &lt;code&gt;FailedScheduling&lt;/code&gt;(파드)·&lt;code&gt;NoCompatibleInstanceTypes&lt;/code&gt;(NodePool) 이벤트 메시지로만 가능합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;왜 이 문서인가.&lt;/strong&gt; Karpenter의 스케줄링은 kube-scheduler식 술어 평가가 아니라 &lt;strong&gt;&amp;ldquo;NodePool requirements ∩ 파드 요구 ∩ 클라우드 offering&amp;quot;의 집합 연산&lt;/strong&gt;이다 — 교집합이 비면 노드가 안 만들어집니다. &amp;ldquo;파드에 affinity를 걸었는데 노드가 안 뜬다&amp;quot;의 원인은 거의 항상 파드 쪽 요구만 보고 NodePool 쪽 우주를 안 본 데 있습니다. 이 문서는 키워드별 레퍼런스이면서 그 교집합 모델을 축으로 삼습니다.&lt;/p&gt;</description></item><item><title>인스턴스는 누가 고르는가</title><link>https://docs.makgol.com/karpenter/04-instance-selection/</link><pubDate>Sat, 01 Aug 2026 00:00:00 +0000</pubDate><guid>https://docs.makgol.com/karpenter/04-instance-selection/</guid><description>
&lt;h1&gt;04 · 인스턴스는 누가 고르는가 — 후보를 넘기고, EC2가 정한다&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;인스턴스 타입을 확정하는 주체는 Karpenter 스케줄러가 아닙니다. 후보 이름 전체를 &lt;code&gt;node.kubernetes.io/instance-type In [...]&lt;/code&gt; 하나로 묶어 NodeClaim에 실어 보냅니다. 타입을 하나로 고정하는 Cluster Autoscaler와 여기서 달라집니다.&lt;/li&gt;
&lt;li&gt;최종 선택자는 EC2입니다. provider-aws가 CreateFleet을 &lt;code&gt;Type: instant&lt;/code&gt;, On-Demand 할당 전략 &lt;code&gt;lowest-price&lt;/code&gt;로 호출합니다. &amp;ldquo;7세대가 싸서 7세대만 뜬다&amp;quot;의 실제 원인은 이 한 줄입니다.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;후보 절단(600/60) 때문에 8세대가 잘려 나간다&amp;quot;는 흔한 오해이고 사실이 아닙니다. 정렬 키가 &lt;em&gt;그 타입의 최저 오퍼링 가격&lt;/em&gt;이라 사이즈에 대해 단조입니다. 잘려 나가는 쪽은 양 세대의 가장 큰 사이즈들입니다.&lt;/li&gt;
&lt;li&gt;단일 NodePool 안에는 선호를 표현할 축이 없습니다. &lt;code&gt;requirements&lt;/code&gt; 스키마는 Key/Operator/Values/MinValues 넷뿐입니다. &lt;code&gt;weight&lt;/code&gt;는 NodePool 레벨에만 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;minValues&lt;/code&gt;는 우선순위 손잡이가 아니라 다양성 하한입니다. 세대 선호에 쓸 수 없을 뿐 아니라 7세대를 후보에 붙들어 두는 역효과를 냅니다.&lt;/li&gt;
&lt;li&gt;파드의 &lt;code&gt;preferred&lt;/code&gt; nodeAffinity도 대안이 아닙니다. Karpenter의 처리 방식은 &amp;ldquo;가장 무거운 term 하나를 hard requirement로 승격한 뒤 실패하면 벗기는&amp;rdquo; 것입니다. 파드마다 걸어야 하고 완화 순서상 네 번째입니다. 벗겨지려면 먼저 스케줄 시뮬레이션이 실패해야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;c8i/m8i/r8i와 c7i/m7i/r7i를 하나의 NodePool에 함께 선언해 두면 &amp;ldquo;8세대 우선, 없으면 7세대 폴백&amp;quot;을 기대하게 되는데, 실제로는 항상 7세대만 뜹니다. 범인은 절단·필터·EC2 중 하나입니다. 어느 쪽이냐에 따라 대응책이 완전히 달라지므로 &amp;ldquo;싼 걸 좋아해서&amp;quot;로는 넘어갈 수 없습니다. 이 문서는 파드가 pending되는 순간부터 EC2가 인스턴스를 띄우는 순간까지 선택이 실제로 일어나는 곳을 코드로 하나씩 지워 갑니다. 흔한 오해 하나(절단이 세대를 자른다)도 명시적으로 깹니다.&lt;/p&gt;</description></item><item><title>세대 선호 만들기</title><link>https://docs.makgol.com/karpenter/05-generation-preference/</link><pubDate>Sat, 01 Aug 2026 00:00:00 +0000</pubDate><guid>https://docs.makgol.com/karpenter/05-generation-preference/</guid><description>
&lt;h1&gt;05 · 세대 선호 만들기 — weight vs NodeOverlay&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;GA 해법은 NodePool을 쪼개고 &lt;code&gt;spec.weight&lt;/code&gt;를 줍니다. weight는 가격보다 먼저 적용됩니다 — NodePool을 고르는 코드 경로(&lt;code&gt;scheduler.go&lt;/code&gt; &lt;code&gt;addToNewNodeClaim&lt;/code&gt;)에는 가격 비교가 아예 없습니다. &lt;code&gt;grep -ic price scheduler.go&lt;/code&gt; → 0건.&lt;/li&gt;
&lt;li&gt;동작은 &amp;ldquo;위에서부터 순차 시도&amp;quot;가 아닙니다. NodeClaimTemplate들이 병렬로 시뮬레이션되고 뮤텍스 아래에서 성공한 것 중 인덱스가 가장 앞선(=weight 최고) 것만 채택됩니다.&lt;/li&gt;
&lt;li&gt;파드 쪽에는 아무것도 걸지 않습니다. nodeSelector/affinity는 필요 없고 오히려 &lt;code&gt;karpenter.sh/nodepool&lt;/code&gt; 셀렉터를 걸면 weight가 통째로 무시됩니다(테스트로 확인됩니다).&lt;/li&gt;
&lt;li&gt;NodeOverlay &lt;code&gt;priceAdjustment&lt;/code&gt;는 알파입니다. feature gate &lt;code&gt;NodeOverlay&lt;/code&gt;가 기본 false입니다. 세대 선호를 실제로 만드는 건 provider-aws가 EC2 Fleet 전략을 &lt;code&gt;prioritized&lt;/code&gt;로 바꾸는 지점인데 — 거기에 확인 못 한 구멍이 둘 있습니다(정수 Priority 규정, 단일 CreateFleet 내 폴백 미보장).&lt;/li&gt;
&lt;li&gt;오버레이를 쓰지 않는 한, 8세대 복귀 장치는 gen7 풀의 &lt;code&gt;expireAfter&lt;/code&gt; 하나뿐입니다. consolidation은 더 싼 쪽으로만 움직이므로 7→8 승격을 절대 하지 않습니다.&lt;/li&gt;
&lt;li&gt;적용 순서를 틀리면 대량 교체가 납니다. 기존 단일 풀에서 세대를 &lt;em&gt;빼는&lt;/em&gt; 편집은 RequirementsDrifted를 유발합니다. 두 풀을 새로 만든 뒤 기존 풀을 지우는 순서로 갑니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;c8i/m8i/r8i를 먼저 쓰고, 없으면 c7i/m7i/r7i로&amp;quot;는 Karpenter가 1급으로 제공하지 않는 요구입니다. &lt;code&gt;requirements&lt;/code&gt; 스키마가 Key/Operator/Values/MinValues뿐이어서 선호도를 표현할 필드가 없습니다(&lt;a href="https://docs.makgol.com/karpenter/04-instance-selection/"&gt;04&lt;/a&gt;). 업스트림도 두 번 반려했습니다 — &lt;a href="https://github.com/kubernetes-sigs/karpenter/issues/1829"target="_blank" rel="noopener"&gt;karpenter#1829&lt;/a&gt; &lt;em&gt;closed as not planned&lt;/em&gt;, &lt;a href="https://github.com/aws/karpenter-provider-aws/issues/6721"target="_blank" rel="noopener"&gt;karpenter-provider-aws#6721&lt;/a&gt; &lt;em&gt;closed&lt;/em&gt;. 남은 두 우회로를 코드까지 비교하고 복붙용 매니페스트 전문을 내놓습니다.&lt;/p&gt;</description></item><item><title>consolidation이 되돌리는 것</title><link>https://docs.makgol.com/karpenter/06-consolidation-traps/</link><pubDate>Sat, 01 Aug 2026 00:00:00 +0000</pubDate><guid>https://docs.makgol.com/karpenter/06-consolidation-traps/</guid><description>
&lt;h1&gt;06 · consolidation이 되돌리는 것 — 구성해 놓고 나중에 무너지는 경로들&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;consolidation의 교체 조건은 가격 부등식 하나뿐입니다. &lt;code&gt;launchPrice &amp;lt; candidatePrice&lt;/code&gt; — strict라 동가격 교체조차 없습니다. 세대·성능·선호도라는 개념은 disruption 패키지 어디에도 인코딩돼 있지 않습니다.&lt;/li&gt;
&lt;li&gt;disruption 패키지는 NodePool weight를 전혀 보지 않습니다. &lt;code&gt;grep -rnE 'Spec\.Weight|OrderByWeight' pkg/controllers/disruption/&lt;/code&gt; → 0건. 코어는 크로스 풀 교체를 막지 않고 정상 경로로 인지합니다.&lt;/li&gt;
&lt;li&gt;크로스 풀 다운그레이드는 좁습니다. 대체안 시뮬레이션도 프로비저닝과 같은 weight 정렬 스케줄러를 씁니다. 평상시엔 gen8 풀에서 대체안이 나오고 strict 부등호에 걸려 탈락합니다. gen8 풀이 스케줄에 실패할 때만 gen7이 이깁니다. 그건 gen7을 원하는 상황입니다.&lt;/li&gt;
&lt;li&gt;한 번 내려가면 consolidation으로는 안 돌아옵니다. &amp;ldquo;더 비싼 교체&amp;rdquo; 분기가 코드에 없습니다. 업스트림 요청도 반려됐습니다(#1829 closed as not planned). 복귀 경로는 &lt;code&gt;expireAfter&lt;/code&gt;와 drift입니다 — 둘 다 가격 필터 없이 교체하므로 재스케줄 시 weight 100인 gen8이 다시 먼저 평가됩니다.&lt;/li&gt;
&lt;li&gt;weight는 &amp;ldquo;보장&amp;quot;이 아닙니다 — 공식 문서가 명시합니다. 원인은 단일 프로비저닝 루프 내부의 빈패킹입니다. &amp;ldquo;이미 떠 있는 노드&amp;rdquo; 때문이 아닙니다. in-flight NodeClaim은 weight를 보지 않고 파드 수 오름차순으로 정렬됩니다. 거기에 파드를 채우는 시도가 새 NodeClaim 생성보다 먼저 옵니다.&lt;/li&gt;
&lt;li&gt;drift는 값 추가엔 침묵하고 값 제거엔 폭발합니다. requirements 판정이 호환성 기반이라 세대 추가는 무해합니다. 풀을 쪼개려고 기존 풀에서 세대를 제거하면 RequirementsDrifted 대량 교체가 시작됩니다. 속도 제어 수단은 &lt;code&gt;disruption.budgets&lt;/code&gt; 하나뿐입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;왜 이 문서인가. &lt;a href="https://docs.makgol.com/karpenter/05-generation-preference/"&gt;05&lt;/a&gt;의 매니페스트는 적용 순간엔 의도대로 동작합니다. 문제는 그 다음입니다 — Karpenter의 재계산 루프는 &amp;ldquo;세대&amp;quot;라는 단어를 모릅니다. 이 문서는 며칠~몇 주에 걸쳐 알람 하나 없이 무너지는 경로를 코어 소스에서 짚습니다. 검증 기준: kubernetes-sigs/karpenter &lt;code&gt;v1.14.0-6-gac7a021e&lt;/code&gt;(로컬 체크아웃).&lt;/p&gt;</description></item><item><title>용량이 없을 때 — ICE와 폴백 지연</title><link>https://docs.makgol.com/karpenter/07-ice-fallback/</link><pubDate>Sat, 01 Aug 2026 00:00:00 +0000</pubDate><guid>https://docs.makgol.com/karpenter/07-ice-fallback/</guid><description>
&lt;h1&gt;07 · 용량이 없을 때 — ICE와 폴백 지연&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;폴백은 이미 공짜입니다. 8세대가 Insufficient Capacity Error(ICE, AWS 응답 코드 &lt;code&gt;InsufficientInstanceCapacity&lt;/code&gt;)를 내는 순간 provider-aws가 그 오퍼링을 unavailable로 마킹하고 코어는 &lt;code&gt;Offerings.Available()&lt;/code&gt;에서 그 오퍼링을 걸러 다음 루프의 후보에서 뺍니다. 손으로 만들어야 하는 건 &amp;ldquo;평소엔 8세대&amp;quot;라는 상향 강제뿐입니다.&lt;/li&gt;
&lt;li&gt;코어는 ICE 난 NodeClaim을 지우고 재큐하지 않습니다. &lt;code&gt;err&lt;/code&gt;를 반환하지도 않으니 controller-runtime 백오프도 안 붙습니다. 재시도는 파드 컨트롤러의 10초 재큐 + 배치창(idle 1s / max 10s)뿐이고 실측 기대치는 대략 11~30초입니다.&lt;/li&gt;
&lt;li&gt;ICE 캐시는 3분입니다. 키는 &lt;code&gt;&amp;lt;capacityType&amp;gt;:&amp;lt;instanceType&amp;gt;:&amp;lt;zone&amp;gt;&lt;/code&gt;. 부족이 지속되면 3분 주기로 실패 왕복이 반복됩니다. 거꾸로 용량이 회복되면 최대 3분 뒤 8세대가 저절로 부활합니다. 사람이 할 일은 없습니다.&lt;/li&gt;
&lt;li&gt;가용성 판정 축은 셋입니다. &lt;code&gt;IsUnavailable()&lt;/code&gt;이 보는 것은 오퍼링 캐시 ∨ capacity-type 전체 차단 캐시 ∨ 전 서브넷 차단 캐시의 OR입니다. 서브넷 IP 고갈은 인스턴스 타입과 무관하게 오퍼링을 죽입니다.&lt;/li&gt;
&lt;li&gt;spot을 섞으면 세대 강제가 무력화됩니다. capacity-type 우선순위가 &lt;code&gt;reserved &amp;gt; spot &amp;gt; on-demand&lt;/code&gt;인데다 spot Fleet은 &lt;code&gt;price-capacity-optimized&lt;/code&gt;라 EC2가 용량 깊이로 타입을 고릅니다. 세대 선호가 목적이면 on-demand로 한정하십시오.&lt;/li&gt;
&lt;li&gt;단일 NodePool 안에서 알파 없이 8세대를 1순위로 만드는 길은 On-Demand Capacity Reservation(ODCR)입니다. reserved 오퍼링 가격이 &lt;code&gt;odPrice / 10,000,000&lt;/code&gt;이라 정렬·절단·Fleet 전부에서 무조건 앞섭니다. 게이트 &lt;code&gt;ReservedCapacity&lt;/code&gt;는 기본 ON(BETA)입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;ldquo;8세대(c8i/m8i/r8i)가 부족하면 7세대로 폴백하고 싶다&amp;quot;에서 폴백 쪽은 이미 동작합니다. ICE를 오퍼링 가용성으로 환산해 스케줄링에 되먹이는 배선이 코어와 provider-aws에 완비돼 있습니다. 이 문서는 그 폴백이 어느 코드에서 몇 초 만에 일어나는지를 끝까지 내려가 01~03에서 고른 구성이 ICE 상황에서 어떻게 행동하는지 확정합니다.&lt;/p&gt;</description></item><item><title>언제 무엇을 멈출 것인가 — disruption 예산</title><link>https://docs.makgol.com/karpenter/08-disruption-budgets/</link><pubDate>Sat, 01 Aug 2026 00:00:00 +0000</pubDate><guid>https://docs.makgol.com/karpenter/08-disruption-budgets/</guid><description>
&lt;h1&gt;08 · 언제 무엇을 멈출 것인가 — disruption 예산 설계&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;disruption 이유 셋을 나누는 기준은 &lt;strong&gt;파드를 옮기느냐&lt;/strong&gt;입니다. &lt;code&gt;Empty&lt;/code&gt;만 안 옮깁니다 — 예산 설계는 여기서 출발합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;reasons&lt;/code&gt;를 생략한 예산은 셋 모두에 적용됩니다.&lt;/strong&gt; 피크 차단용 &lt;code&gt;nodes: &amp;quot;0&amp;quot;&lt;/code&gt;에 &lt;code&gt;reasons&lt;/code&gt;를 안 적으면 &lt;strong&gt;빈 노드 정리까지 같이 멈춥니다.&lt;/strong&gt; 가장 흔한 오설정인데 에러 없이 침묵으로 나타나 발견이 늦습니다.&lt;/li&gt;
&lt;li&gt;같은 이유에 예산이 여럿 활성이면 &lt;strong&gt;가장 제한적인 값이 이깁니다.&lt;/strong&gt; 전역 &lt;code&gt;nodes: &amp;quot;1&amp;quot;&lt;/code&gt; 하나로 나머지 설계가 전부 무력화될 수 있습니다.&lt;/li&gt;
&lt;li&gt;예산이 막는 것은 &lt;strong&gt;graceful disruption만&lt;/strong&gt;입니다. &lt;code&gt;expireAfter&lt;/code&gt; 만료·인터럽션·Node Repair는 예산 밖입니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nodes: &amp;quot;0&amp;quot;&lt;/code&gt;이 막는 것은 &lt;strong&gt;실행만&lt;/strong&gt;입니다. drift 판정과 마킹은 계속 쌓이므로 예산을 푸는 순간 밀린 교체가 한꺼번에 터집니다.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;노드가 안 줄어든다&amp;quot;의 진단 순서는 &lt;strong&gt;이벤트 → 예산 → requirements → topology&lt;/strong&gt;입니다. 예산을 1순위에 두는 이유는 유일하게 &lt;strong&gt;시도했다는 증거를 이벤트로 남기기&lt;/strong&gt; 때문입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;왜 이 문서인가.&lt;/strong&gt; v1에서 drift는 못 끄게 되고 expiration은 forceful로 되돌아갔다(&lt;a href="https://docs.makgol.com/karpenter/01-changelog-v1-transition/"&gt;01&lt;/a&gt;). 그래서 남은 통제 수단이 사실상 &lt;code&gt;disruption.budgets&lt;/code&gt; 하나인데 문법이 짧아 다 이해했다고 착각하기 쉽습니다. &lt;strong&gt;생략된 필드의 기본 해석&lt;/strong&gt;이 동작의 절반을 결정합니다.&lt;/p&gt;</description></item><item><title>메트릭 수집 비용 — 무엇을 버릴 것인가</title><link>https://docs.makgol.com/karpenter/10-metric-cost/</link><pubDate>Thu, 30 Jul 2026 00:00:00 +0000</pubDate><guid>https://docs.makgol.com/karpenter/10-metric-cost/</guid><description>
&lt;h1&gt;10 · 메트릭 수집 비용 — 무엇을 버릴 것인가&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;비용을 만드는 건 메트릭 60개가 아니라 시리즈 수입니다. 60개 중 &lt;strong&gt;파드 단위 6개&lt;/strong&gt;가 대부분을 차지하고 그 6개만 배포마다 전량 churn합니다.&lt;/li&gt;
&lt;li&gt;Datadog은 OpenMetrics로 긁은 것을 전부 custom metric으로 셉니다. 공식 문서 표현이 &lt;em&gt;&amp;ldquo;all metrics retrieved by the generic Prometheus check are considered custom metrics&amp;rdquo;&lt;/em&gt; 입니다. 아무 설정 없이 붙이면 청구가 튑니다.&lt;/li&gt;
&lt;li&gt;OpenMetrics 체크에는 &lt;code&gt;max_returned_metrics&lt;/code&gt; 기본 2000 상한이 있습니다. 대규모 클러스터에서는 이 선에서 경고 없이 잘립니다 — 없는 메트릭과 잘린 메트릭이 구분되지 않습니다.&lt;/li&gt;
&lt;li&gt;VM에서는 청구가 아니라 &lt;strong&gt;&lt;code&gt;indexdb&lt;/code&gt; 팽창&lt;/strong&gt;이 비용입니다. 시리즈 총수가 같아도 churn이 크면 인덱스가 계속 자랍니다.&lt;/li&gt;
&lt;li&gt;Prometheus의 보호 장치는 전부 기본으로 꺼져 있습니다 — &lt;code&gt;sample_limit&lt;/code&gt;·&lt;code&gt;label_limit&lt;/code&gt;·&lt;code&gt;target_limit&lt;/code&gt; 기본값이 모두 &lt;code&gt;0&lt;/code&gt;(무제한)입니다.&lt;/li&gt;
&lt;li&gt;파드 6종을 버려도 잃는 게 거의 없습니다. 파드 단위 상태는 kube-state-metrics가 이미 더 잘 냅니다.&lt;/li&gt;
&lt;li&gt;켜기 전에 잽니다. 엔드포인트를 직접 긁으면 백엔드에 아무것도 넣지 않고 시리즈 수를 셀 수 있습니다(§5.1). 붙였다가 줄이는 순서는 Datadog에서 그 달 청구가 이미 발생한 뒤입니다.&lt;/li&gt;
&lt;li&gt;drop보다 keep이 낫습니다. 업스트림이 메트릭을 추가하면 blocklist는 그것을 자동으로 통과시킵니다(§4.1).&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://docs.makgol.com/karpenter/09-metrics-logs-events/"&gt;09&lt;/a&gt;가 &amp;ldquo;무엇이 나오나&amp;quot;라면 여기는 &amp;ldquo;무엇을 저장할 것인가&amp;quot;입니다 — 60개를 다 긁는 것 자체는 문제가 아니고 비용이 백엔드마다 다른 이름으로 나타나는 게 주제입니다. 카디널리티 폭발의 원리는 &lt;a href="https://docs.makgol.com/monitoring/victoriametrics/practice/01-cardinality/"&gt;VictoriaMetrics / 카디널리티&lt;/a&gt;가 소유합니다. 여기서는 그 결과만 다룹니다.&lt;/p&gt;</description></item><item><title>13 · consolidation 후보 선별과 심사</title><link>https://docs.makgol.com/karpenter/13-consolidation-models/</link><pubDate>Sun, 02 Aug 2026 00:00:00 +0000</pubDate><guid>https://docs.makgol.com/karpenter/13-consolidation-models/</guid><description>
&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;p&gt;&lt;strong&gt;먼저 결론&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;consolidation은 사용률이 낮은 노드를 골라 지우는 기능이 아닙니다. &lt;strong&gt;후보 선별 → 사유 판정 → 스케줄링 시뮬레이션 → 삭제 또는 교체&lt;/strong&gt;의 네 단계를 매 라운드 반복하고 단계마다 서로 다른 이유로 후보가 떨어져 나갑니다.&lt;/li&gt;
&lt;li&gt;삭제냐 교체냐를 정하는 것은 &lt;strong&gt;시뮬레이션 결과&lt;/strong&gt;입니다. 파드를 전부 다른 노드에 앉힐 수 있으면 삭제, 한 대가 더 필요한데 그게 더 싸면 교체, 두 대 이상 필요하면 아무것도 하지 않습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Balanced&lt;/code&gt;는 기존 알고리즘을 대체하지 않습니다.&lt;/strong&gt; &lt;code&gt;WhenEmptyOrUnderutilized&lt;/code&gt;가 만들어 낸 커맨드에 승인 조건을 하나 더 거는 정책이라, 통합이 늘어나는 경우는 없습니다.&lt;/li&gt;
&lt;li&gt;Drift는 consolidation과 &lt;strong&gt;별개의 disruption method&lt;/strong&gt;입니다. 정책을 무엇으로 두든 계속 돌고 &lt;code&gt;Balanced&lt;/code&gt;의 스코어도 받지 않습니다.&lt;/li&gt;
&lt;li&gt;이 글은 코어 &lt;strong&gt;v1.14.0&lt;/strong&gt; 기준입니다. 인용한 코드 위치는 &lt;code&gt;kubernetes-sigs/karpenter&lt;/code&gt; 체크아웃(&lt;code&gt;v1.14.0-6-gac7a021e&lt;/code&gt;)을 직접 열어 확인했습니다.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;1. 전체 처리 흐름&lt;span class="hx:absolute hx:-mt-20" id="1-전체-처리-흐름"&gt;&lt;/span&gt;
&lt;a href="#1-%ec%a0%84%ec%b2%b4-%ec%b2%98%eb%a6%ac-%ed%9d%90%eb%a6%84" class="subheading-anchor" aria-label="이 섹션에 대한 고유 링크"&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3&gt;1.1 Disruption Controller 안에서의 위치&lt;span class="hx:absolute hx:-mt-20" id="11-disruption-controller-안에서의-위치"&gt;&lt;/span&gt;
&lt;a href="#11-disruption-controller-%ec%95%88%ec%97%90%ec%84%9c%ec%9d%98-%ec%9c%84%ec%b9%98" class="subheading-anchor" aria-label="이 섹션에 대한 고유 링크"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;consolidation에는 전용 컨트롤러가 없습니다. Disruption Controller 하나가 &lt;strong&gt;다섯 개의 method&lt;/strong&gt;를 등록해 두고 순서대로 물어봅니다.&lt;/p&gt;</description></item><item><title>14 · MultiNode 예산과 전역 후보 탐색</title><link>https://docs.makgol.com/karpenter/14-multinode-budget-search/</link><pubDate>Tue, 04 Aug 2026 00:00:00 +0000</pubDate><guid>https://docs.makgol.com/karpenter/14-multinode-budget-search/</guid><description>
&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;p&gt;&lt;strong&gt;먼저 결론&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MultiNode의 disruption budget은 NodePool별로 계산하고 소비합니다.&lt;/li&gt;
&lt;li&gt;하지만 후보 탐색에는 NodePool·AZ 경계가 없습니다. 모든 후보를 전역 정렬한 뒤 각 Pool의 budget만큼 남깁니다. 그렇게 섞인 목록의 prefix를 시뮬레이션합니다.&lt;/li&gt;
&lt;li&gt;최종 validation은 선택된 커맨드의 안전성만 다시 확인합니다. 전역 prefix 탐색에서 놓친 NodePool/AZ 조합을 찾아 주지는 않습니다.&lt;/li&gt;
&lt;li&gt;주된 위험은 budget 위반보다 탐색 누락, Pool 간 간섭, 후보 기회 편향입니다.&lt;/li&gt;
&lt;li&gt;이 글은 코어 v1.14.0 체크아웃(&lt;code&gt;v1.14.0-6-gac7a021e&lt;/code&gt;)을 기준으로 확인했습니다.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;1. 확인하려는 질문&lt;span class="hx:absolute hx:-mt-20" id="1-확인하려는-질문"&gt;&lt;/span&gt;
&lt;a href="#1-%ed%99%95%ec%9d%b8%ed%95%98%eb%a0%a4%eb%8a%94-%ec%a7%88%eb%ac%b8" class="subheading-anchor" aria-label="이 섹션에 대한 고유 링크"&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;MultiNodeConsolidation.ComputeCommands()&lt;/code&gt;는 후보를 전역 정렬한 뒤 &lt;code&gt;disruptionBudgetMapping[candidate.NodePool.Name]&lt;/code&gt;을 확인하고 차감합니다.&lt;/p&gt;</description></item><item><title>15 · NodePool별 MultiNode 최소 변경 계획</title><link>https://docs.makgol.com/karpenter/15-nodepool-multinode-plan/</link><pubDate>Tue, 04 Aug 2026 00:00:00 +0000</pubDate><guid>https://docs.makgol.com/karpenter/15-nodepool-multinode-plan/</guid><description>
&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;p&gt;&lt;strong&gt;이 문서의 범위&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>16 · MultiNode upstream 이슈 조사</title><link>https://docs.makgol.com/karpenter/16-multinode-upstream-issue-review/</link><pubDate>Thu, 06 Aug 2026 00:00:00 +0000</pubDate><guid>https://docs.makgol.com/karpenter/16-multinode-upstream-issue-review/</guid><description>
&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;p&gt;&lt;strong&gt;먼저 결론&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이 문제는 AWS provider가 아니라 &lt;strong&gt;provider-neutral Karpenter core&lt;/strong&gt;의 MultiNode 후보 탐색 알고리즘에 있습니다.&lt;/li&gt;
&lt;li&gt;논의 장소도 &lt;code&gt;aws/karpenter-provider-aws&lt;/code&gt;보다 &lt;code&gt;kubernetes-sigs/karpenter&lt;/code&gt;가 맞습니다.&lt;/li&gt;
&lt;li&gt;새 Issue는 권장하지 않습니다. 같은 문제를 직접 다룬 &lt;code&gt;#853&lt;/code&gt;, &lt;code&gt;#2434&lt;/code&gt;, &lt;code&gt;#2814&lt;/code&gt;가 이미 있습니다.&lt;/li&gt;
&lt;li&gt;현재 기준점은 열린 채 &lt;code&gt;triage/accepted&lt;/code&gt;된 **&lt;a href="https://github.com/kubernetes-sigs/karpenter/issues/2434"target="_blank" rel="noopener"&gt;#2434 Multinode consolidation delayed/stuck&lt;/a&gt;**입니다.&lt;/li&gt;
&lt;li&gt;별도 &lt;code&gt;consolidationCoverage&lt;/code&gt; 설정을 앞세우는 것보다 &lt;code&gt;#2434&lt;/code&gt;에 재현 사례와 측정값을 추가하고 &lt;strong&gt;설정 없는 후보 compatibility 개선&lt;/strong&gt;을 RFC에서 논의하는 쪽이 upstream 방향과 맞습니다.&lt;/li&gt;
&lt;li&gt;조사 기준일은 &lt;strong&gt;2026-08-04&lt;/strong&gt;입니다. Issue 상태와 라벨은 이후 변경될 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;0. 핵심 Issue 네 개를 먼저 비교&lt;span class="hx:absolute hx:-mt-20" id="0-핵심-issue-네-개를-먼저-비교"&gt;&lt;/span&gt;
&lt;a href="#0-%ed%95%b5%ec%8b%ac-issue-%eb%84%a4-%ea%b0%9c%eb%a5%bc-%eb%a8%bc%ec%a0%80-%eb%b9%84%ea%b5%90" class="subheading-anchor" aria-label="이 섹션에 대한 고유 링크"&gt;&lt;/a&gt;&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;항목&lt;/th&gt;
&lt;th style="text-align: right"&gt;NodePool별 필터링과의 거리&lt;/th&gt;
&lt;th style="text-align: right"&gt;현재 진전&lt;/th&gt;
&lt;th&gt;역할&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/kubernetes-sigs/karpenter/issues/2814"target="_blank" rel="noopener"&gt;#2814 ConsolidationGroup&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: right"&gt;가장 가까움&lt;/td&gt;
&lt;td style="text-align: right"&gt;종료&lt;/td&gt;
&lt;td&gt;구체적인 hard-grouping 해결안&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/kubernetes-sigs/karpenter/pull/2871"target="_blank" rel="noopener"&gt;PR #2871 node-group POC&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: right"&gt;매우 가까움&lt;/td&gt;
&lt;td style="text-align: right"&gt;코드 존재, 정체&lt;/td&gt;
&lt;td&gt;label·AZ grouping 실제 구현&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/kubernetes-sigs/karpenter/issues/2434"target="_blank" rel="noopener"&gt;#2434 Multinode delayed/stuck&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: right"&gt;문제 정의가 직접적&lt;/td&gt;
&lt;td style="text-align: right"&gt;Accepted, 구현 없음&lt;/td&gt;
&lt;td&gt;canonical root-cause Issue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/kubernetes-sigs/karpenter/issues/3141"target="_blank" rel="noopener"&gt;#3141 priority-scored list&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: right"&gt;hard filter보다는 heuristic&lt;/td&gt;
&lt;td style="text-align: right"&gt;Accepted, needs-design&lt;/td&gt;
&lt;td&gt;가장 활발한 장기 설계&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;0.1 NodePool별 필터링에 가장 가까운 것&lt;span class="hx:absolute hx:-mt-20" id="01-nodepool별-필터링에-가장-가까운-것"&gt;&lt;/span&gt;
&lt;a href="#01-nodepool%eb%b3%84-%ed%95%84%ed%84%b0%eb%a7%81%ec%97%90-%ea%b0%80%ec%9e%a5-%ea%b0%80%ea%b9%8c%ec%9a%b4-%ea%b2%83" class="subheading-anchor" aria-label="이 섹션에 대한 고유 링크"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Issue만 비교하면 &lt;code&gt;#2814&lt;/code&gt;가 가장 가깝습니다.&lt;/p&gt;</description></item><item><title>무엇을 봐야 하나 — 메트릭·로그·이벤트</title><link>https://docs.makgol.com/karpenter/09-metrics-logs-events/</link><pubDate>Thu, 30 Jul 2026 00:00:00 +0000</pubDate><guid>https://docs.makgol.com/karpenter/09-metrics-logs-events/</guid><description>
&lt;h1&gt;09 · 무엇을 봐야 하나 — 메트릭·로그·이벤트&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;p&gt;&lt;strong&gt;한눈에&lt;/strong&gt;&lt;/p&gt;</description></item></channel></rss>